2011-05-18 58 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+給他。