2011-05-18 66 views
2

这是我的代码: -为什么在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()

+0

通常情况下,你不需要那样做。但这取决于你在JPanel中放置了什么。显示更多代码可能会很有用,特别是构造函数和getListCellRenderer的其余部分。 – jfpoilpret 2011-05-18 10:08:52

+0

还要注意你的方法不应该返回null。 – jfpoilpret 2011-05-18 10:09:31

+0

@jfpoilpret:用类代码更新了我的问题。 – 2011-05-18 10:16:32

回答

3

你必须使创建,在施工时加入的MyRender所有儿童进行重组类上使用revalidate()

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; 
} 
+0

然后,我应该在'User'对象上进行处理? – 2011-05-18 11:53:16

+0

我不明白你的问题;在我上面的代码片断中,我没有移动任何与用户有关的东西。我做出的唯一更改与不变的组件有关,应该在开始时创建并添加到MyRender中。 – jfpoilpret 2011-05-18 12:10:27

+0

抱歉误会。得到它没有'removeAll()'工作。日Thnx。 – 2011-05-18 12:32:29

0

还面板

+0

在哪里调用'revalidate()'?最后? – 2011-05-18 10:20:35

+0

只是在removeAll() – 2011-05-18 10:22:41

+0

不,你没有得到我。我想要的是摆脱'removeAll()'。用'removeAll()'一切正常,不需要额外添加任何东西。 – 2011-05-18 10:24:47

1

不,你不应该调用的removeAll()。我觉得你的问题是,你每次都创建内部getListCellRendererComponent方法的新JPanel的方法,这里所说的:

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

如果进行此JPanel类字段,你可能不会有调用移除所有。

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