Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JFrame repaint();如何使用线程信息更新JFrame?_Java_Swing - Fatal编程技术网

Java JFrame repaint();如何使用线程信息更新JFrame?

Java JFrame repaint();如何使用线程信息更新JFrame?,java,swing,Java,Swing,我试着在JFrame上设置一个简单的计时器。我可以显示计数器的初始值,但任何后续更改都不会在JFrame上更新。对于我所做的错事,如果有人轻推我的答案,我将不胜感激。我认为这是一个无法调用repaint()的问题,但如果我尝试将其放入,结果可能会出现错误,或者什么都没有 package com.game.ryan; import java.awt.Dimension; import javax.swing.JFrame; class Screen extends JFrame{ privat

我试着在JFrame上设置一个简单的计时器。我可以显示计数器的初始值,但任何后续更改都不会在JFrame上更新。对于我所做的错事,如果有人轻推我的答案,我将不胜感激。我认为这是一个无法调用repaint()的问题,但如果我尝试将其放入,结果可能会出现错误,或者什么都没有

package com.game.ryan;
import java.awt.Dimension;
import javax.swing.JFrame;
class Screen extends JFrame{


private Dimension d = new Dimension(800,600);
private JFrame f;

public Screen(){
    f = new JFrame();
    f.setIgnoreRepaint(false);
    f.setResizable(false);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setMinimumSize(d);
    f.setLocationRelativeTo(null);
    f.add(new MyPanel());
    f.pack();
    f.setVisible(true);
}

public static void main(String[] args){
    Screen s = new Screen();
}

}
我还有:

package com.game.ryan;

import java.awt.Graphics;

import javax.swing.JPanel;

public class MyPanel extends JPanel{

private OneThread ot = new OneThread();
private int counter = ot.getThreadCounter();

public MyPanel(){
    Thread t1 = new Thread(new OneThread());
    t1.start();

}

public void paintComponent(Graphics g){
    g.drawString("TIME: ", 10, 20);
    g.drawString(Integer.toString(counter), 50, 20);        
}
}
最后

package com.game.ryan;

public class OneThread implements Runnable{

private int counter = 45;

public OneThread(){

}

@Override
public void run() {

    for(int x = 0; x >= 0; x++){
        try{
            Thread.sleep(1000);
            counter++;
            x++;
            System.out.println(counter);

        }catch(Exception e){
            e.printStackTrace();
        }
    }       
}

public int getThreadCounter(){
    return counter;
}
}
我在控制台上得到一个递增的计数器,所以我猜该部件工作正常


预期结果是计数器在JFrame中正确显示(每1000毫秒更新一次)。

您可能希望重新考虑您的设计:

  • 一个基本变量保存一个值,就这样。如果将原语保留的值指定给另一个变量,以后更改原始变量将不会影响另一个变量保留的值。例如,代码中的任何内容都不会更改JPanel所持有的计数器变量所持有的值
  • 请注意,即使您的计划成功,您也有两个完全独立的单线程对象,更改其中一个对象的状态对另一个对象没有影响
  • 最好让GUI侦听变量的更改,然后让线程更改变量的状态,然后通知所有侦听器此更改。PropertyChangeListener可以很好地实现这一点
  • 请注意,Swing计时器比后台线程更容易实现

您可能希望重新思考您的设计:

  • 一个基本变量保存一个值,就这样。如果将原语保留的值指定给另一个变量,以后更改原始变量将不会影响另一个变量保留的值。例如,代码中的任何内容都不会更改JPanel所持有的计数器变量所持有的值
  • 请注意,即使您的计划成功,您也有两个完全独立的单线程对象,更改其中一个对象的状态对另一个对象没有影响
  • 最好让GUI侦听变量的更改,然后让线程更改变量的状态,然后通知所有侦听器此更改。PropertyChangeListener可以很好地实现这一点
  • 请注意,Swing计时器比后台线程更容易实现

    • 我看不到你告诉用户界面它应该自我更新的地方

      在复制API中已经可用的内容方面,您也要走很长的路

      摆动和螺纹需要仔细考虑。Swing使用单线程模型来管理UI的所有更新。预期UI的所有迭代都将在线程(也称为事件调度线程)的上下文中完成

      这意味着,无论何时,您想要从任何其他线程创建或更新UI,都需要将调用同步回EDT

      虽然有很多方法可以实现这一点,但最简单的方法是使用
      javax.swing.Timer

      import java.awt.BorderLayout;
      import java.awt.EventQueue;
      import java.awt.GridBagLayout;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.text.DateFormat;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.Timer;
      import javax.swing.UIManager;
      import javax.swing.UnsupportedLookAndFeelException;
      
      public class LabelClock {
      
          public static void main(String[] args) {
              new LabelClock();
          }
      
          protected static final DateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm.ss");
          private JLabel clock;
      
          public LabelClock() {
              EventQueue.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      try {
                          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                      } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                      }
      
                      clock = new JLabel();
                      tick();
      
                      JFrame frame = new JFrame("Testing");
                      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                      frame.setLayout(new GridBagLayout());
                      frame.add(clock);
                      frame.pack();
                      frame.setLocationRelativeTo(null);
                      frame.setVisible(true);
      
                      Timer timer = new Timer(500, new ActionListener() {
                          @Override
                          public void actionPerformed(ActionEvent e) {
                              tick();
                          }
                      });
                      timer.setRepeats(true);
                      timer.setCoalesce(true);
                      timer.start();
                  }
              });
          }
      
          protected void tick() {
              clock.setText(DATE_FORMAT.format(new Date()));
          }
      
      }
      

      我没有看到你告诉UI它应该自我更新的地方

      在复制API中已经可用的内容方面,您也要走很长的路

      摆动和螺纹需要仔细考虑。Swing使用单线程模型来管理UI的所有更新。预期UI的所有迭代都将在线程(也称为事件调度线程)的上下文中完成

      这意味着,无论何时,您想要从任何其他线程创建或更新UI,都需要将调用同步回EDT

      虽然有很多方法可以实现这一点,但最简单的方法是使用
      javax.swing.Timer

      import java.awt.BorderLayout;
      import java.awt.EventQueue;
      import java.awt.GridBagLayout;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.text.DateFormat;
      import java.text.SimpleDateFormat;
      import java.util.Date;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.Timer;
      import javax.swing.UIManager;
      import javax.swing.UnsupportedLookAndFeelException;
      
      public class LabelClock {
      
          public static void main(String[] args) {
              new LabelClock();
          }
      
          protected static final DateFormat DATE_FORMAT = new SimpleDateFormat("HH:mm.ss");
          private JLabel clock;
      
          public LabelClock() {
              EventQueue.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      try {
                          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                      } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                      }
      
                      clock = new JLabel();
                      tick();
      
                      JFrame frame = new JFrame("Testing");
                      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                      frame.setLayout(new GridBagLayout());
                      frame.add(clock);
                      frame.pack();
                      frame.setLocationRelativeTo(null);
                      frame.setVisible(true);
      
                      Timer timer = new Timer(500, new ActionListener() {
                          @Override
                          public void actionPerformed(ActionEvent e) {
                              tick();
                          }
                      });
                      timer.setRepeats(true);
                      timer.setCoalesce(true);
                      timer.start();
                  }
              });
          }
      
          protected void tick() {
              clock.setText(DATE_FORMAT.format(new Date()));
          }
      
      }
      

      swingutilities.invokeLater
      委托给
      EventQueue.invokeLater
      ,所以这方面没什么…非常感谢大家。我一次又一次地看视频,感到很沮丧,于是决定尝试做点什么。我想你应该从某个地方开始。
      swingutilities.invokeLater
      委托给
      EventQueue.invokeLater
      ,所以这方面没什么……非常感谢大家。我一次又一次地看视频,感到很沮丧,于是决定尝试做点什么。我想你得从某个地方开始。