2010-11-21 20 views
0

Bitte versuchen Sie, das folgende Beispiel auszuführen und erklären Sie mir, warum Repaint von Zeit zu Zeit nicht funktioniert, besonders wenn Sie auf eine Zeile klicken. Es sieht so aus, als ob JList die bevorzugte Größe der Zeilen vergisst. Ich meine, dass, wenn dieser Code in festen Intervallen ausgeführt wird, ein zufälliges Intervall die JList leer bleibt.Wie wird JList neu streichen?

import javax.swing.JList; 
import javax.swing.ListCellRenderer; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JFrame; 
import javax.swing.BorderFactory; 
import javax.swing.DefaultListModel; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.util.Timer; 
import java.util.TimerTask; 
class ListItem 
{ 
private Color color; 
private String value; 
public ListItem(Color c, String s) 
{ 
    color = c; 
    value = s; 
} 
public Color getColor() 
{ 
    return color; 
} 
public String getValue() 
{ 
    return value; 
} 
} 

class MyCellRenderer extends 
JLabel implements ListCellRenderer 
{ 
public MyCellRenderer() 
{ 
    setOpaque(true); 
} 
public Component getListCellRendererComponent(JList list, 
    Object value, // value to display 
     int index, // cell index 
     boolean iss, // is selected 
     boolean chf) // cell has focus? 
{ 
    System.out.println(" i cell-rendering "+CustomList.tid + " " 
    + CustomList.model.getSize() + " " + index+" "+CustomList.statusList.getValueIsAdjusting() + " "); 
    setText(((ListItem)value).getValue()); 
    setBackground(((ListItem)value).getColor()); 
    if (iss) 
    { 
    setBorder(BorderFactory.createLineBorder(Color.blue, 1)); 
    } 
    else 
    { 
    setBorder(BorderFactory.createLineBorder(list.getBackground(), 1)); 
    } 
    return this; 
} 
} 

public class CustomList 
{ 
public static DefaultListModel model; 
public static JList statusList; 
public static int tid = 0; 

public static void tidUr() 
{ 
    int delay = 1000; 
    int period = 1000; 
    Timer timer = new Timer(); 
    timer.scheduleAtFixedRate(new TimerTask() 
    { 
    public void run() 
    { 
    // model = new DefaultListModel(); 
    // statusList.setModel(model); 
    // statusList.setCellRenderer(new MyCellRenderer()); 
    model.clear(); 
    tid++; 
    ListItem li = new ListItem(Color.cyan, "test line one "+tid); 
    model.addElement(li); 
    li = new ListItem(Color.yellow, "foo foo foo foo foo"); 
    model.addElement(li); 
    li = new ListItem(Color.green, "quick brown fox"); 
    model.addElement(li); 
    } 
    }, delay, period); 
} 

public static void main(String args[]) 
{ 
    JFrame frame = new JFrame("Custom List Demo"); 
    frame.addWindowListener(new WindowAdapter() 
    { 
    public void windowClosing(WindowEvent e) 
    { 
    System.exit(0); 
    } 
    } 
    ); 

    model = new DefaultListModel(); 
    statusList = new JList(model); 
    statusList.setCellRenderer(new MyCellRenderer()); 

    ListItem li = new ListItem(Color.cyan, "test line one"); 
    model.addElement(li); 
    li = new ListItem(Color.yellow, "foo foo foo foo foo"); 
    model.addElement(li); 
    li = new ListItem(Color.green, "quick brown fox"); 
    model.addElement(li); 

    JPanel panel = new JPanel(); 
    panel.add(statusList); 
    frame.getContentPane().add("Center", panel); 
    frame.setLocation(300, 400); 
    frame.setSize(200, 200); 
    //frame.pack(); 
    frame.setVisible(true); 

    // tidUr(); 
    ActionListener actionListener = new ActionListener() { 
     public void actionPerformed(ActionEvent actionEvent) { 
      System.out.println("Hello World Timer"); 
      model.clear(); 
      tid++; 
      ListItem li = new ListItem(Color.cyan, "test line one "+tid); 
      model.addElement(li); 
      li = new ListItem(Color.yellow, "foo foo foo foo foo"); 
      model.addElement(li); 
      li = new ListItem(Color.green, "quick brown fox"); 
      model.addElement(li); 
     } 
     }; 

    javax.swing.Timer t2 = new javax.swing.Timer(1000, actionListener); 
    t2.start(); 

} 
} 

Antwort

4

Nicht sicher genau das, was das Neuzeichnen Problem ist, dass Sie zu beschreiben versuchen.

Ein kurzer Blick auf den Code ist jedoch das offensichtliche Problem, dass Sie einen Swing-Timer verwenden sollten, um die Updates durchzuführen. Alle Änderungen an Swing-Komponenten sollten im Event-Dispatch-Thread vorgenommen werden. Da Änderungen am Modell die Swing-Komponente benachrichtigen, um sich selbst zu aktualisieren, sollten die Modellaktualisierungen auf dem EDT durchgeführt werden.

Lesen Sie den Abschnitt aus dem Swing-Tutorial auf Concurrency für weitere Informationen.

+0

Danke euch allen !!! Das hat das Problem gelöst und ich habe gelernt, dass java.util.Timer für das Kombinieren mit Swing unzutreffend ist. – Hans

+0

ActionListener actionListener = neuer ActionListener() { public void actionPerformed (ActionEvent actionEvent) { System.out.println ("Hello World Timer") ; \t \t \t \t modell.clear(); \t \t \t \t tid ++; \t \t \t \t ListItem li = neues ListItem (Color.cyan, "test line one" + tid); \t \t \t \t Modell.AddElement (li); \t \t \t \t li = neues ListItem (Farbe: gelb, "foo foo foo foo foo"); \t \t \t \t Modell.AddElement (li); \t \t \t \t li = neues ListItem (Color.green, "quick brown fox"); \t \t \t \t Modell.AddElement (li); } }; \t \t \t \t javax.swing.Timer t2 = neuer javax.swing.Timer (1000, actionListener); \t \t t2.start(); – Hans

2

Anstatt java.util.Timer zu verwenden, sollten Sie javax.swing.Timer verwenden, das entwickelt wurde, um mit Swing-Komponenten zu arbeiten, was wahrscheinlich Ihr Problem ist.

Swing-Komponenten dürfen nur auf dem Thema Event Dispatch modifiziert werden und die Symptome, die Sie („von Zeit zu Zeit“) beschreiben, sind typisch, wenn ein anderer Thread als EDT der GUI aktualisiert, kann es scheinen gut zu funktionieren, aber dann passiert plötzlich etwas "Seltsames".

+0

JTable funktioniert sowohl mit java.util.Timer als auch mit javax.swing.Timer. JList funktioniert NUR mit javax.swing: Timer – Hans

+1

Es scheint, dass es mit java.util.Timer funktioniert, aber Sie verletzen Swing single thread policy und daher können Sie nie sicher sein. – Uhlen

Verwandte Themen