Почему removeAll () требуется в ListCellRenderer? - PullRequest
2 голосов
/ 18 мая 2011

Это мой код: -

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 ]

4 голосов
/ 18 мая 2011

Вы должны реструктурировать свой класс так, чтобы все дочерние элементы 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 голос
/ 18 мая 2011

Нет, вам не нужно вызывать removeAll ().Я думаю, что ваша проблема в том, что вы создаете новый JPanel внутри метода getListCellRendererComponent каждый раз, когда вызывается метод:

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

Если вы сделали этот JPanel полем класса, вы, вероятно, невызвать removeAll.

edit: лучше ответил jfpoilpret.1+ ему.

0 голосов
/ 18 мая 2011

также используйте revalidate() на панели

...