简体   繁体   English

JList如何重绘?

[英]How does JList repaint?

Please try to run the following example and explain to me why repaint fails to work from time to time especially if you click on a row. 请尝试运行以下示例,并向我解释为什么重新绘制有时不起作用的原因,特别是如果您单击一行时。 It looks like JList forgets about the rows preferred size. 看起来JList忘记了行的首选大小。 I mean that when running this code at fixed intevals, some random interval the JList goes blank. 我的意思是,以固定的间隔运行此代码时,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();

 }
}

Not sure exactly what the repaint problem is that you are trying to describe. 不确定您要描述的重涂问题是什么。

However, taking a quick look at the code the obvious problem is that you should be using a Swing Timer to do the updates. 但是,快速浏览一下代码,明显的问题是您应该使用Swing计时器进行更新。 All changes to Swing components should be done on the Event Dispatch Thread. 对Swing组件的所有更改都应在事件分发线程上完成。 Since changes to the model will notify the Swing component to update itself the model updateds should be done on the EDT. 由于对模型的更改将通知Swing组件自行更新,因此应在EDT上进行模型更新。

Read the section from the Swing tutorial on Concurrency for more information. 阅读Swing 并发教程中的有关更多信息的部分。

Instead of using java.util.Timer you should use javax.swing.Timer which is designed to work with Swing components, that is most probably your problem. 与其使用java.util.Timer使用旨在与Swing组件一起使用的javax.swing.Timer ,这很可能是您遇到的问题。

Swing components may only be modified on the Event Dispatch Thread and the symptoms you describe ("from time to time") is typical when another thread than EDT updates the GUI, it may seem to work fine but then suddenly something "strange" happens. 只能事件分发线程上修改Swing组件,并且您描述的症状(“时不时”)是典型的,而EDT以外的另一个线程更新GUI时,它似乎可以正常工作,但随后突然出现“奇怪”的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM