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();
}
});
}
}
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.
I think that there is easier method as
public void valueChanged(ListSelectionEvent e) {
fromListSelectionListener
see
getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
there you can to overrideisSelected
, for multisleection in SelectionModel is bettercellHasFocus
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()
.