【问题标题】:Jlist Custom RendererJlist 自定义渲染器
【发布时间】:2012-08-01 01:01:14
【问题描述】:

我正在尝试添加一个我猜你会称它为列表中每个项目的子列表。我已经构建了一个自定义渲染器,它提供了以下输出。正如您所看到的,这里有些东西不正确,我没有运气找到我的问题的答案。我猜我需要更改面板布局中的某些内容以获得正确的结果,但不知道是什么。

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

【问题讨论】:

    标签: java swing jlist renderer


    【解决方案1】:

    首先,请记住,CellRenderers 在 Swing 中被用作“橡皮图章”。这样做是为了节省内存并帮助提高性能。这允许组件(如 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;
        }
    

    【讨论】:

    • 嗨@MadProgrammer。您说:“第三,JList 不支持编辑器,渲染器不是编辑器”。所以,我的问题是,你会怎么做来展示,并制作一个可编辑的组件列表(或序列)?具体来说,我正在通过 CellRenderers 在 JList 中填充自定义窗格,但所有功能(如按钮等)都不起作用。
    • 简单的解决方案是实际使用单个列JTable。您可以通过覆盖模型的getColumnName 方法并返回一个空字符串来避免不显示列名
    • 所以@MadProgrammer,那样必须使用 TableCellEditor 的特定实现来设置表格,还是我错了?呈现的自定义单元格仍然不允许按钮交互。也许更好的解决方案是将组件动态添加到 ScrollPane 内的 LayoutManager?,我不知道该怎么做,但我会搞砸它。
    • 好吧,在这种情况下,使用布局管理器并将组件动态添加到容器窗格中要容易得多,而不是使用表格或列表或其他任何东西。没有渲染器和编辑器。然后使用 removeAll() ---> validate(), repaint() 到容器窗格来改变内容。
    猜你喜欢
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 2017-06-09
    • 2017-11-24
    • 2013-09-25
    • 2011-07-14
    • 1970-01-01
    • 2010-10-19
    相关资源
    最近更新 更多