0

How can I change a JLabel icon of only one JList cell(for example: clicking in JList)? I tried to access the JLabel getting with listCellRender but it don't works:

    @Override
    public void valueChanged(ListSelectionEvent e) {
        if (!e.getValueIsAdjusting()) {
             ListCellRenderer r = list.getCellRenderer();
             JLabel comp = (JLabel) r.getListCellRendererComponent(list, list.getSelectedValue(), list.getSelectedIndex(), false, false);
             comp.setIcon(UIManager.getIcon("Tree.leafIcon"));
    }

Can anyone give some idea? Thanks in advance!

My code:

import java.awt.*;
import java.util.Arrays;
import javax.swing.*;
import javax.swing.event.*;

/**
 * @see http://stackoverflow.com/questions/7620579
 * @see http://stackoverflow.com/questions/4176343
 */
public class ListPanel extends JPanel {

    private static final long serialVersionUID = -5558761237888601952L;
    private static final int N = 5;
    private DefaultListModel dlm = new DefaultListModel();
    private JList list = new JList(dlm);
    private ListRenderer myRender;
    // http://stackoverflow.com/questions/13752188/chat-client-emoticons-window-java
    // http://docs.oracle.com/javase/tutorial/uiswing/components/icon.html VER

    public ListPanel() {
        super(new GridLayout());

        for (int i = 0; i < N * N; i++) {
            String name = "Cell: " + i;//String.format("%02d", i);
            dlm.addElement(name);
        }
        //dlm.getElementAt(0)
        list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
        //list.getCellRenderer().getListCellRendererComponent(list, value, index, isSelected, cellHasFocus)
        list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
        list.setVisibleRowCount(N);
        myRender = new ListRenderer();
        list.setCellRenderer(myRender);
        list.addListSelectionListener(new SelectionHandler());
        JScrollPane pane = new JScrollPane(list);
        this.add(pane, BorderLayout.CENTER);
    }

    private class ListRenderer extends DefaultListCellRenderer {


        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            JLabel label =  (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            //System.out.println(">> " + index);
            label.setBorder(BorderFactory.createEmptyBorder(N, N, N, N));
            label.setIcon(UIManager.getIcon("html.pendingImage"));
            label.setHorizontalTextPosition(JLabel.CENTER);
            label.setVerticalTextPosition(JLabel.BOTTOM);
            return label;
        }
    }

    private class SelectionHandler implements ListSelectionListener {

        @Override
        public void valueChanged(ListSelectionEvent e) {
            if (!e.getValueIsAdjusting()) {
                System.out.println(list.getSelectedValue());
            }
        }
    }

    private void display() {
        JFrame f = new JFrame("ListPanel");
        //f.setPreferredSize(new Dimension(400, 400));
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ListPanel().display();
            }
        });
    }
}
SpecTrum
  • 67
  • 1
  • 6

3 Answers3

2

You're doing it backwards. The cell renderer should simply use the isSelected argument and set the icon you want if this argument is true, and no icon if it's false.

No need for a selection listener. The renderer will automatically be invoked when the selection changes.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Hi! I used a selection listener just for example. I want change the current icon to another. Can you help me? – SpecTrum Sep 28 '13 at 07:04
  • As I said. it's the job of the renderer to set the icon. In the renderer check what the value to render is (or its index, or its selected flag, or whatever), and depending on this value, set the appropriate icon. See http://docs.oracle.com/javase/tutorial/uiswing/components/list.html#renderer – JB Nizet Sep 28 '13 at 07:07
  • I wanted to make this job outside of renderers. I use the selection listener just for example. Is this possible? Thanks! – SpecTrum Sep 28 '13 at 07:17
  • No. It's the job of the renderer to render the cell. – JB Nizet Sep 28 '13 at 07:22
2
  • I think that there is easier method as public void valueChanged(ListSelectionEvent e) { from ListSelectionListener

  • see getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { there you can to override isSelected, for multisleection in SelectionModel is better cellHasFocus

mKorbel
  • 109,525
  • 20
  • 134
  • 319
1

Is there any way to change the icons after rendered?

You can dynamically choose the icon based on criteria such as index or value at the time of rendering. Using the example cited here, the following renderer produces the image shown. You can always update an icon and repaint().

list panel icons

private class ListRenderer extends DefaultListCellRenderer {

    Icon icon1 = UIManager.getIcon("html.pendingImage");
    Icon icon2 = UIManager.getIcon("html.missingImage");

    public ListRenderer() {
        this.setBorder(BorderFactory.createLineBorder(Color.red));
    }

    @Override
    public Component getListCellRendererComponent(JList list, Object
            value, int index, boolean isSelected, boolean cellHasFocus) {
        JLabel label = (JLabel) super.getListCellRendererComponent(
            list, value, index, isSelected, cellHasFocus);
        label.setBorder(BorderFactory.createEmptyBorder(N, N, N, N));
        label.setIcon(icon1);
        if (index % 2 == 0) {
            label.setIcon(icon2);
        }
        label.setHorizontalTextPosition(JLabel.CENTER);
        label.setVerticalTextPosition(JLabel.BOTTOM);
        return label;
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045