我正在尝试创建一个读取屏幕的线程并将其显示在一个框架中,此代码意味着以5fps运行,到目前为止,它读取屏幕,但我无法使JFrame显示更新的图像每个“框架”或200毫秒。当我使用repaint();或revalidate();
public static void startScreenRecorder()
{
Thread screenThread = new Thread()
{
public synchronized void run()
{
long time;
long lastFrameTime = 0;
JFrame frame = new JFrame("Screen capture");
ImagePanel panel = new ImagePanel(captureScreen());
frame.add(panel);
frame.setSize(300, 400);
frame.setVisible(true);
while (true)
{
time = System.currentTimeMillis();
while (time - lastFrameTime < 190)
{
try {
Thread.sleep(10);
} catch (Exception e) {
}
time = System.currentTimeMillis();
}
lastFrameTime = time;
panel = new ImagePanel(captureScreen());
panel.revalidate();
panel.repaint();
frame.revalidate();
frame.repaint();
}
}
};
screenThread.start();
}
答案 0 :(得分:2)
不要使用Thread.sleep()来尝试控制动画。
动画应该使用Swing Timer来完成。当您使用Timer时,GUI将在EDT上自动更新。
panel = new ImagePanel(captureScreen());
上面的代码没有做任何事情。它只是在内存中创建一个面板。无处你实际将面板添加到GUI。更改变量的引用不会更新GUI。
相反,您可能应该在框架中添加JLabel(最初创建框架时)。然后当你有一个新的图像时,你只需:
label.setIcon( new ImageIcon( your screen capture ) );
答案 1 :(得分:1)
如果您的代码完全没有显示图像,我会不会感到惊讶,因为它忽略了Swing线程规则:
captureScreen()
。Thread.sleep(...)
。 setIcon(...)
交换可视化的JLabel图标?SwingWorker<Void, Icon>
来完成您的工作,然后让它发布ImageIcons,然后将其显示在GUI的JLabel中。如果你这样做,那么你可能不会使用Swing Timer,因为时间将在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();
}
});
}
}
哪个会显示......