2009-11-03 19 views
5

Sto tentando di modificare le righe di JList in modo dinamico. Ho bisogno di cambiare il colore dell'ultima riga, evidenziarlo (n è sconosciuto durante la compilazione). Ho visto molti esempi con ListCellRenderer personalizzato, ma tutti erano "statici".Modifica del colore delle righe JList in fase di esecuzione

In altre parole, ho JList con x righe. Durante il runtime la mia "business logic" rileva l'ennesima riga è importante. Quindi voglio rendere il suo sfondo verde, aspettare un secondo, e poi renderlo di nuovo bianco. Un'altra cosa, non voglio cambiare la selezione delle righe.

Qual è il modo migliore per farlo?

+0

msawicki nota che la versione precedente della mia risposta sarebbe bloccare l'intero filo evento spedizione. il che significa che mentre la riga è evidenziata non puoi fare nient'altro nella GUI. e lo ripeto è solo un rapido campione sporco – jitter

+0

Ok, grazie. Ho aggiornato la mia versione. –

risposta

5

Basato sul campione ListDemo di SUN.

Se si immette del testo nel campo di testo che non è nell'elenco e si ottiene evidenziazione viene aggiunto.

Se il testo si trova nell'elenco e si evidenzia evidenzia la voce nell'elenco viene temporaneamente evidenziata in blu.

Nota la soluzione qui con il campo di confronto è solo per demo. Per ulteriori corretta applicazione considerano le altre idee proposte e considerare l'utilizzo di 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

non sospenderebbe l'EDT per un secondo? – akf

+0

Grazie. Funziona perfettamente. –

+0

hai ragione, ovviamente. sostituito con l'implementazione di Swingworker – jitter

2

Il ListCellRenderer personalizzato, che implementa il metodo getListCellRendererComponent, avrà accesso sia allo JList sia al valore che sta convertendo. Questo ti dà un paio di opzioni per come determinare quando a dipingere la n esima riga verde:

  1. Si potrebbe sottoclasse JList e hanno il renderer chiederlo quale colore da utilizzare per il bg. Il JList sottoclasse potrebbe innescare un ridisegno quando la logica di business determina che è giunto il momento per la n ° fila per essere verde, e quindi avviare uno swing Timer di innescare un ridisegno restituendo il bg torna alla normalità
  2. Quando la logica di business determina quando devi mostrare la riga come verde, hai anche la possibilità di impostare lo stato sull'oggetto di supporto della riga e testarlo per quello stato entro getListCellRendererComponent, impostando il verde di bg se lo stato è corretto. Anche in questo caso, è possibile impostare un'oscillazione Timer per ripristinare lo stato sull'oggetto di supporto.
6

Semplice, impostare un ListCellRenderer personalizzato al JList utilizzando:

list.setCellRenderer(myListCellrenderer); 

Ora all'interno del metodo getListCellRendererComponent override() fare qualcosa di simile:

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

L'esempio presume che il vostro overrid di rendering personalizzato DefaultListCellRenderer

Problemi correlati