2009-11-03 8 views
5

JList行を動的に変更しようとしています。私は行の色を変更する必要があります(nはコンパイル時に不明です)。私はカスタムListCellRendererで多くの例を見ましたが、すべて静的でした。実行時にJList行の色を変更する

つまり、私はx行のJListを持っています。実行時に、 "ビジネスロジック"がn番目の行を検出することが重要です。だから私はその背景を緑色にし、1秒待ってから白くしたい。もう一つ、行の選択を変更しないでください。

どうすればよいですか?

+0

msawickiノートを使用することを検討してください。これは、行が強調表示されている間に、GUI内で何も実行できないことを意味します。そして私は再びそれがただ素早く汚れたサンプルであると言う。 – jitter

+0

ありがとう、ありがとう。バージョンを更新しました。 –

答えて

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

これはEDTを一時停止しませんか? – akf

+0

ありがとうございます。それは完全に動作します。 –

+0

あなたはもちろん正しいです。スイングワーカーの実装に置き換えられました – jitter

2

メソッドgetListCellRendererComponentを実装しているカスタムListCellRendererは、JListとそれがリロードしている値の両方にアクセスできます。これは、あなたの緑N番目の行をペイントする時期を決定する方法についてはカップルのオプションがあります。

  1. あなたはJListのサブクラスを作成し、レンダラーがBGに使用する色、それを頼むかもしれません。ビジネス・ロジックは、それがN行目は緑色であり、その後、場合ビジネスロジック
  2. バック正常
  3. にBGを戻す再描画をトリガするスイング Timerを開始するための時間であると判断した場合 JListサブクラスは、再描画をトリガすることができ行を緑色で表示するかどうかを決定するときは、行のバッキングオブジェクトに状態を設定し、その状態が getListCellRendererComponentの範囲内であるかどうかをテストし、状態が正しい場合はbgを緑に設定するオプションもあります。ここでもSwing Timerを設定してバッキングオブジェクトの状態を元に戻すことができます。
シンプル
6

は、使用してのJListにカスタムListCellRendererを設定します。

list.setCellRenderer(myListCellrenderer); 

オーバーライドされたメソッドgetListCellRendererComponent(内側)は、このような何か:

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

上記の例では、あなたのことを想定しカスタムレンダラーオーバーライドDefaultListCellRenderer