Java 我很难每隔200分钟更新一次图像

Java 我很难每隔200分钟更新一次图像,java,image,jframe,jpanel,screen-capture,Java,Image,Jframe,Jpanel,Screen Capture,我正在尝试创建一个线程来读取屏幕并在一个帧中显示它,该代码旨在以5fps的速度运行,到目前为止它读取屏幕,但是我在使JFrame每“帧”或200毫秒显示更新图像时遇到了问题。当我使用repaint()时;或重新验证() publicstaticvoid startScreenRecorder() { 线程屏幕线程=新线程() { 公共同步的无效运行() { 长时间; 长lastFrameTime=0; JFrame=新的JFrame(“屏幕截图”); ImagePanel=新的ImagePane

我正在尝试创建一个线程来读取屏幕并在一个帧中显示它,该代码旨在以5fps的速度运行,到目前为止它读取屏幕,但是我在使JFrame每“帧”或200毫秒显示更新图像时遇到了问题。当我使用repaint()时;或重新验证()

publicstaticvoid startScreenRecorder()
{
线程屏幕线程=新线程()
{
公共同步的无效运行()
{
长时间;
长lastFrameTime=0;
JFrame=新的JFrame(“屏幕截图”);
ImagePanel=新的ImagePanel(captureScreen());
框架。添加(面板);
框架。设置尺寸(300400);
frame.setVisible(true);
while(true)
{
时间=System.currentTimeMillis();
while(时间-lastFrameTime<190)
{
试一试{
睡眠(10);
}捕获(例外e){
}
时间=System.currentTimeMillis();
}                
lastFrameTime=时间;
panel=新图像面板(captureScreen());
panel.revalidate();
panel.repaint();
frame.revalidate();
frame.repaint();
}
}
};
screenThread.start();
}

如果您的代码完全没有显示图像,我不会感到惊讶,因为它忽略了Swing线程规则:

  • 所有Swing代码只需要在Swing事件调度线程(EDT)上调用
  • 所有其他长时间运行的代码都需要在后台线程中调用。我假设这意味着
    captureScreen()
  • 除非您想让整个应用程序进入睡眠状态,否则永远不要在Swing事件线程上调用
    Thread.sleep(…)
  • 最好使用一个摆动计时器
  • 您可以创建新的ImagePanel,但不使用它们——例如,您永远不会将它们添加到GUI中,除了第一个JPanel。请注意,如果您更改变量所引用的对象(此处为panel变量),这将对其他地方使用的对象实例(此处为GUI中显示的JPanel)完全没有影响
  • 与其创建新的JPanel,不如用图像创建ImageIcons,并将可视化的JLabel图标与
    setIcon(…)
    交换
  • <> LI>因为你有很多背景资料,请考虑使用<代码> SaveWorks来完成你的工作,并让它发布在GUI的J标签中显示的图像图标。如果您这样做了,那么您可能不会使用Swing计时器,因为计时将在SwingWorker的后台线程中完成
例如:

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

@SuppressWarnings("serial")
public class SwingWorkerEg extends JPanel {
   private static final int PREF_W = 600;
   private static final int PREF_H = 400;
   private JLabel displayedLabel = new JLabel();

   public SwingWorkerEg() {
      setLayout(new BorderLayout());
      add(displayedLabel);
      try {
         MySwingWorker mySwingWorker = new MySwingWorker();
         mySwingWorker.execute();
      } catch (AWTException e) {
         e.printStackTrace();
      }
   }

   public void setLabelIcon(Icon icon) {
      displayedLabel.setIcon(icon);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private class MySwingWorker extends SwingWorker<Void, Icon> {
      private final Rectangle SCREEN_RECT = new Rectangle(0, 0, PREF_W,
            PREF_H);
      private Robot robot = null;

      public MySwingWorker() throws AWTException {
         robot = new Robot();
      }

      @Override
      protected Void doInBackground() throws Exception {
         Timer utilTimer = new Timer();
         TimerTask task = new TimerTask() {

            @Override
            public void run() {
               BufferedImage capturedImage = captureScreen();
               publish(new ImageIcon(capturedImage));
            }

         };
         long delay = 200;
         utilTimer.scheduleAtFixedRate(task, delay, delay);
         return null;
      }

      @Override
      protected void process(List<Icon> chunks) {
         for (Icon icon : chunks) {
            setLabelIcon(icon);
         }
      }

      private BufferedImage captureScreen() {
         BufferedImage img = robot.createScreenCapture(SCREEN_RECT);
         return img;
      }

   }

   private static void createAndShowGui() {
      SwingWorkerEg mainPanel = new SwingWorkerEg();

      JFrame frame = new JFrame("SwingWorker Eg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
import java.awt.AWTException;
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.Rectangle;
导入java.awt.Robot;
导入java.awt.image.buffereImage;
导入java.util.List;
导入java.util.Timer;
导入java.util.TimerTask;
导入javax.swing.Icon;
导入javax.swing.ImageIcon;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
导入javax.swing.SwingWorker;
@抑制警告(“串行”)
公共类SwingWorkerReg扩展了JPanel{
专用静态最终整型预调W=600;
私有静态最终整型参数H=400;
私有JLabel displayedlab=新JLabel();
公共SwingWorkerReg(){
setLayout(新的BorderLayout());
添加(显示标签);
试一试{
MySwingWorker MySwingWorker=新的MySwingWorker();
mySwingWorker.execute();
}捕获(awtexe){
e、 printStackTrace();
}
}
公共无效设置标签图标(图标){
displayedLabel.setIcon(图标);
}
@凌驾
公共维度getPreferredSize(){
返回新维度(PREF_W,PREF_H);
}
私有类MyWingWorker扩展SwingWorker{
私有最终矩形屏幕=新矩形(0,0,预,
PREF_H);
私人机器人=空;
public MySwingWorker()抛出AWTException{
机器人=新机器人();
}
@凌驾
受保护的Void doInBackground()引发异常{
定时器utilTimer=新定时器();
TimerTask任务=新的TimerTask(){
@凌驾
公开募捐{
BuffereImage capturedImage=captureScreen();
发布(新图像图标(capturedImage));
}
};
长延时=200;
utilTimer.scheduleAtFixedRate(任务、延迟、延迟);
返回null;
}
@凌驾
受保护的无效进程(列表块){
用于(图标:块){
setLabelIcon(图标);
}
}
专用缓冲区图像捕获屏幕(){
BuffereImage img=robot.createScreenCapture(屏幕截图);
返回img;
}
}
私有静态void createAndShowGui(){
SwingWorkerEg主面板=新建SwingWorkerEg();
JFrame=新JFrame(“SwingWorker Eg”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(主面板);
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
createAndShowGui();
}
});
}
}
这将显示

不要使用Thread.sleep()来尝试控制动画

动画应该通过使用动画来完成。使用计时器时,图形用户界面会在EDT上自动更新

panel = new ImagePanel(captureScreen());
上面的代码没有任何作用。它只是在内存中创建一个面板。实际上,没有任何地方可以将面板添加到GUI中。更改变量的引用不会更新GUI

相反,您可能应该在框架中添加一个JLabel
panel = new ImagePanel(captureScreen());
label.setIcon( new ImageIcon( your screen capture ) );