为什么在ListCellRenderer中需要removeAll()?

时间:2011-05-18 10:04:52

标签: java swing listcellrenderer

这是我的代码: -

public class MyRender extends JPanel implements ListCellRenderer {

    ImageIcon on_img;
    JLabel name = new JLabel();
    JLabel icn = new JLabel();
    JLabel img = new JLabel();

    public MyRender(Atalk) {
        setOpaque(true);
        setBackground(Color.WHITE);
        setForeground(Color.black);
        on_img = new ImageIcon(MyCls.class.getClassLoader().getResource("imgPath"));
    }

    @Override
    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {
        if (value != null) {
            removeAll();
            setLayout(new BorderLayout());
            User user = (User) value;
            String pres = user.getPresence().toLowerCase();
            img.setIcon(default_img);
            if (pres.contains("unavailable"))
                icn.setIcon(off_img);
            else
                icn.setIcon(on_img);
            name.setText(user.getName());
            JPanel panel = new JPanel();
            panel.setLayout(new BorderLayout());

            add(img, BorderLayout.EAST);
            add(icn, BorderLayout.WEST);

            panel.add(st, BorderLayout.CENTER);
            panel.add(name, BorderLayout.NORTH);

            add(panel, BorderLayout.CENTER);

            JLabel lbl = new JLabel(" ");
            lbl.setSize(100, 5);
            add(lbl, BorderLayout.AFTER_LAST_LINE);

            if (isSelected) {
                setBackground(Color.lightGray);
                panel.setBackground(Color.lightGray);
            } else {
                setBackground(Color.white);
                panel.setBackground(Color.white);
            }

            return this;
        }
        return null;
    }
}

如您所见,我调用了removeAll()方法。如果我删除该行,则数据无法正确显示。所有数据都相互重叠。如果我添加removeAll()一切正常。为什么会这样?是否有必要致电removeAll()

3 个答案:

答案 0 :(得分:4)

您必须对课程进行重组,以便在施工时创建并添加MyRender的所有子项。

getListCellRendererComponent()应使用来更改现有组件的值或视觉属性(例如背景)。

不要忘记getListCellRendererComponent()应该尽可能快(可以经常调用它),因此它不应该创建组件,而只能修改现有组件。

通常,以下是getListCellRendererComponent()方法的外观:

@Override
public Component getListCellRendererComponent(
    JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
    if (value != null) {
        User user = (User) value;
        String pres = user.getPresence().toLowerCase();
        img.setIcon(default_img);
        if (pres.contains("unavailable"))
            icn.setIcon(off_img);
        else
            icn.setIcon(on_img);
        name.setText(user.getName());
        if (isSelected) {
            setBackground(Color.lightGray);
            panel.setBackground(Color.lightGray);
        } else {
            setBackground(Color.white);
            panel.setBackground(Color.white);
        }
    }
    return this;
}

答案 1 :(得分:1)

不,你不应该调用removeAll()。我认为你的问题是你每次在这里调用方法时都在getListCellRendererComponent方法中创建一个新的JPanel:

JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());

如果您将此JPanel设为类字段,则可能不必调用removeAll。

编辑:jfpoilpret更好地回答。 1+给他。

答案 2 :(得分:0)

也可以在面板上使用revalidate()