Swing のスレッド化ルールを無視するため、コードに画像がまったく表示されなくても驚かないでしょう。
- すべての Swing コードは、Swing イベント ディスパッチ スレッド (EDT) でのみ呼び出す必要があります。
- 他のすべての実行時間の長いコードは、バックグラウンド スレッドで呼び出す必要があります。という意味だと思います
captureScreen()
。
Thread.sleep(...)
アプリケーション全体をスリープ状態にする場合を除き、Swing イベント スレッドを呼び出さないでください。
- おそらくスイングタイマーを使用する方が良いでしょう。
- 新しい ImagePanel を作成しますが、何もしません。たとえば、最初の JPanel を除いて、それらを GUI に追加することはありません。変数が参照するオブジェクト (ここではパネル変数) を変更しても、別の場所で使用されているオブジェクトのインスタンス (GUI に表示される JPanel) にはまったく影響しないことに注意してください。
- 新しい JPanel を作成するのではなく、イメージで ImageIcons を作成し、視覚化された JLabel のアイコンを と交換してみ
setIcon(...)
ませんか?
- 多くのバックグラウンド処理が行われている
SwingWorker<Void, Icon>
ため、作業を行うために を使用することを検討し、GUI の JLabel に表示される ImageIcon を公開するようにします。これを行った場合、タイミングは SwingWorker のバックグラウンド スレッドで行われるため、おそらく Swing タイマーを使用しないでしょう。
例えば:
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();
}
});
}
}
どちらが表示されますか...