2011-09-05 14 views
12

मैं पहले से ही पढ़ने/इन पदों की कोशिश की लेकिन वह मदद नहीं की:स्विंग JList

मैं क्या जरूरत है एक ListCellRenderer जो बाएं ओर एक आइकन के साथ एक पैनल और दाईं ओर गतिशील लंबाई का एक पाठ देता है (जैसे किसी भी मंच में: बाईं तरफ उपयोगकर्ता अवतार, दाईं ओर वह पाठ पोस्ट)। ग्रंथ नहीं मुझे ज्ञात हैं, इसलिए मैं एक निश्चित सेल ऊंचाई निर्धारित नहीं कर सकता। इसके अलावा, पाठ की लंबाई सूची सेल से सूची कक्ष में भिन्न होती है। इसलिए पाठ की लंबाई के आधार पर प्रत्येक सूची कक्ष को अपनी ऊंचाई की आवश्यकता होती है। दरअसल वास्तव में एक आम लेआउट ... लेकिन स्विंग के लिए नहीं। सेल ऊंचाई बस पाठ की लंबाई के अनुसार विस्तार नहीं करता है।

मैंने JList में डायनामिक सेल हाइट्स और मल्टीलाइन ग्रंथों के बारे में लगभग किसी भी पोस्ट को पढ़ा है, लेकिन समाधान नहीं मिला। तो मैंने एक छोटा सा एसएससीसीई देने का फैसला किया। कृपया मुझे बताएं कि मैंने जो वर्णन किया है उसे हासिल करने के लिए या कृपया मेरे कोड को ठीक करें यदि आपको लगता है कि यह आसान है।

धन्यवाद

यहाँ चौथाई SSCCE है:

public class MultiLineList extends JFrame 
{ 

    private static final long serialVersionUID = 1L; 

    public static void main(final String[] args) 
    { 
     new MultiLineList(); 
    } 

    private MultiLineList() 
    { 
     setTitle("MultiLineList"); 
     setSize(800, 450); 
     setResizable(true); 
     setVisible(true); 
     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     this.getContentPane().setLayout(new BorderLayout()); 

     final DefaultListModel model = new DefaultListModel(); 
     model.addElement("This is a short text"); 
     model.addElement("This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. "); 
     model.addElement("This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. "); 

     final JList list = new JList(model); 
     list.setCellRenderer(new MyCellRenderer()); 

     this.add(list); 

     this.getContentPane().invalidate(); 
     this.getContentPane().validate(); 

    } 

    public class MyCellRenderer extends DefaultListCellRenderer 
    { 
     @Override 
     public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean hasFocus) 
     { 

      final String text = (String) value; 

      //create panel 
      final JPanel p = new JPanel(); 
      p.setLayout(new BorderLayout()); 

      //icon 
      final JPanel IconPanel = new JPanel(new BorderLayout()); 
      final JLabel l = new JLabel("icon"); //<-- this will be an icon instead of a text 
      IconPanel.add(l, BorderLayout.NORTH); 
      p.add(IconPanel, BorderLayout.WEST); 

      //text 
      final JTextArea ta = new JTextArea(); 
      ta.setText(text); 
      ta.setLineWrap(true); 
      ta.setWrapStyleWord(true); 
      p.add(ta, BorderLayout.CENTER); 

      return p; 

     } 
    } 

} 
+0

हाथ से समस्या से असंबंधित: ए) neve getXXRendererComponent में r-ever _create_ घटक b) _extend_ कक्षाएं न करें अगर नया पूरा नहीं करता है- एक आवश्यकता – kleopatra

+1

ध्यान दें कि एक एसएससीसीई में आयात शामिल होना चाहिए। हम सभी ऑटोमैजिक आईडीई का उपयोग नहीं करते हैं जो उन्हें समझ सकते हैं! –

+0

मैं इसे ध्यान में रखूंगा – haferblues

उत्तर

15

संपादित करें 1: उफ़ - @ एंड्रयू स्क्रीनशॉट देखकर, महसूस किया कि इस अपेक्षा के अनुरूप काम नहीं कर रहा , टेक्स्ट वास्तव में इसके साथ दिखाए जाने से अधिक लंबा है (एक आंतरिक टिप्पणी को अनदेखा किया गया है "PENDING: JSCrollPane में JList के लिए काम नहीं कर रहा है"; -) थोड़ा सा खोद जाएगा और अगर मैं इसे जल्द ही काम नहीं कर सकता तो यह जवाब हटा दूंगा।

संपादित करें: इसे मिला - नीचे दिखाए गए प्रस्तुतकर्ता कार्यान्वयन ठीक है, अपराधी जेएलिस्ट है जो कभी-कभी इष्टतम आकार कैशिंग से कम है। वहाँ कि

  • BasicListUI के दो हिस्सों को ध्यान में नहीं ले करता है कि सूची का आकार बदलने के आंतरिक आकार समाशोधन की आवश्यकता हो सकती हैं (वास्तव में पंक्ति की ऊँचाई) कैश, आवेदन कोड ऐसा करने के लिए उसे बलपूर्वक चाहिए, f.i. एक घटक लिस्टर
  • सूची के ट्रैक के स्क्रॉल करने योग्य कार्यान्वयन ViewportWidth में तर्क है जो रास्ते में खड़ा होता है (क्षेत्र की लूपिंग क्षेत्र को तब तक बाहर ले जाता है जब तक कि यह एक पंक्ति नहीं हो), सबक्लास सत्य लौटने के लिए।

कोड नीचे रेंडरर का उपयोग करता है:

final JList list = new JList(model) { 

     /** 
     * @inherited <p> 
     */ 
     @Override 
     public boolean getScrollableTracksViewportWidth() { 
      return true; 
     } 


    }; 
    list.setCellRenderer(new MyCellRenderer()); 

    ComponentListener l = new ComponentAdapter() { 

     @Override 
     public void componentResized(ComponentEvent e) { 
      // next line possible if list is of type JXList 
      // list.invalidateCellSizeCache(); 
      // for core: force cache invalidation by temporarily setting fixed height 
      list.setFixedCellHeight(10); 
      list.setFixedCellHeight(-1); 
     } 

    }; 

    list.addComponentListener(l); 
    add(new JScrollPane(list)); 

पहले जवाब (दाता कार्यान्वयन जो घटक प्रतिपादन के रूप में JTextArea उपयोग करता है)

TextArea थोड़ा आकार में मुश्किल है: यह करने की जरूरत है कुछ उचित के लिए आरंभ करें:

public class MyCellRenderer implements ListCellRenderer { 

    private JPanel p; 
    private JPanel iconPanel; 
    private JLabel l; 
    private JTextArea ta; 

    public MyCellRenderer() { 
     p = new JPanel(); 
     p.setLayout(new BorderLayout()); 

     // icon 
     iconPanel = new JPanel(new BorderLayout()); 
     l = new JLabel("icon"); // <-- this will be an icon instead of a 
           // text 
     iconPanel.add(l, BorderLayout.NORTH); 
     p.add(iconPanel, BorderLayout.WEST); 

     // text 
     ta = new JTextArea(); 
     ta.setLineWrap(true); 
     ta.setWrapStyleWord(true); 
     p.add(ta, BorderLayout.CENTER); 
    } 

    @Override 
    public Component getListCellRendererComponent(final JList list, 
      final Object value, final int index, final boolean isSelected, 
      final boolean hasFocus) { 

     ta.setText((String) value); 
     int width = list.getWidth(); 
     // this is just to lure the ta's internal sizing mechanism into action 
     if (width > 0) 
      ta.setSize(width, Short.MAX_VALUE); 
     return p; 

    } 
} 
+0

यह वास्तव में सही काम करता है। मैंने int चौड़ाई = list.getWidth() को int चौड़ाई = list.getWidth() - l.getIcon() से बदल दिया है IconWidth(); अन्यथा Textarea की ऊंचाई की गणना की जाती है जैसे सूची की कुल चौड़ाई इसके लिए उपलब्ध है। बहुत बहुत धन्यवाद। मैंने आज भी बहुत कुछ सीखा। – haferblues

+0

@ हफरब्लूज़ - बाकी चौड़ाई को समायोजित करने के लिए अच्छी पकड़, धन्यवाद :-) – kleopatra

+0

@ क्लेओपेट्रा - अच्छा फिक्स! मैं अपने बालों को फाड़ रहा था! –

11

Multi-Line List

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

public class MultiLineList 
{ 
    private static final long serialVersionUID = 1L; 

    public static void main(final String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new MultiLineList(); 
      } 
     }); 
    } 

    private MultiLineList() 
    { 
     JFrame f = new JFrame("MultiLineList"); 
     f.setResizable(true); 
     f.setVisible(true); 
     f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     f.getContentPane().setLayout(new BorderLayout()); 

     final DefaultListModel model = new DefaultListModel(); 
     model.addElement("This is a short text"); 
     model.addElement("This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. "); 
     model.addElement("This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. This is an even longer text. "); 

     final JList list = new JList(model); 
     list.setCellRenderer(new MyCellRenderer()); 

     f.add(list); 

     f.pack(); 
    } 

    public class MyCellRenderer extends DefaultListCellRenderer 
    { 
     final JPanel p = new JPanel(new BorderLayout()); 
     final JPanel IconPanel = new JPanel(new BorderLayout()); 
     final JLabel l = new JLabel("icon"); //<-- this will be an icon instead of a text 
     final JLabel lt = new JLabel(); 
     String pre = "<html><body style='width: 200px;'>"; 

     MyCellRenderer() { 
      //icon 
      IconPanel.add(l, BorderLayout.NORTH); 
      p.add(IconPanel, BorderLayout.WEST); 

      p.add(lt, BorderLayout.CENTER); 
      //text 
     } 

     @Override 
     public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean hasFocus) 
     { 
      final String text = (String) value; 
      lt.setText(pre + text); 

      return p; 
     } 
    } 
} 
+4

डर्न .. फिर से पीटा गया, _with_ स्क्रीनशॉट :-) – kleopatra

+0

आप रेंडरर में घटकों को न बनाने के बारे में अच्छी सलाह दे रहे थे। ;) –

+0

http://stackoverflow.com/questions/6901153/expand-jlist-row-height-depending-on-content/6902589#6902589, लेकिन दोनों +1 – mKorbel