Jlist Custom Renderer

本小妞迷上赌 提交于 2021-02-04 19:49:13

问题


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

回答1:


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.

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

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...

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

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


来源:https://stackoverflow.com/questions/11751191/jlist-custom-renderer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!