2012-08-01 234 views
2

我想添加一个我想你会称之为列表中的每个项目的子列表。我已经构建了一个自定义渲染器,它提供了下面的输出。正如你可以看到有些事情不是在这里,我没有运气追踪我的问题的答案。我猜我需要在面板的布局中改变一些东西来获得正确的结果,但不知道是什么。Jlist自定义渲染器

http://i.stack.imgur.com/jCKjJ.jpg

import java.awt.BorderLayout; 
import java.awt.Component; 
import java.awt.Container; 
import java.awt.GridLayout; 
import java.util.Random; 
import javax.swing.JCheckBox; 
import javax.swing.JLabel; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JSeparator; 
import javax.swing.ListCellRenderer; 
import javax.swing.border.EmptyBorder; 

public class GAListRendererAdv extends Container implements ListCellRenderer { 
private static final long serialVersionUID = 1L; 
private JPanel pnl = new JPanel(); 
private Random rnd = new Random(); 

public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, 
     boolean cellHasFocus) { 

    pnl.setLayout(new BorderLayout(0, 0)); 

    JCheckBox chckbxSomething = new JCheckBox("something"); 
    pnl.add(chckbxSomething, BorderLayout.NORTH); 

    JSeparator separator = new JSeparator(); 
    pnl.add(separator, BorderLayout.CENTER); 

    JPanel panel_1 = new JPanel(); 
    panel_1.setBorder(new EmptyBorder(0, 35, 0, 0)); 
    pnl.add(panel_1, BorderLayout.SOUTH); 
    panel_1.setLayout(new GridLayout(0, 1, 0, 0)); 

    int rndNum = rnd.nextInt(5) + 1; 

    for (int i = 0; i < rndNum; i ++) { 
    JLabel lblNewLabel2 = new JLabel("New label"); 
    panel_1.add(lblNewLabel2); 
    } 

    return pnl; 
} 
} 

回答

4

首先,请记住,CellRenderers被用作摆动 “橡皮图章”。这样做是为了节省内存并帮助提高性能。这允许组件像JList一样维护对渲染器的单个引用,但仍绘制列表中的所有项目。

这意味着,当调用getListCellRendererComponent时,渲染器将处于与上次调用相同的状态。

从我可以从你的代码来讲,这将意味着,每个渲染器被调用时,添加了另一个复选框,将另一隔离另一个小组和其它更多的标签...

所有其次,渲染器尽可能不要在getListCellRendererComponent中创建任何内容,这只会增加内存使用量(部分代码可能没有选择)。

第三,JList不支持编辑器,因为我之前说过的原因,渲染器不是编辑器。

正。在将所有元素添加到面板之前,尝试从面板的“正文”部分删除内容。

// Don't use Container, use JPanel instead, mixing heavy and light weight components 
// is never a good idea :P 
public class GAListRendererAdv extends JPanel implements ListCellRenderer { 
    private static final long serialVersionUID = 1L; 
    private JPanel pnl = new JPanel(); 
    private Random rnd = new Random(); 

    private JCheckBox checkBox; 

    public GAListRendererAdv() { 

     setLayout(new BorderLayout(0, 0));    
     checkBox = new JCheckBox(); 

     add(checkBox, BorderLayout.NORTH); 
     add(new JSeparator(), BorderLayout.CENTER); 

     pnl = new JPanel(new GridLayout(0, 1, 0, 0)); 
     pnl.setBorder(new EmptyBorder(0, 35, 0, 0)); 

     add(pnl BorderLayout.SOUTH); // Don't forget to add the panel :P 

    } 

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 

     pnl.removeAll(); 
     int rndNum = rnd.nextInt(5) + 1; 

     for (int i = 0; i < rndNum; i ++) { 
      JLabel lblNewLabel2 = new JLabel("New label"); 
      pnl.add(lblNewLabel2); 
     } 

     return this; 
    } 
+1

Hi @MadProgrammer。你说:“第三,JList不支持编辑器,渲染器不是编辑器”。所以,这里是我的问题,那么你会怎么做,然后制作一个可编辑的组件列表(或序列)? 具体来说,我通过CellRenderer填充JList中的自定义窗格,但所有funcionallity(如按钮等)不起作用。 – giorgiline 2012-10-21 21:15:46

+0

简单的解决方案是实际使用一个单独的列'JTable'。你可以逃脱不通过覆盖模型的'getColumnName'方法,并返回一个空字符串 – MadProgrammer 2012-10-21 22:30:17

+0

所以@MadProgrammer,这样的表必须与特定的实现为TableCellEditor的设置或我错了显示列名?自定义单元格渲染仍然不允许按钮交互。 也许更好的解决方案是将组件添加到ScrollPane中的LayoutManager中?我不知道如何做到这一点,但我会乱它。 – giorgiline 2012-10-22 10:48:12