我的屏幕录制应用程序中有一个线程无法配合:
package recorder; import java.awt.AWTException; import java.awt.Insets; import java.io.IOException; import javax.swing.JFrame; public class RepeatThread extends Thread { volatile boolean stop; public volatile Thread recordingThread; JFrame frame; int count = 0; RepeatThread( JFrame myFrame ) { stop = false; frame = myFrame; } public void run() { while( stop == false ) { int loopDelay = 33; // 33 is approx. 1000/30, or 30 fps long loopStartTime = System.currentTimeMillis(); Insets insets = frame.getInsets(); // Get the shape we're recording try { ScreenRecorder.capture( frame.getX() + insets.left, frame.getY() + insets.top, frame.getWidth() - ( insets.left + insets.right ), frame.getHeight() - ( insets.top + insets.bottom ) ); } catch( AWTException e1 ) { // TODO Auto-generated catch block e1.printStackTrace(); } catch( IOException e1 ) { // TODO Auto-generated catch block e1.printStackTrace(); } // Add another picture long loopEndTime = System.currentTimeMillis(); int loopTime = (int )( loopEndTime - loopStartTime ); if( loopTime < loopDelay ) { try { sleep( loopDelay - loopTime ); // If we have extra time, // sleep } catch( Exception e ) { } // If something interrupts it, I don't give a crap; just // ignore it } } } public void endThread() { stop = true; count = 0; ScreenRecorder.reset(); // Once I get this annoying thread to work, I have to make the pictures // into a video here! } }
多年来一直困扰着我。它会定期将屏幕截图带到指定区域。
当您开始录制时,它会隐藏(缩小)窗口。在Mac上,当您以应用程序为焦点时,所有隐藏的窗口都会激活。在我的课程中WListener(我已经确认可以工作),我有:
WListener
public void windowActivated(WindowEvent e){ if(ScreenRecorder.recordingThread!= null){ ScreenRecorder.recordingThread.endThread(); } }
所以应该发生的是,当他单击应用程序时,截屏线程将停止。但是,我必须残酷地搞砸一些东西,因为当线程运行时,它甚至不会让窗口重新出现。这是我的第一个话题,所以我期待这样的怪异问题。你知道怎么了吗
编辑:好的,我使stop变为volatile,这是我创建线程的地方:
package recorder; import java.awt.AWTException; import java.awt.Robot; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.*; import javax.imageio.ImageIO; import javax.swing.JFrame; public class ScreenRecorder { static RepeatThread recordingThread; static int count; public static void record(JFrame frame) { if(recordingThread == null) { //Make a new thread if we don't have one recordingThread = new RepeatThread(frame); recordingThread.start(); } } public static void capture(int x, int y, int width, int height) throws AWTException, IOException { // capture the whole screen //BufferedImage screencapture = new Robot().createScreenCapture( // new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()) ); BufferedImage screencapture = new Robot().createScreenCapture( new Rectangle( x, y, width, height)); // Save as JPEG File directory = new File("/Users/stuart/Movies/temp"); if(directory.exists() == false) { directory.mkdirs(); } count ++; File file = new File("/Users/stuart/Movies/temp/screencapture" + count + ".jpg"); ImageIO.write(screencapture, "jpg", file); // Save as PNG // File file = new File("screencapture.png"); // ImageIO.write(screencapture, "png", file); } public static void stop() { } public static void reset() { count = 0; } }
因为您显然试图每X毫秒执行一个工作单元,所以如果使用Java的Executor,这将容易得多:
ScheduledExecutorService service = executors.newSingleThreadScheduledExecutor(); service.scheduleAtFixedRate(new Runnable() { public void run() { // do one iteration of your work ScreenRecorder.capture(...); ... } }, 0L, 33L, TimeUnit.MILLISECONDS); ... service.shutdown(); // to stop
手动执行操作并Thread没有您做的那么麻烦(不是在挖洞,只是说在Java中并不那么糟糕),但是以上内容仍然是最简单的选择。
Thread