/* * SnapShot.java * * Created on den 29 december 2004, 23:24 */ package krut.KRUT_GUI; /** * * @author jonte */ import java.awt.*; import javax.swing.*; import java.awt.image.BufferedImage; /** This class is used to show a snapshot. Originally * the snapshot was only used to show a single * screenshot; however it was later expanded * to include the preview window. The new methods * (the preview related ones) use the old methods * for initialization. This update was done more * like a hack than as a restructuring, and the * readability of the code suffered. This should * be worked on. * The original code for showing just a * screenshot is found in the snapshot-related * methods in RunKRUT and ScreenGrabber, and the * new calls for updating the preview window are * made from the run method in the ScreenGrabber * class. */ public class SnapShot extends Thread { /** The JFrame used to * show the animation of the film as it records.*/ public JFrame previewFrame; /** The class that paints the preview images. */ ShowPic preview; /** This is the amount of milliseconds to sleep between each update * of the window. The window will only update if updatePreviewImage * has been called since the last update. */ public int sleepMillis = 1000; /** A flag used to keep track of if the update Thread is running or not. */ private boolean isRunning = false; /** True if nextImage has been updated, and the window should be * repainted, false if not. */ private boolean imageUpdated = false; /** The image that will be displayed at the next update of the * window. */ private BufferedImage nextImage; /** As long as the isRunning parameter is true, * the present method sleeps an amount of time * determined by the sleepMillis parameter. After * sleeping, the updateImage method is called if * the imageUpdated parameter is true. Then the * present method sleeps again. */ public void run() { while (isRunning) try { sleep(sleepMillis); if (imageUpdated) updateImage(); } catch (InterruptedException ie) { System.out.println(ie); } } /** Load a picture from file into an Image * * @param fileName The name of the file containing the picture * @param comp A component (like the frame where the image * should be drawn) to use for the MediaTracker. * * @return The Image. */ public Image loadPic(String fileName, java.awt.Component comp) throws OutOfMemoryError { Image loadImage = Toolkit.getDefaultToolkit().createImage(fileName); MediaTracker mediaTracker = new MediaTracker(comp); mediaTracker.addImage(loadImage, 0); try { mediaTracker.waitForID(0); } catch (InterruptedException ie) { System.err.println(ie); } return loadImage; } /** Initializes and shows the preview window, * displaying a new BufferedImage. * * @param width The width of the preview window. * @param height The height of the preview window. */ public void initPreviewWindow(int width, int height) { if (previewFrame == null) previewFrame = new JFrame("Preview (lower quality FPS)"); nextImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); try { preview = new ShowPic(nextImage); JComponent newContentPane = preview; newContentPane.setOpaque(true); previewFrame.setContentPane(newContentPane); previewFrame.pack(); previewFrame.setVisible(true); } catch (OutOfMemoryError o) { System.out.println(o); } if (!isRunning) { isRunning = true; start(); } setPriority(MIN_PRIORITY); } /** Changes the update frequency of the preview window. * * @param fps The update frequency given as updates per second. */ public void setFps(int fps) { sleepMillis = 1000 / fps; } /** Closes the preview window and free system resources. */ public void stopPreviewWindow() { // isRunning = false; previewFrame.dispose(); /** Is this necessary? Can't remember. */ previewFrame = null; preview = null; } /** Update the image in the preview window. The actual updating of * the image seen in the window is done by the run method. * * @param nextImage The BufferedImage that should be shown in * the preview window at the next update. */ public synchronized void updatePreviewImage(BufferedImage nextImage) { this.nextImage = nextImage; imageUpdated = true; } /** Updates the image seen in the preview window to the one * waiting in nextImage. */ private synchronized void updateImage() { if (preview != null) preview.setImage(nextImage); imageUpdated = false; } /** This class shows the image. */ public class ShowPic extends JPanel { private JPanel drawingPane; private BufferedImage image; private Graphics graph; private int imSizeX, imSizeY; private ShowPic(BufferedImage imageToShow) throws OutOfMemoryError { super(new BorderLayout()); imSizeX = imageToShow.getWidth(); imSizeY = imageToShow.getHeight(); // image = new BufferedImage(imSizeX, imSizeY, imageToShow.getType()); // graph = image.getGraphics(); // graph.drawImage(imageToShow, 0, 0, this); image = imageToShow; drawingPane = new DrawingPane(); drawingPane.setBackground(Color.white); JScrollPane scroller = new JScrollPane(drawingPane); /** The size of the scroller is set to the size of the image * + the size of all the relevant (?) insets in order to make * the scroller not show as the window displays. If it does not * work, it is problably not a disaster. It is just cosmetic. */ Insets scInsets = scroller.getInsets(), myInsets = this.getInsets(); /** ^^^ */ scroller.setPreferredSize(new Dimension( imSizeX + scInsets.left + scInsets.right + myInsets.left + myInsets.right, imSizeY + scInsets.top + scInsets.bottom + myInsets.top + myInsets.bottom)); add(scroller, BorderLayout.CENTER); drawingPane.setPreferredSize(new Dimension(imSizeX, imSizeY)); drawingPane.revalidate(); } /** Change the image that shows in this window. * * @param imageToShow A BufferedImage representing the * new image to show. */ public void setImage(BufferedImage imageToShow) { image = imageToShow; repaint(); } public class DrawingPane extends JPanel { protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(image, 0, 0, this); } } } /** Show a new image in a new SnapShot window. * * @param frame The frame to show the image in. * @param image The image. */ public void createAndShowGUI(JFrame frame, BufferedImage image) throws OutOfMemoryError { frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); JComponent newContentPane = new ShowPic(image); newContentPane.setOpaque(true); frame.setContentPane(newContentPane); frame.pack(); frame.setVisible(true); } }