Почему removeAll() требуется в 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 ответа
Вы должны реструктурировать свой класс так, чтобы все дети 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;
}
Нет, вам не нужно вызывать removeAll(). Я думаю, что ваша проблема в том, что вы создаете новый JPanel внутри метода getListCellRendererComponent каждый раз, когда вызывается метод здесь:
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
Если бы вы сделали этот JPanel полем класса, вам, скорее всего, не пришлось бы вызывать removeAll.
редактировать: лучше ответил jfpoilpret. 1+ для него.