如果您的代码根本没有显示任何图像,我不会感到惊讶,因为它忽略了 Swing 线程规则:
- 所有 Swing 代码只需要在 Swing 事件调度线程 (EDT) 上调用。
- 所有其他长时间运行的代码都需要在后台线程中调用。我认为这意味着
captureScreen()
.
Thread.sleep(...)
除非您想让整个应用程序进入睡眠状态,否则您永远不应该调用Swing 事件线程。
- 也许最好使用摆动计时器。
- 您创建了新的 ImagePanel,但对它们什么也不做——例如,除了第一个 JPanel 之外,您从不将它们添加到 GUI 中。请注意,如果您更改变量引用的对象,此处为面板变量,这将绝对不会影响在其他地方使用的对象实例,即在 GUI 中显示的 JPanel。
- 与其创建新的 JPanel,不如用您的图像创建 ImageIcons 并将可视化的 JLabel 的图标替换为
setIcon(...)
?
- 由于您有很多背景资料,请考虑使用 a
SwingWorker<Void, Icon>
来完成您的工作,并让它发布 ImageIcon,然后将其显示在 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();
}
});
}
}
哪个会显示...