Java 为什么ListCellRenderer中需要removeAll()?
这是我的代码:-Java 为什么ListCellRenderer中需要removeAll()?,java,swing,listcellrenderer,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);
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?还可以在面板上使用重新验证您必须重新构造类,以便在构建时创建并添加MyRender的所有子级 GetListCellRenderComponent应仅用于更改值或视觉属性,例如现有组件的背景 不要忘记GetListCellRenderComponent应该尽可能快,因为它可以被频繁调用,因此它不应该创建组件,而应该只修改现有的组件 通常,以下是GetListCellRenderComponent方法的外观:
@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。我认为您的问题在于每次在此处调用getListCellRenderComponent方法时,您都在该方法内部创建一个新的JPanel:
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
如果将此JPanel设置为类字段,则可能不必调用removeAll
编辑:由jfpoilpret更好地回答。1+给他。通常,你不需要这样。但这取决于你在JPanel里放了什么。显示更多代码可能会很有用,特别是构造函数和getListCellRenderer的其余部分。还请注意,您的方法不应返回null。@jfpoilpret:用类代码更新了我的问题。@Harry Joy。。。真的不需要,removeAll是job for Action,包括JPanel的paintBorder和ListCellRendered,默认情况下返回JLabel,现在我的问题1由JButton Action开始,您将更改JList内容,JList包含JLabel+图标+图像图标2我们谈论的是一个JList 3,但只有一个或多个JListJList@mKorbel:回答:1是Jlist包含JPanel,其中包括JLabel、ImageIcon,我稍后还会对Jlist执行操作。2总计4 Jlist,但所有共享都拥有新的MyRender。3是的。不要在@和`人名'之间使用空格,它不会通知此人。在哪里调用重新验证?最后?不,你不会明白的。我想要的是摆脱removeAll。使用removeAll可以正常工作,无需添加任何额外内容。非常好的建议,但如果您添加了一些JComponents,则只需调用revalidate,但如果您删除了一些JComponents,则需要调用revalidate+repaint,remove->add->revalidate+repaint;那么我应该在哪里对用户对象进行处理呢?我不理解你的问题;在上面的代码片段中,我没有移动任何与用户相关的内容。我所做的唯一更改是与不变组件相关的,应该在开始时创建并添加到MyRender中。很抱歉误解。没动就成功了。Thnx。