2010-11-21 2 views
0

다음 예제를 실행하고 특히 행을 클릭하면 다시 그리기가 실패하는 이유를 설명하십시오. JList는 행 기본 크기를 잊어 버린 것처럼 보입니다. 고정 된 intevals에서이 코드를 실행할 때 JList가 비어있는 임의의 간격이 있음을 의미합니다.JList는 어떻게 다시 그립니다?

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(); 

} 
} 

답변

4

묘사하려는 재 페인트 문제가 무엇인지 정확하게 모릅니다.

그러나 코드를 빠르게 살펴보면 업데이트를 수행 할 때 스윙 타이머를 사용해야한다는 것이 분명합니다. Swing 구성 요소에 대한 모든 변경 사항은 Event Dispatch Thread에서 수행해야합니다. 모델을 변경하면 Swing 구성 요소에 업데이트를 알리므로 모델 업데이트는 EDT에서 수행해야합니다.

자세한 내용은 Concurrency의 스윙 튜토리얼 섹션을 참조하십시오.

+0

감사합니다. 이 문제를 해결하고 java.util.Timer가 Swing과 결합하기에 부적절하다는 것을 배웠습니다. – Hans

+0

ActionListener actionListener = new ActionListener() { public void actionPerformed (ActionEvent actionEvent) { System.out.println ("Hello World Timer") ; \t \t \t \t model.clear(); \t \t \t \t tid ++; \t \t \t \t ListItem li = 새 ListItem (Color.cyan, "test line one"+ tid); \t \t \t \t model.addElement (li); \t \t \t \t li = 새로운 ListItem (Color.yellow, "foo foo foo foo foo"); \t \t \t \t model.addElement (li); \t \t \t \t li = 새로운 ListItem (Color.green, "quick brown fox"); \t \t \t \t model.addElement (li); } }; \t \t \t \t javax.swing.Timer t2 = new javax.swing.Timer (1000, actionListener); \t \t t2.start(); – Hans

2

java.util.Timer 대신에 가장 좋은 방법 일 수있는을 사용해야합니다.이 구성 요소는 Swing 구성 요소와 함께 작동하도록 설계되었습니다. EDT 아닌 다른 쓰레드가 GUI를 업데이트 할 때, 그것은 잘 작동하는 것처럼 보일 수 있습니다

스윙 구성 요소 만 이벤트 발송 쓰레드수정할 수 수 있으며, 당신이 ("수시로") 설명 증상이 일반적이지만, 갑자기 뭔가 이상한 일이 일어난다.

+0

JTable은 java.util.Timer 및 javax.swing.Timer와 함께 작동합니다. JList는 javax.swing에서만 작동합니다. Timer – Hans

+1

java.util.Timer에서 제대로 작동하는 것처럼 보일 수 있지만 Swing 단일 스레드 정책을 위반하고 있으므로 확신 할 수 없습니다. – Uhlen