为什么ListCellRenderer中需要removeAll()?
这是我的代码:-
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()
?
This is my code:-
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;
}
}
As you can see I have called removeAll()
method. If I remove that line the data is not displayed properly. All data overlaps each other. And If I add removeAll()
all works fine. Why this happens? Is it necessary to call removeAll()
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您必须重构您的类,以便在构造时创建并添加
MyRender
的所有子级。getListCellRendererComponent()
应该仅用于更改现有组件的值或视觉属性(例如背景)。不要忘记 getListCellRendererComponent() 应该尽可能快(可以非常频繁地调用它),因此它不应该创建组件,而只能修改现有组件。
通常,您的
getListCellRendererComponent()
方法应如下所示:You have to restructure your class so that all children of
MyRender
are created and added at construction time.getListCellRendererComponent()
should be used ONLY to change values or visual attributes (e.g. background) of existing components.Don't forget that
getListCellRendererComponent()
should be as fast as possible (it can be called quite frequently), hence it should not create components but only modify existing ones.Typically, here is how your
getListCellRendererComponent()
method should look like:不,您不必调用removeAll()。我认为您的问题是,每次在此处调用该方法时,您都会在 getListCellRendererComponent 方法内部创建一个新的 JPanel:
如果您将此 JPanel 设为类字段,则可能不必调用removeAll。
编辑:jfpoilpret 回答得更好。给他1+。
No, you shouldn't have to call removeAll(). I think that your problem is that you're creating a new JPanel inside of the getListCellRendererComponent method each time the method is called here:
If you made this JPanel a class field, you would likely not have to call removeAll.
edit: answered better by jfpoilpret. 1+ to him.
还可以在面板上使用
revalidate()
also use
revalidate()
on panel