2015-01-06 9 views
6

जावा में वाई-अक्ष के साथ बॉक्सलेआउट के केंद्र में कुछ वर्णों को संरेखित करने के साथ एक समस्या प्रतीत होती है। मुझे नहीं पता कि इसका क्या कारण हो सकता है, & मैंने प्रभाव का प्रदर्शन करने के लिए एक एसएससीसीई बनाया है। उदाहरण में, मैं केवल 'ए', & चरित्र का उपयोग करता हूं, मैं प्रत्येक जेपीनेल के प्रत्यक्ष मध्य में एक रेखा खींचता हूं ताकि यह प्रदर्शित किया जा सके कि प्रत्येक मामले केंद्र से कितना दूर है। बोल्ड टेक्स्ट के साथ मामला ठीक से दिखता है, लेकिन सामान्य स्वरूपण & इटालिक्स दोनों सेटऑलिग्मेंटएक्स & सेट होरिज़ोंन्टल एलाइनमेंट का उपयोग करने के बावजूद पूरी तरह से ऑफ-सेंटर हैं। इस प्रभाव को समझने में कोई मदद की सराहना की जाती है।वाई-एक्सिस पर जावा बॉक्सलेआउट में सिंगल अक्षरों का संरेखण ऑफ-सेंटर

किसी भी तरह से समस्या मेरे विशिष्ट कंप्यूटर पर जावा के साथ है, तो यह एक छवि है जब मैं एसएससीसीई चलाता हूं, जो वाई-अक्ष & के साथ बॉक्सलेआउट के साथ तीन अलग जेपीनल लोड करता है केवल चरित्र 'एक' प्रत्येक में साथ JLabel केंद्रित: enter image description here

यहाँ & SSCCE के लिए कोड है:

import javax.swing.*; 
import java.awt.*; 
import javax.swing.border.*; 

public class AlignmentTest extends JPanel 
{ 
    public AlignmentTest(char label, int style) 
    { 
     JLabel l = new JLabel(Character.toString(label)); 
     setBorder(BorderFactory.createLineBorder(Color.BLACK,1)); 
     setBackground(Color.WHITE); 
     setLayout(new BoxLayout(this,BoxLayout.Y_AXIS)); 
     setPreferredSize(new Dimension(300,50)); 
     add(Box.createVerticalGlue()); 
     add(l); 
      l.setFont(l.getFont().deriveFont(style)); 
      l.setAlignmentX(CENTER_ALIGNMENT); 
      l.setHorizontalAlignment(JLabel.CENTER); 
     add(Box.createVerticalGlue()); 
    } 
    public static void main(String[] args) 
    { 
     JFrame f = new JFrame("Alignment Test"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLayout(new GridLayout(1,0,5,5)); 
     f.add(new AlignmentTest('a',Font.PLAIN)); 
     f.add(new AlignmentTest('a',Font.BOLD)); 
     f.add(new AlignmentTest('a',Font.ITALIC)); 
     f.pack(); 
     f.setVisible(true); 
    } 
    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     g.drawLine(getWidth()/2,0,getWidth()/2,getHeight()); 
    } 
} 
+1

स्पष्टता के लिए, का उपयोग 'style' [नाम] (http://docs.oracle.com/javase/8/docs/api/constant-values.html#java। awt.Font.BOLD)। – trashgod

+0

अच्छा बिंदु, मैंने इसके बारे में नहीं सोचा था। मैंने अब 'शैली' नामों का उपयोग करने के लिए कोड बदल दिया है। इनपुट के लिए धन्यवाद। –

उत्तर

4

पात्रों में से विंडोज 7 से कोई भी पर JDK7 का उपयोग करते हुए केंद्र गठबंधन कर रहे हैं।

मैंने जेटीक्स्टफिल्ड प्रदर्शित करने के लिए कुछ बदलाव किए और मैंने जेटीक्स्टफिल्ड (1, 3, 5) के कॉलम के साथ खेला। चूंकि कॉलम में वृद्धि हुई है, केंद्र में सुधार हुआ है और कॉलम 5 और ऊपर के लिए उचित था। तो समस्या किसी भी तरह से घटक की चौड़ाई से संबंधित है।

मुझे लगता है कि लेआउट में कुछ अजीब राउंडिंग त्रुटि है। यह मेरे लिए एक बग की तरह लगता है।

यदि आप ऐसे लेआउट में रुचि रखते हैं जो BoxLayout को कुछ समान कार्यक्षमता प्रदान करता है तो आप Relative Layout देख सकते हैं। अपने उदाहरण में परिवर्तन छोटे हैं:

import javax.swing.*; 
import java.awt.*; 
import javax.swing.border.*; 

public class AlignmentTest extends JPanel 
{ 
    public AlignmentTest(char label, int style) 
    { 
     JLabel l = new JLabel(Character.toString(label)); 
     setBorder(BorderFactory.createLineBorder(Color.BLACK,1)); 
     setBackground(Color.WHITE); 
//  setLayout(new BoxLayout(this,BoxLayout.Y_AXIS)); 
     setLayout(new RelativeLayout(RelativeLayout.Y_AXIS)); 
     setPreferredSize(new Dimension(300,50)); 
//  add(Box.createVerticalGlue()); 
     add(Box.createVerticalGlue(), new Float(1)); 
     add(l); 
      l.setFont(l.getFont().deriveFont(style)); 
      l.setAlignmentX(CENTER_ALIGNMENT); 
      l.setHorizontalAlignment(JLabel.CENTER); 
//  add(Box.createVerticalGlue()); 
     add(Box.createVerticalGlue(), new Float(1)); 
    } 
    public static void main(String[] args) 
    { 
     JFrame f = new JFrame("Alignment Test"); 
     JScrollPane scroller = new JScrollPane(); 
      JPanel panel = new JPanel(new GridLayout(1,0,5,5)); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLayout(new GridLayout(1,0,5,5)); 
     f.add(new AlignmentTest('a',Font.PLAIN)); 
     f.add(new AlignmentTest('a',Font.BOLD)); 
     f.add(new AlignmentTest('a',Font.ITALIC)); 
     f.pack(); 
     f.setVisible(true); 
    } 
    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     g.drawLine(getWidth()/2,0,getWidth()/2,getHeight()); 
    } 
} 
+0

'सापेक्ष लयआउट' निश्चित रूप से एक पर्याप्त कामकाज है। मैंने इससे पहले नहीं सुना है, लेकिन यह कुछ ऐसा है जो मैं यहां और भविष्य के अनुप्रयोगों में उपयोग कर सकता हूं। हालांकि, मुझे इसका उपयोग करने के लिए अपने प्रोजेक्ट में 'रिलेवेटिवआउट' के लिए स्रोत कोड कॉपी करना था और स्रोत कोड कॉपी करना था। मेरे पास जावा संस्करण 1.7.0_25 है। मुझे जावा में निर्मित 'रिलेवेटिवआउट' क्लास को मैन्युअल रूप से स्रोत कोड की प्रतिलिपि बनाने की आवश्यकता के बिना अपडेट करने की आवश्यकता है? –

+0

@ScottHetrick, RelativeLayout केवल कुछ (असमर्थित) कोड है जिसे मैंने लिंक में वर्णित कार्यक्षमता प्रदान करने के लिए लिखा था। इसके लिए कोई जार फ़ाइल या कुछ भी नहीं है, इसलिए हाँ आप इसे किसी भी वर्ग की तरह इस्तेमाल करते हैं जिसे आप स्वयं लिखते हैं। कक्षा संस्करण निर्भर नहीं है। – camickr

+0

ओह, मैं गचाचा। यह प्रभावशाली है। सिफारिश के लिए धन्यवाद, मैं भविष्य में इसका उपयोग करूँगा। –

4

प्रभाव आप देख रास्ता BoxLayout की कार्यप्रणाली का एक विरूपण साक्ष्य प्रतीत होता है। How to Use BoxLayout: Box Layout Features से इंटरपोलेटिंग, "जब BoxLayout बाएं से दाएं घटकों को बताता है, ... कंटेनर के दाईं ओर कोई भी अतिरिक्त स्थान दिखाई देता है।" जब संलग्न कंटेनर का प्रारंभिक आकार लेबल के (निश्चित) आकार का एक छोटा सा हिस्सा है, जैसा कि नीचे दिखाया गया है, विसंगति न्यूनतम है; यह कैसे बढ़ता है यह देखने के लिए फ्रेम को क्षैतिज रूप से फैलाएं। एक कार्य-आस-पास उस डिग्री को कम करना होगा जिसमें संलग्न कंटेनर का पसंदीदा आकार कृत्रिम रूप से बढ़ाया गया हो।

image

import javax.swing.*; 
import java.awt.*; 

public class AlignmentTest extends JPanel { 
    private final JLabel l; 
    public AlignmentTest(String label, int style) { 
     setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); 
     setBackground(Color.WHITE); 
     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 
     l = new JLabel(label, JLabel.CENTER); 
     l.setFont(l.getFont().deriveFont(style)); 
     l.setAlignmentX(CENTER_ALIGNMENT); 
     l.setOpaque(true); 
     l.setBackground(Color.cyan); 
     add(Box.createVerticalGlue()); 
     add(l); 
     add(Box.createVerticalGlue()); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     int w = l.getPreferredSize().width; 
     int h = l.getPreferredSize().height; 
     return new Dimension(w * 3, h * 3); 
    } 

    public static void main(String[] args) { 
     JFrame f = new JFrame("Alignment Test"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLayout(new GridLayout(1, 0, 5, 5)); 
     f.add(new AlignmentTest("aMa", Font.PLAIN)); 
     f.add(new AlignmentTest("aMa", Font.BOLD)); 
     f.add(new AlignmentTest("aMa", Font.ITALIC)); 
     f.pack(); 
     f.setVisible(true); 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawLine(getWidth()/2, 0, getWidth()/2, getHeight()); 
    } 
} 
+0

यह एक व्यवहार्य कामकाज है, लेकिन इस मुद्दे को पूरी तरह हल करने के लिए एक और सीधा समाधान की आवश्यकता होगी। –

5

एक और तरीका है से बचने के लिए "बॉक्स लेआउट विशेषताएं: ... किसी भी अतिरिक्त जगह कंटेनर के दाईं ओर दिखाई देने", आप एक ही DimensionJLabel#getPreferredSize() के रूप में वापस जाने के लिए JLabel#getMinimumSize() विधि ओवरराइड करने के लिए की आवश्यकता होगी ।

क्षमा करें, मुझे गलत समझा गया।

@camickr पहले ही कहा गया है,

मुझे लगता है कि होगा वहाँ लेआउट में कुछ अजीब पूर्णांकन त्रुटि है। यह मेरे लिए एक बग की तरह लगता है।

काफी सही है।

फिक्स्ड उदाहरण:

//MinimumSize checkbox 
//selected true: set min width = 100px 
//selected false: set min width = 7px(default "a" width) 
//Here's my attempt(I am running JDK 1.7.0_72 on Windows 7): 
import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 
import javax.swing.*; 

public class AlignmentTest4 extends JPanel { 
    private static boolean FLAG = false; 
    @Override public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    g.drawLine(getWidth()/2, 0, getWidth()/2, getHeight()); 
    } 
    @Override public Dimension getPreferredSize() { 
    return new Dimension(300, 80); 
    } 
    public static JLabel makeLabel(String label, int style) { 
    JLabel l = new JLabel(label) { 
     @Override public Dimension getPreferredSize() { 
     return new Dimension(120, 30); 
     } 
     @Override public Dimension getMinimumSize() { 
     Dimension d = super.getMinimumSize(); 
     if (FLAG) { 
      d.width = 100; 
     } else { 
      d.width = 7; 
     } 
     return d; 
     //if (FLAG) { 
     // return this.getPreferredSize(); 
     //} else { 
     // return super.getMinimumSize(); 
     //} 
     } 
    }; 
    l.setOpaque(true); 
    l.setBackground(Color.ORANGE); 
    l.setFont(l.getFont().deriveFont(style)); 
    l.setAlignmentX(Component.CENTER_ALIGNMENT); 
    l.setAlignmentY(Component.CENTER_ALIGNMENT); 
    l.setVerticalAlignment(SwingConstants.CENTER); 
    l.setVerticalTextPosition(SwingConstants.CENTER); 
    l.setHorizontalAlignment(SwingConstants.CENTER); 
    l.setHorizontalTextPosition(SwingConstants.CENTER); 
    return l; 
    } 
    public static JComponent makePanel() { 
    JPanel p = new JPanel(new GridLayout(0, 1, 5, 5)); 

    JPanel p1 = new AlignmentTest4(); 
    p1.setBorder(BorderFactory.createTitledBorder("BoxLayout.X_AXIS")); 
    p1.setLayout(new BoxLayout(p1, BoxLayout.X_AXIS)); 
    p1.add(Box.createHorizontalGlue()); 
    p1.add(makeLabel("a", Font.PLAIN)); 
    p1.add(Box.createHorizontalGlue()); 

    JPanel p2 = new AlignmentTest4(); 
    p2.setBorder(BorderFactory.createTitledBorder("BoxLayout.Y_AXIS")); 
    p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS)); 
    p2.add(Box.createVerticalGlue()); 
    p2.add(makeLabel("a", Font.PLAIN)); 
    p2.add(Box.createVerticalGlue()); 

    for (JPanel c : Arrays.asList(p1, p2)) { 
     c.setBackground(Color.WHITE); 
     p.add(c); 
    } 
    return p; 
    } 
    public static JComponent makeUI() { 
    final JPanel p = new JPanel(new BorderLayout()); 
    p.add(makePanel()); 
    p.add(new JCheckBox(new AbstractAction("MinimumSize") { 
     @Override public void actionPerformed(ActionEvent e) { 
     FLAG = ((JCheckBox) e.getSource()).isSelected(); 
     SwingUtilities.updateComponentTreeUI(p); 
     } 
    }), BorderLayout.SOUTH); 
    return p; 
    } 
    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override public void run() { 
     createAndShowGUI(); 
     } 
    }); 
    } 
    public static void createAndShowGUI() { 
    JFrame f = new JFrame("Alignment Test"); 
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    f.getContentPane().add(makeUI()); 
    f.pack(); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
    } 
} 
+0

बहुत दिलचस्प है। यह अच्छी तरह से काम करता है, लेकिन यह मेरे लिए एक और सवाल लाता है: मुझे समझ में नहीं आ रहा है कि क्यों जावा 'जेनबेल' की 'getMinimumSize()' विधि का उपयोग कर रहा है ताकि यह पता चल सके कि 'जेलाबेल' को कैसे शुरू किया जाए। क्या यह 'जेपीनेल' के वर्तमान आकार का उपयोग नहीं करना चाहिए, न्यूनतम आकार नहीं? –

+0

'जेपीनेल' की 'getMinimumSize() 'विधि इस मामले में अप्रासंगिक है। "यह" कीवर्ड अज्ञात आंतरिक वर्ग ('JLabel') को संदर्भित करता है। '@ ओवरराइड सार्वजनिक आयाम getMinimumSize() {System.out.println (जेएलएबल का यह उदाहरण);/* ट्यूर */इसे वापस करें .getPreferredSize(); } ' – aterai

+0

आह, ठीक है। मुझे लगता है कि उस मामले में संशोधित प्रश्न होगा: 'जेलाबेल' की 'न्यूनतम न्यूनतम() विधि का उपयोग क्यों किया जा रहा है? केंद्र के लिए माप निर्धारित करने के लिए, मुझे लगता है कि वर्तमान आकार का उपयोग किया जाएगा, न्यूनतम आकार नहीं। –

संबंधित मुद्दे