2009-11-03 83 views
5

Tôi đang cố gắng thay đổi các hàng JList theo cách động. Tôi cần thay đổi màu hàng thứ n, đánh dấu nó (n không rõ trong quá trình biên dịch). Tôi đã thấy rất nhiều ví dụ với ListCellRenderer tùy chỉnh, nhưng tất cả đều là "tĩnh".Thay đổi màu hàng JList khi chạy

Nói cách khác tôi có JList với x hàng. Trong thời gian chạy "logic kinh doanh" của tôi phát hiện hàng thứ n là quan trọng. Vì vậy, tôi muốn làm cho nền của nó màu xanh lá cây, chờ một giây, và sau đó làm cho nó trở lại màu trắng. Một điều nữa, đừng thay đổi lựa chọn hàng.

Cách tốt nhất để làm như vậy là gì?

+0

msawicki lưu ý rằng phiên bản trước của câu trả lời của tôi sẽ chặn toàn bộ chủ đề sự kiện văn. có nghĩa là trong khi hàng được đánh dấu bạn không thể làm bất cứ điều gì khác trong gui. và tôi nói lại lần nữa chỉ là một mẫu bẩn nhanh – jitter

+0

Ok, Cảm ơn. Tôi đã cập nhật phiên bản của mình. –

Trả lời

5

Dựa trên mẫu ListDemo từ SUN.

Nếu bạn nhập một số văn bản trong trường văn bản không có trong danh sách và bạn nhấn đánh dấu nó sẽ được thêm vào.

Nếu văn bản nằm trong danh sách và bạn nhấn đánh dấu mục nhập trong danh sách sẽ được tạm thời đánh dấu màu xanh lam.

Lưu ý giải pháp ở đây với trường đối sánh chỉ để trình diễn. Để biết thêm chi thực hiện đúng xem xét các ý tưởng khác được đề xuất và xem xét sử dụng 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

điều này sẽ không làm tạm dừng EDT trong một giây? – akf

+0

Cảm ơn bạn. Nó hoạt động hoàn hảo. –

+0

bạn đúng tất nhiên. thay thế bằng việc thực hiện swingworker – jitter

2

Trình chỉnh sửa danh sách tùy chỉnh của bạn, thực hiện phương thức getListCellRendererComponent, sẽ có quyền truy cập vào cả hai JList và giá trị mà nó đang tính lại. Điều này sẽ cho bạn một vài tùy chọn cho việc làm thế nào để xác định khi nào để sơn n hàng thứ màu xanh lá cây:

  1. Bạn có thể phân lớp JList và có renderer hỏi nó mà màu sắc để sử dụng cho các bg. Các JList lớp con có thể kích hoạt một repaint khi logic kinh doanh xác định rằng đó là thời gian cho n hàng ngày để có màu xanh, và sau đó bắt đầu một Swing Timer để kích hoạt một repaint trả lại bg trở lại bình thường
  2. Khi logic kinh doanh xác định khi nào bạn nên hiển thị hàng là màu xanh lá cây, bạn cũng có tùy chọn đặt trạng thái trên đối tượng sao lưu của hàng và kiểm tra trạng thái đó trong trạng thái getListCellRendererComponent, đặt màu xanh lá cây bg nếu trạng thái là chính xác. Một lần nữa, bạn có tùy chọn thiết lập Swing Timer để hoàn nguyên trạng thái trên đối tượng sao lưu.
6

đơn giản, thiết lập một ListCellRenderer tùy chỉnh để JList bạn sử dụng:

list.setCellRenderer(myListCellrenderer); 

Bây giờ bên trong phương pháp getListCellRendererComponent ghi đè() làm một cái gì đó như thế này:

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

Ví dụ trên giả định rằng bạn trình kết xuất đồ họa tùy chỉnh mặc định DefaultListCellRenderer

Các vấn đề liên quan