2009-11-03 146 views
5

我正在嘗試動態更改JList行。我需要改變第n行顏色,突出顯示它(n在編譯期間是未知的)。我看到很多自定義ListCellRenderer的例子,但都是「靜態的」。在運行時更改JList行顏色

換句話說,我必須用JList的x行。在運行期間,我的「業務邏輯」檢測第n行很重要。所以我想讓它的背景變成綠色,等一秒鐘,然後再把它變成白色。還有一件事,不要改變行選擇。

什麼是這樣做的最佳方法是什麼?

+0

msawicki注意,我的回答以前的版本會阻止整個事件調度線程。這意味着當行被突出顯示時,你不能在GUI中做任何事情。我再說一次只是一個快速骯髒的示例 – jitter 2009-11-03 04:57:48

+0

好的,謝謝。我更新了我的版本。 – 2009-11-03 16:31:26

回答

5

自定義渲染基於從SUN ListDemo樣品。

如果你進入這是不是在列表中的文本框的一些文本和你打突出顯示被添加。

如果文本是在列表中,你打突出顯示列表中的條目被暫時藍色高亮顯示。

注意這裏的解決方案與匹配字段是僅用於演示。欲瞭解更多正確實施考慮提出其他的想法,並考慮使用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(); } 
     }); 
    } 
} 
+0

難道不會暫停美國東部時間一秒鐘? – akf 2009-11-03 04:36:48

+0

謝謝。它完美的作品。 – 2009-11-03 04:48:37

+0

你當然是對的。取而代之的是擺動工具的實施 – jitter 2009-11-03 04:55:03

2

實現方法getListCellRendererComponent的自定義ListCellRenderer將有權訪問JList以及它正在重寫的值。這給你如何確定何時繪製ñ個行綠色幾個選項:

  1. 你可以繼承JList並有渲染要求它使用的BG的顏色。當商業邏輯決定了它是時間ñ個行是綠色的JList子類可能引發重繪,然後啓動一個鞦韆Timer觸發重繪返回BG恢復正常
  2. 當商業邏輯確定何時應該將行顯示爲綠色,還可以選擇在行的後備對象上設置狀態,並在getListCellRendererComponent內測試該狀態,如果狀態正確,則將bg設置爲綠色。再次,您可以選擇設置Swing Timer以恢復支持對象上的狀態。

    list.setCellRenderer(myListCellrenderer); 
    

    現在覆蓋的方法getListCellRendererComponent()內做這樣的事情:

6

簡單,使用設置自定義ListCellRenderer您的JList

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

上面的例子假設你overrid DefaultListCellRenderer

相關問題