如何更改仅一个JList单元格的JLabel图标(例如:单击JList)? 我尝试使用listCellRender访问JLabel,但它不起作用:
@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"));
}
任何人都可以提出一些想法吗? 提前谢谢!
我的代码:
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();
}
});
}
}
答案 0 :(得分:2)
你正在倒退。如果此参数为true,则单元格渲染器应该只使用isSelected
参数并设置所需的图标,如果该参数为false,则不设置图标。
无需选择监听器。选择更改时,将自动调用渲染器。
答案 1 :(得分:2)
我认为来自public void valueChanged(ListSelectionEvent e) {
ListSelectionListener
方法更简单
请参阅getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
,您可以覆盖isSelected
,因为SelectionModel中的多段落更好cellHasFocus
答案 2 :(得分:1)
渲染后有没有办法更改图标?
您可以根据渲染时的索引或值等条件动态选择图标。使用引用here的示例,以下渲染器生成显示的图像。您随时可以更新图标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;
}
}