Why is removeAll () required in ListCellRenderer?

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 called the removeAll() method. If I delete this line, the data will not display correctly. All data overlap. And if I add removeAll() , everything works fine. Why is this happening? Should I call removeAll() ?

+2
source share
3 answers

You must restructure your class so that all MyRender children are created and added at build time.

getListCellRendererComponent() should be used ONLY to change the values ​​or visual attributes (e.g. background) of existing components.

Do not forget that getListCellRendererComponent() should be as fast as possible (it can be called quite often), so it should not create components, but only modify existing ones.

Typically, this is what your getListCellRendererComponent() method looks like:

 @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; } 
+4
source

No, you do not need to call removeAll (). I think your problem is that you create a new JPanel inside the getListCellRendererComponent method every time the method is called:

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

If you made this JPanel field a class, you probably won't have to call removeAll.

edit: jfpoilpret answered better. 1+ him.

+1
source

also use revalidate() on the panel

0
source

Source: https://habr.com/ru/post/1495460/


All Articles