java 在运行时更改 JList 行颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1664924/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Changing JList row color at runtime
提问by Maciek Sawicki
I am trying to change JList rows dynamically. I need change nth row colour, highlight it(n is unknown during compilation). I saw a lot of examples with custom ListCellRenderer, but all were "static".
我正在尝试动态更改 JList 行。我需要更改第 n 行颜色,突出显示它(编译期间 n 未知)。我看到了很多自定义 ListCellRenderer 的例子,但都是“静态的”。
In other words I have JList with x rows. During runtime my "business logic" detects nth row is important. So I want make its background green, wait one second, and then make it white again. One more thing, don't wan change row selection.
换句话说,我有 x 行的 JList。在运行时,我的“业务逻辑”检测到第 n 行很重要。所以我想让它的背景变成绿色,等一秒钟,然后再把它变成白色。还有一件事,不要改变行选择。
What is the best way to do so?
这样做的最佳方法是什么?
回答by Suraj Chandran
Simple, set a custom ListCellRenderer to your JList using:
简单,使用以下方法将自定义 ListCellRenderer 设置为您的 JList:
list.setCellRenderer(myListCellrenderer);
Now inside the overridden method getListCellRendererComponent() do something like this:
现在在重写的方法 getListCellRendererComponent() 中执行如下操作:
public Component getListCellRendererComponent(.....) {
Component c = super.getListCellRendererComponent();
c.setBackGround(Color.blue)
return c;
}
The above example assumed that your custom renderer overrid DefaultListCellRenderer
上面的例子假设你的自定义渲染器覆盖了 DefaultListCellRenderer
回答by jitter
Based on ListDemo sample from SUN.
基于来自 SUN 的 ListDemo 示例。
If you enter some text in the textfield which isn't in the list and you hit highlight it gets added.
如果您在文本字段中输入一些不在列表中的文本并且您点击突出显示它会被添加。
If the text is in the list and you hit highlight the entry in the list gets temporarily highlighted blue.
如果文本在列表中并且您点击突出显示列表中的条目会暂时突出显示为蓝色。
Note the solution here with the match field is just for demo. For more correct implementation consider the other ideas proposed and consider using javax.swing.Timer
请注意此处带有匹配字段的解决方案仅用于演示。为了更正确地实施,请考虑提出的其他想法并考虑使用javax.swing.Timer
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class ListDemo extends JPanel {
private JList list;
private DefaultListModel listModel;
public String match = null;
private static final String hireString = "Highlight";
private JTextField employeeName;
public ListDemo() {
super(new BorderLayout());
listModel = new DefaultListModel();
listModel.addElement("Test1");
listModel.addElement("Test2");
listModel.addElement("Test3");
list = new JList(listModel);
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
list.setSelectedIndex(0);
list.setVisibleRowCount(5);
list.setCellRenderer(new MyListCellRenderer());
JScrollPane listScrollPane = new JScrollPane(list);
JButton hireButton = new JButton(hireString);
HireListener hireListener = new HireListener(hireButton);
hireButton.setActionCommand(hireString);
hireButton.addActionListener(hireListener);
hireButton.setEnabled(false);
employeeName = new JTextField(10);
employeeName.addActionListener(hireListener);
employeeName.getDocument().addDocumentListener(hireListener);
listModel.getElementAt(list.getSelectedIndex()).toString();
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new BoxLayout(buttonPane,
BoxLayout.LINE_AXIS));
buttonPane.add(Box.createHorizontalStrut(5));
buttonPane.add(employeeName);
buttonPane.add(hireButton);
buttonPane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
add(listScrollPane, BorderLayout.CENTER);
add(buttonPane, BorderLayout.PAGE_END);
}
class MyListCellRenderer extends JLabel implements ListCellRenderer {
public MyListCellRenderer() {
setOpaque(true);
}
public Component getListCellRendererComponent(JList paramlist, Object value, int index, boolean isSelected, boolean cellHasFocus) {
setText(value.toString());
if (value.toString().equals(match)) {
setBackground(Color.BLUE);
SwingWorker worker = new SwingWorker() {
@Override
public Object doInBackground() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) { /*Who cares*/ }
return null;
}
@Override
public void done() {
match = null;
list.repaint();
}
};
worker.execute();
} else
setBackground(Color.RED);
return this;
}
}
class HireListener implements ActionListener, DocumentListener {
private boolean alreadyEnabled = false;
private JButton button;
public HireListener(JButton button) {
this.button = button;
}
public void actionPerformed(ActionEvent e) {
String name = employeeName.getText();
if (listModel.contains(name)) {
match = name;
list.repaint();
employeeName.requestFocusInWindow();
employeeName.selectAll();
return;
}
if (name.equals("")) {
Toolkit.getDefaultToolkit().beep();
employeeName.requestFocusInWindow();
employeeName.selectAll();
return;
}
int index = list.getSelectedIndex();
if (index == -1)
index = 0;
else
index++;
listModel.insertElementAt(employeeName.getText(), index);
employeeName.requestFocusInWindow();
employeeName.setText("");
list.setSelectedIndex(index);
list.ensureIndexIsVisible(index);
}
public void insertUpdate(DocumentEvent e) {
enableButton();
}
public void removeUpdate(DocumentEvent e) {
handleEmptyTextField(e);
}
public void changedUpdate(DocumentEvent e) {
if (!handleEmptyTextField(e))
enableButton();
}
private void enableButton() {
if (!alreadyEnabled)
button.setEnabled(true);
}
private boolean handleEmptyTextField(DocumentEvent e) {
if (e.getDocument().getLength() <= 0) {
button.setEnabled(false);
alreadyEnabled = false;
return true;
}
return false;
}
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("ListDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new ListDemo();
newContentPane.setOpaque(true);
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() { createAndShowGUI(); }
});
}
}
回答by akf
Your custom ListCellRenderer, which implements the method getListCellRendererComponent, will have access to both the JListand the value that it is redering. This gives you a couple options for how to determine when to paint the nth row green:
实现方法的自定义 ListCellRenderergetListCellRendererComponent将可以访问JList它正在重绘的和 值。这为您提供了如何确定何时将第n行涂成绿色的几个选项:
- You could subclass
JListand have the renderer ask it which color to use for the bg. TheJListsubclass could trigger a repaint when the business logic determines that it is time for the nth row to be green, and then start an SwingTimerto trigger a repaint returning the bg back to normal - When the business logic determines when you should show the row as green, you also have the option of setting state on the backing object of the row, and test it for that state within
getListCellRendererComponent, setting the bg green if the state is correct. Again, you have the option of setting an SwingTimerto revert the state on the backing object.
- 您可以创建子类
JList并让渲染器询问它为 bg 使用哪种颜色。该JList子类可能引发重绘当商业逻辑决定了它是时间Ñ个行是绿色的,然后启动一个秋千Timer触发重绘返回BG恢复正常 - 当业务逻辑确定何时应将行显示为绿色时,您还可以选择在行的支持对象上设置状态,并在 中测试该状态
getListCellRendererComponent,如果状态正确,则将 bg 设置为绿色。同样,您可以选择设置 SwingTimer以恢复支持对象的状态。

