/* * A simple proto of an image sorting tool, SJ 051107 * * Takes image filenames from command line * for each image, SPACE does nothing (but show next image), * letters a-c (currently, TODO) copy the image a directory a, b, c * q quits * * Demonstrates image loading and drawing, SwingWorker threads, KeyListener */ /* TODO * directory names from somewhere * * close files, dispose imagereaders * no cycle through images * make copy more portable (now used mv) * show file name more clearly * better scaling to display (in background thread) * revert to previous image (and optinally undo previous copy) * scaling/re-encoding saved images (in background) * mouse action * options from menus/checkbuttons * FileSelector to open a new directory * progress bar * ... */ import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import javax.imageio.ImageIO; import javax.swing.*; import java.util.Set; import java.util.HashSet; public class ImageSelect extends JFrame implements KeyListener { static String[] files; static int next = -1; Set oDirectories; // TODO: get from somewhere static char [] dirs = {'a', 'b', 'c'}; Container cPane; ImageReader currIR, nextIR; ImagePanel IP; public ImageSelect() { oDirectories = new HashSet(); for (int i = 0; i < dirs.length; i++) oDirectories.add(dirs[i]); draw(); } private void draw() { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // image displaying panel IP = new ImagePanel(); IP.setPreferredSize(new Dimension(400, 300)); this.add(IP); this.addKeyListener(this); this.pack(); this.setVisible(true); // start loading first image nextIR = getNextIR(); if (nextIR == null) { // no images this.dispose(); return; } // display first image next(); } /* * display next image */ private void next() { currIR = nextIR; // previously loaded image nextIR = getNextIR(); // start loading a new image showImage(currIR); // show image } /* * start new image reader for next filename */ private ImageReader getNextIR() { if (files.length == 0) return null; next = (next + 1) % files.length; ImageReader IR = new ImageReader(files[next], this.getWidth(), this.getHeight()); IR.execute(); return IR; } /* * show image of an ImageReader */ private void showImage(ImageReader IR) { IP.setImage(IR); IP.repaint(); } // Key listener public void keyTyped(KeyEvent e) { if (e.getKeyChar() == ' ') next(); else if (e.getKeyChar() == 'q') this.dispose(); else if (oDirectories.contains(e.getKeyChar())) { currIR.copyToDir("" + e.getKeyChar()); next(); } } public void keyPressed(KeyEvent e) { } public void keyReleased(KeyEvent e) { } public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. files = args; javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { ImageSelect cgui = new ImageSelect(); } }); } // main() /* * Image viewing panel */ public class ImagePanel extends JPanel { BufferedImage bi; /* * get image from ImageReader */ public void setImage(ImageReader IR) { try { bi = IR.get(); } catch (Exception e) { System.err.println("ImagePanel.setImage: " +e); } } /* * show image scaled to this panel */ public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; // g2.drawImage(bi, 0, 0, this.getWidth(), this.getHeight(), null); g2.drawImage(bi, 0, 0, null); } } // class ImagePanel /* * background thread to load and decode an image from file */ public class ImageReader extends SwingWorker { String fn = null; int w, h; public ImageReader(String fileName, int width, int heigth) { fn = fileName; w = width; h = heigth; } /* * loads an image */ @Override public BufferedImage doInBackground() { BufferedImage bi, bi2; try { // read image bi = ImageIO.read(new File(fn)); // scale image // Image im = bi.getScaledInstance(w, h, Image.SCALE_FAST); Image im = bi.getScaledInstance(w, h, Image.SCALE_SMOOTH); bi2 = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Graphics2D bi2g = bi2.createGraphics(); bi2g.drawImage(im, 0, 0, null); bi2g.drawString(fn, 10, 10); // add file name return bi2; } catch (Exception e) { return null; } } public void copyToDir(String dirName) { // TODO: not portable try { Runtime.getRuntime().exec("cp " + fn + " " + dirName); } catch (Exception e) {} } } // class ImageReader } // class ImageSelect