2011-09-05 32 views
12

Tôi đã đọc/thử các bài viết nhưng điều đó không giúp:Swing JList với văn bản nhiều dòng và chiều cao năng động

Những gì tôi cần là ListCellRenderer trả về bảng điều khiển có biểu tượng ở bên trái và văn bản có độ dài động ở bên phải (như trong bất kỳ diễn đàn nào: ở bên trái hình đại diện của người dùng, ở bên phải t anh ấy đăng văn bản). Các văn bản là NOT được tôi biết, vì vậy tôi không thể đặt chiều cao ô cố định. Hơn nữa, độ dài văn bản khác với ô danh sách để liệt kê ô. Vì vậy, mỗi ô danh sách cần chiều cao của riêng nó tùy thuộc vào độ dài của văn bản. Trên thực tế một bố trí thực sự phổ biến ... nhưng không phải cho Swing. Chiều cao ô chỉ không mở rộng theo độ dài văn bản.

Tôi đã đọc hầu hết mọi bài đăng ở đó về chiều cao ô động và văn bản nhiều dòng trong JList, nhưng không thể tìm thấy giải pháp. Vì vậy, tôi quyết định đưa ra một SSCCE nhỏ. Xin vui lòng cho tôi một gợi ý về làm thế nào để đạt được những gì tôi mô tả hoặc xin vui lòng sửa mã của tôi nếu bạn nghĩ rằng nó dễ dàng.

Cảm ơn

Đây là ths 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

không liên quan đến vấn đề ở bàn tay: a) neve Các thành phần r-ever _create_ trong các lớp getXXRendererComponent b) không _extend_ nếu mới không đáp ứng yêu cầu là một yêu cầu – kleopatra

+1

Lưu ý rằng một SSCCE phải bao gồm cả việc nhập khẩu. Không phải tất cả chúng ta đều sử dụng các IDE tự động hóa có thể tìm ra chúng! –

+0

Tôi sẽ ghi nhớ điều đó trong đầu – haferblues

Trả lời

15

Sửa 1: oops - nhìn thấy @ ảnh chụp màn hình của Andrew, nhận ra rằng đây không hoạt động như mong đợi , văn bản thực sự dài hơn hiển thị với điều này (bỏ qua một nhận xét nội bộ "ĐANG ĐANG: không làm việc cho JList trong JScrollPane"; -) Sẽ đào một chút và xóa câu trả lời này nếu tôi không thể làm cho nó hoạt động sớm.

Chỉnh sửa 2: đã nhận được - việc triển khai trình kết xuất như được hiển thị bên dưới không sao, thủ phạm là JList với bộ nhớ đệm kích thước tối ưu ít thường xuyên hơn. Có hai phần của số đó

  • Bộ nhớ cache cơ bản trong một ComponentListener
  • Việc triển khai có thể cuộn của danh sáchXuất đườngWidth chứa logic đứng trong đường dẫn (dẫn đến kéo dài vòng lặp của khu vực cho đến khi nó là một dòng đơn), phân lớp để trả về true.

Mã mà sử dụng các renderer dưới đây:

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)); 

câu trả lời đầu tiên (một việc thực hiện kết xuất đồ họa trong đó sử dụng JTextArea như render thành phần)

TextArea là một chút khó khăn trong kích thước: nó cần phải được khởi tạo cho một cái gì đó hợp lý:

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

điều này thực sự hoạt động hoàn hảo. Tôi vừa thay thế int width = list.getWidth() bởi int width = list.getWidth() - l.getIcon(). GetIconWidth(); Nếu không chiều cao của vùng văn bản được tính như thể tổng chiều rộng của danh sách có sẵn cho nó. Cảm ơn bạn rất nhiều. Tôi cũng đã học được rất nhiều ngày hôm nay. – haferblues

+0

@haferblues - bắt tốt điều chỉnh với phần còn lại chiều rộng, nhờ :-) – kleopatra

+0

@ kleopatra - sửa chữa tốt đẹp! Tôi đã xé tóc ra! –

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

darn .. bị đánh đập lần nữa, một ảnh chụp màn hình _with_ :-) – kleopatra

+0

Bạn quá bận rộn không cho lời khuyên tốt về việc không tạo thành phần trong trình kết xuất đồ họa. ;) –

+0

http://stackoverflow.com/questions/6901153/expand-jlist-row-height-depending-on-content/6902589#6902589, nhưng cả hai +1 – mKorbel

Các vấn đề liên quan