How to change a cell icon of JList in run time

亡梦爱人 提交于 2019-12-02 15:37:33

问题


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();
            }
        });
    }
}

回答1:


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.




回答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




回答3:


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().

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


来源:https://stackoverflow.com/questions/19064185/how-to-change-a-cell-icon-of-jlist-in-run-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!