2012-11-12 38 views
6

के रूप में लिपटे HTML-टेक्स्ट के साथ जेएलएबल एचटीएमएल-टेक्स्ट युक्त जेएलएबल स्वचालित रूप से उपलब्ध स्थान का उपयोग करके लाइनों को लपेटता है। यदि कोई JLabel को JSrollPane में जोड़ता है तो उसे पसंदीदा आकार को एक सभ्य मूल्य पर सेट करना होगा अन्यथा यह लपेट नहीं पाएगा। यह सब एक लेआउटमैनेजर का उपयोग कर जेपीनल के अंदर अन्य घटकों के साथ ठीक काम करना चाहिए।JSLrollPane क्लाइंट

क्योंकि मैं एक आकार बदलने योग्य एप्लिकेशन विंडो चाहता हूं, मैंने आकार बदलने की घटनाओं का ट्रैक रखने के लिए जेएसक्रॉलपेन बढ़ाया और व्यूपोर्ट की चौड़ाई में सिंक किए गए आकार को गतिशील रूप से बदल दिया। असल में यह काम करता है लेकिन कभी-कभी लेआउट मैनेजर द्वारा पसंदीदा ऊंचाई की गणना गलत होती है (मूल्य बहुत बड़ा या बहुत छोटा होता है)। उदाहरण के लिए पहली पंक्ति के माध्यम से लाल सीमा काटने की दृश्यता इंगित करती है कि ऊंचाई की गणना गलत है।

framegrabbing

मैं एक एकल रैपिंग JLabel साथ विफलता पुन: पेश नहीं कर सकते।

import java.awt.Color; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.event.ComponentEvent; 
import java.awt.event.ComponentListener; 
import javax.swing.BorderFactory; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 

public class WrappedLabel implements Runnable { 

    public static void main(String[] args){ 
     SwingUtilities.invokeLater(new WrappedLabel()); 
    } 

    @Override 
    public void run(){ 
     final JPanel panel = new JPanel(new GridBagLayout()); 
     final GridBagConstraints gc = new GridBagConstraints(); 
     gc.fill = GridBagConstraints.BOTH; 
     gc.weightx = 1.0; 
     gc.weighty = 1.0; 
     { 
      gc.gridx = 0; 
      gc.gridy = 0; 
      final JLabel label = new JLabel(
       "<html>" + "please add some more text here" 
      ); 
      label.setBorder(BorderFactory.createLineBorder(Color.RED)); 
      panel.add(label, gc); 
     } 
     { 
      gc.gridx = 0; 
      gc.gridy = 1; 
      final JLabel label = new JLabel(
       "<html>" + "please add some more text here" 
      ); 
      label.setBorder(BorderFactory.createLineBorder(Color.RED)); 
      panel.add(label, gc); 
     } 
     final JFrame frame = new JFrame(); 
     frame.add(new ScrollPane(panel)); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.setSize(256, 256); 
     frame.setVisible(true); 
    } 

    private class ScrollPane extends JScrollPane implements ComponentListener { 

     ScrollPane(Container view){ 
      super(view); 
      this.viewport.addComponentListener(this); 
     } 

     @Override 
     public void componentHidden(ComponentEvent ce){ 
     } 

     @Override 
     public void componentMoved(ComponentEvent ce){ 
     } 

     /** calculating required height is a 3 step process 
      * 1. sync width of client and viewport, set height of client to high value 
      * 2. let GridbagManager calculate required minimum size 
      * 3. set preferredSize and revalidate 
     **/ 
     @Override 
     public void componentResized(ComponentEvent ce){ 
      assert(this.viewport == ce.getSource()); 
      final Container view = (Container) this.viewport.getView(); 
      final int width = this.viewport.getExtentSize().width; 
      view.setPreferredSize(new Dimension(width, Integer.MAX_VALUE)); 
      final int height = view.getLayout().preferredLayoutSize(view).height; 
      view.setPreferredSize(new Dimension(width, height)); 
      view.revalidate(); 
     } 

     @Override 
     public void componentShown(ComponentEvent ce){ 
     } 

    } 

} 
+0

+1 अच्छा सवाल – mKorbel

+5

'// कुछ पाठ here' जोड़ने उह , नहीं धन्यवाद, मैं इसे * आप * करने के लिए छोड़ दूंगा। वास्तव में, जल्द से जल्द बेहतर सहायता के लिए, एक [एसएससीसीई] (http://sscce.org/) पोस्ट करें। –

उत्तर

1

जाहिर है यह या तो GridBagLayout में एक बग है, या आप एक तरह से पूरी तरह से डेवलपर्स द्वारा अप्रत्याशित में लेआउट इंजन का उपयोग कर रहे हैं। एचटीएमएल के साथ कई मल्टी-लाइन लेबल्स, पसंदीदा आकार सेट करना और तुरंत पीछे के दरवाजे से पसंदीदा आकार पूछना? ओह!

मैंने देखा कि कभी-कभी लेआउट विंडो आकार घटते समय लेआउट गलत तरीके से काम करता है: scrollpane के अंदर पैनल कम नहीं होता है और क्षैतिज स्क्रॉलबार प्रकट होता है। (मैं रास्ते में विंडोज का उपयोग कर रहा हूँ)।

when decreasing

इसके अलावा, कभी कभी, अगर खड़ी स्क्रॉलबार दिखाई दे रही थी और पैनल ऊंचाई बड़ी थी, और उसके बाद मैं खिड़की के आकार में वृद्धि, पैनल ऊंचाई अनुचित रूप से बड़ी बनी हुई है और अंतराल लेबल के चारों ओर दिखाई देते हैं:

enter image description here

मेरे लिए, जब मैं खिड़की कम करता हूं तो लेआउट हर बार गलत होता है; बढ़ते काम बेहतर होते हैं लेकिन यदि यह गलत हो जाता है, तो यह हर बार भी गलत होता है। मैंने कंसोल करने के लिए डीबगिंग और प्रिंटिंग मानों की कोशिश की; ऐसा लगता है कि view.getLayout().preferredLayoutSize(view) न केवल view.setPreferredSize पर निर्भर करता है बल्कि पैनल और स्क्रॉलपेन के वर्तमान आकार पर भी निर्भर करता है। ग्रिडबैगलाउट का कोड गोता लगाने के लिए बहुत जटिल है।

गंदे हैक

के बाद से हर दूसरे आकार सही परिणाम पैदावार, क्यों नहीं इसे दो बार आकार परिवर्तन? ScrollPane.componentResized हैंडलर में चीजों को डुप्लिकेट करना असफल रहा, संभवतः क्योंकि स्क्रॉलपेन का आकार वही रहता है। स्क्रॉलपैन को अलग-अलग मानों के साथ दो बार आकार बदलना होगा। इसे सबसे सरल तरीके से परीक्षण करने के लिए, मैंने जेएफआरएएम को उप-वर्गीकृत किया: यह componentResized सुनता है और इसकी बाल विंडो दो बार बदलता है। दूसरे आकार को SwingUtilities.invokeLater के माध्यम से स्थगित करना होगा।

द्वारा

final MyFrame frame = new MyFrame(scroll); 

लाइनों

final JFrame frame = new JFrame(); 
frame.add(scroll); 

बदलें और निम्नलिखित वर्ग जोड़ें:

private class MyFrame extends JFrame implements ComponentListener { 

    private Component child; 

    public MyFrame(Component child){ 
     this.child=child; 
     setLayout(null); 
     getContentPane().add(child); 
     addComponentListener(this); 
    } 

    public void componentResized(ComponentEvent e) { 
     Dimension size=getContentPane().getSize(); 
     child.setSize(new Dimension(size.width-1,size.height)); 
     validate(); 
     SwingUtilities.invokeLater(new ResizeRunner(size)); 
    } 

    public void componentMoved(ComponentEvent e) {} 
    public void componentShown(ComponentEvent e) {} 
    public void componentHidden(ComponentEvent e) {} 

    private class ResizeRunner implements Runnable { 
     private Dimension size; 
     public ResizeRunner(Dimension size){ 
      this.size=size; 
     } 
     public void run() { 
      child.setSize(size); 
      validate(); 
     } 
    } 

} 

ही एक लेआउट प्रबंधक उपवर्गीकरण द्वारा प्राप्त किया जा सकता है।

जाहिर है, इस दृष्टिकोण असजीला और अक्षम है, लेकिन एक JRE बग के लिए एक समाधान के रूप, और कुछ नहीं में मदद करता है, तो ... ;-)

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

  • कोई संबंधित समस्या नहीं^_^