Jlist自定义渲染器 [英] Jlist Custom Renderer

查看:173
本文介绍了Jlist自定义渲染器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试添加一个我想您可以将其称为子列表的列表中的每个项目.我建立了一个自定义渲染器,提供以下输出.如您所见,这里不对劲,我没有运气来寻找问题的答案.我想我需要更改面板布局中的某些内容以获得正确的结果,但不知道是什么.

I'm trying to add a i guess you would call it a sub list to each item on a list. I've built a custom renderer that gives the below output. As you can see something isn't right here an i've had no luck tracking down an answer to my problem. I'm guessing i need to change something in the layout of the panel to get the correct result but no idea what.

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

推荐答案

首先,请记住,CellRenderers在Swing中用作橡皮图章".这样做是为了节省内存并帮助提高性能.这样,像JList这样的组件就可以维护对渲染器的单一引用,但仍可以绘制列表中的所有项目.

Firstly, remember, CellRenderers are used as "rubber stamps" in Swing. This is done to save memory and help increase performance. This allows components, like JList, to maintain a single reference to the renderer but still paint all the items in the list.

这意味着,无论何时调用getListCellRendererComponent,渲染器都将处于与上次调用时相同的状态.

This means, that when ever getListCellRendererComponent is called, the renderer will be in the same state it was last it was called.

从我的代码中可以看出,这意味着每次调用渲染器时,您都会添加一个ANOTHER复选框,一个ANOTHER分隔符,一个ANOTHER面板以及更多标签...

From what I can tell from your code, this will mean that each time the renderer is called, you add ANOTHER checkbox, ANOTHER separator ANOTHER panel and lots more labels...

第二,对于渲染器,尽量不要在getListCellRendererComponent中创建任何内容,这只会增加内存使用率(部分代码可能没有选择).

Secondly of all, with renderers, try not to create anything in the the getListCellRendererComponent where possible, this is just increasing you memory usage (part of your code may not have a choice).

第三,由于我之前提到的原因,JList不支持编辑器,渲染器不是编辑器.

Thirdly, JList does not support editors, renderers are not editors, for the reasons I've stated before.

第四.在将所有元素添加到面板的正文"部分之前,请尝试删除其中的内容.

Forthly. Try removing the content from the "body" portion of the panel before adding all your elements to it.

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

这篇关于Jlist自定义渲染器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆