代码之家  ›  专栏  ›  技术社区  ›  Alex

如何在JList中突出显示一个项目?[副本]

  •  2
  • Alex  · 技术社区  · 16 年前

    我正在尝试动态更改JList行。我需要改变第n行的颜色,突出显示它(n是未知的编译过程中)。我看到很多自定义ListCellRenderer的例子,但都是“静态的”。

    换句话说,我有JList和x行。在运行时,我的“业务逻辑”检测到第n行很重要。所以我想把背景变成绿色,等一下,然后再变成白色。还有一件事,不要更改行选择。

    最好的方法是什么?

    0 回复  |  直到 16 年前
        1
  •  5
  •   jitter    16 年前

    基于SUN的ListDemo示例。

    如果您在textfield中输入一些不在列表中的文本,并点击highlight,则会添加该文本。

    如果文本在列表中,并且您点击了highlight,则列表中的条目将临时高亮显示为蓝色。

    注意,这里的解决方案和匹配字段仅用于演示。为了更正确地实施,请考虑提出的其他想法并考虑使用 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(); }
            });
        }
    }
    
        2
  •  6
  •   Suraj Chandran    16 年前

    简单地说,使用以下方法将自定义ListCellRenderer设置为JList:

    list.setCellRenderer(myListCellrenderer);
    

    public Component getListCellRendererComponent(.....) {
        Component c = super.getListCellRendererComponent();
        c.setBackGround(Color.blue)
        return c;
    }
    

    上面的示例假设您的自定义呈现器覆盖DefaultListCellRenderer

        3
  •  2
  •   akf    16 年前

    实现方法的自定义ListCellRenderer getListCellRendererComponent ,将可以访问 JList 以及它重新定义的价值。这为您提供了几个选项来确定何时绘制 n

    1. 你可以把 让渲染器询问背景使用哪种颜色。这个 列表框 第一排是绿色,然后开始荡秋千 Timer 触发重绘,使背景恢复正常
    2. 当业务逻辑决定何时应该将行显示为绿色时,您还可以选择在行的backing对象上设置状态,并在中测试该状态 ,如果状态正确,则将bg设置为绿色。同样,您可以选择设置摆动 还原备份对象的状态。