Application Structure

From: news.skynet.be (mart_at_nonstoploop.co.uk)
Date: 09/20/04

  • Next message: Raymond DeCampo: "Re: help java"
    Date: Mon, 20 Sep 2004 10:19:44 +0200
    
    

    Hello. I am a beginner at this Java stuff, so bear with me.

    I have been writing an imaging application as a way of learning Java. I

    have got little bits working and tied them together in an application. But

    now I am looking to tune, or correctly model, the application use threads to

    improve performance.

    What I am looking for is if I have structured my application in a logical

    way and if I have where would it be useful to apply threads. Below is the

    code of the application if someone could take a quick look and see if I have

    made any major blunders with my structure and where they would apply

    threads. Thanks for taking the time to read.

    import java.awt.*;
    import java.io.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import java.awt.image.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.*;
    import javax.swing.UIManager;
    import java.util.LinkedList;
    import java.awt.image.BufferedImage;
    import javax.imageio.*;

    //start of new image processor class
    class newImgProc2 extends JComponent{
     private BufferedImage source, destination;
     public JComboBox options;
     public int startX, startY, endX, endY, ix, iy, rectH, rectW;
     public LinkedList lLsUndo = new LinkedList();
     public int undoFlag = 0;
     public JScrollPane iScroll;
     public boolean swap = false;

     public newImgProc2( BufferedImage image ) {//extend buffered image

    to include undo handler

       source = destination = image;
       setBackground(Color.white);
       setLayout(new BorderLayout());
       // create a panel to hold the combo box
       JPanel controls = new JPanel();
       JPanel nuCont = new JPanel();

       //use my button creator class to create a button
       ButtCreator butt1 = new

    ButtCreator("myBright","graphics/bright.gif","graphics/roll.gif","Make

    Brighter");
       ButtCreator butt2 = new

    ButtCreator("myScale","graphics/scale.gif","graphics/roll.gif","Scale

    Down");
       ButtCreator bLoad = new

    ButtCreator("myLoad","graphics/load.gif","graphics/roll.gif","Load a File");
       ButtCreator bSave = new

    ButtCreator("mySave","graphics/save.gif","graphics/roll.gif","Save a File");
       ButtCreator bDark = new

    ButtCreator("myDark","graphics/dark.gif","graphics/roll.gif","Make Darker");
       ButtCreator bRot = new

    ButtCreator("myRotate","graphics/rotate.gif","graphics/roll.gif","Rotate the

    image");
       ButtCreator bUndo = new

    ButtCreator("myUndo","graphics/undo.gif","graphics/roll.gif","Undo");
       ButtCreator bRedo = new

    ButtCreator("myRedo","graphics/redo.gif","graphics/roll.gif","Redo");
        controls.add(butt1);
        controls.add(bDark);
        controls.add(butt2);
        controls.add(bLoad);
        controls.add(bSave);
        controls.add(bRot);
        nuCont.add(bUndo);
        nuCont.add(bRedo);

        add(controls, BorderLayout.NORTH);
        add(nuCont, BorderLayout.SOUTH);

        //------
        //add an event handler
        //add the event listener to the object
        Proc*** pB = new Proc***();
        butt1.addActionListener(pB);
        butt2.addActionListener(pB);
        bLoad.addActionListener(pB);
        bSave.addActionListener(pB);
        bDark.addActionListener(pB);
        bUndo.addActionListener(pB);
        bRedo.addActionListener(pB);
        bRot.addActionListener(pB);

    }

    //undo method
     public void updateUndoAr(BufferedImage img){
      lLsUndo.add(undoFlag,img);
      undoFlag = undoFlag+1;
      if(lLsUndo.size()>undoFlag){
       for (int i=undoFlag;i<=lLsUndo.size();i++){
        lLsUndo.remove(i);
       }
      }
     }

     public void undoUndoAr(){
      try{
       System.out.println("before undo "+undoFlag);
       if(undoFlag-1>=0){
      undoFlag = undoFlag-1;
       }

       BufferedImage last =

    (BufferedImage)lLsUndo.get(undoFlag);
       setTheImage(last);
       System.out.println("after undo "+undoFlag);

      }
      catch( IndexOutOfBoundsException e){
       Toolkit.getDefaultToolkit().beep();
       JPanel warn = new JPanel();
       JOptionPane.showMessageDialog(warn, "ERROR: Undo

    Error!\n\t\tNothing left to undo!\n"+e);
      }
     }

    public void redoUndoAr(){
     try{
      System.out.println("f before redo "+undoFlag);
      undoFlag = undoFlag+1;
      System.out.println("f after redo "+undoFlag);
      BufferedImage last = (BufferedImage)lLsUndo.get(undoFlag);
      setTheImage(last);

     }
     catch( IndexOutOfBoundsException e){
      Toolkit.getDefaultToolkit().beep();
      JPanel warn = new JPanel();
      JOptionPane.showMessageDialog(warn, "ERROR: Redo

    Error!\n\t\tNothing more to redo!\n"+e);
     }
    }

     //class proc*** implements ActionListener, UndoableEditListener{
     class Proc*** implements ActionListener{

      public void actionPerformed(ActionEvent e){

       String b = e.getActionCommand();//teh name of the

    button

       BufferedImageOp op = null;
       if(b.equals("myBright")){
        op = new RescaleOp(1.5f, 0, null);
       }
       else if(b.equals("myUndo")){
        undoUndoAr();
       }
       else if(b.equals("myRedo")){
        redoUndoAr();
       }
       else if(b.equals("myScale")){

        op = new

    AffineTransformOp(AffineTransform.getScaleInstance(.75, .75), null);

       }
       else if(b.equals("myLoad")){
        getImage();
       }
       else if(b.equals("myRotate")){
        op = new

    AffineTransformOp(AffineTransform.getRotateInstance(Math.PI / 6), null);
       }
       else if(b.equals("myDark")){
        op = new RescaleOp(.5f, 0, null);
       }
       else if(b.equals("mySave")){
        try{
           outputFile();
        }
        catch(Exception exp){
           System.out.println(exp);
        }
       }

       if (op != null){
        updateUndoAr(destination);
        destination = op.filter(source, null);
        source = destination;

       }
       repaint();

      }
     }

     //class to deal with painting the thing
     public void paintComponent(Graphics g) {
       int imageWidth = destination.getWidth();
       int imageHeight = destination.getHeight();
       int width = getSize().width;
       int height = getSize().height;

       g.drawImage(destination,0, 0, null);

       //start listeners

       addMouseListener(new MouseAdapter(){

        public void mousePressed(MouseEvent e){

        startX = e.getX();
        startY = e.getY();
        }

        public void mouseReleased(MouseEvent e){
         updateUndoAr(destination);
         BufferedImage my;

         if(swap == true){
        my = source.getSubimage(ix,iy,rectW,rectH);
        swap = false;
         }
         else{
        my =

    source.getSubimage(startX,startY,rectW,rectH);
        swap = false;
         }

         source = my;
         destination = source;
         repaint();
        }
       });

       addMouseMotionListener(new MouseMotionAdapter(){

        public void mouseDragged(MouseEvent e){
         repaint();

          ix = e.getX();
          iy = e.getY();

          if(ix>startX){
         rectW = ix - startX;
          }
          else{
         rectW = startX - ix;
         swap = true;
          }

          if(iy>startY){
         rectH = iy - startY;
          }
          else{
         rectH = startY - iy;
         swap = true;
          }

         Graphics g2 = getGraphics();
         if(swap == true){
         g2.drawRect(ix,iy,rectW,rectH);
         }
         else{

    g2.drawRect(startX,startY,rectW,rectH);
         }
         }
       });
       //end list

      }

    // temp output file bit
     public void outputFile() throws Exception{
       //start of the output stuff
       FileOutputStream fo = new FileOutputStream("graphics/myImg.jpg");
       BufferedOutputStream bo = new BufferedOutputStream(fo);

       ImageIO.write(destination, "jpeg", bo);

       bo.close();
       //finding the size of teh image in memory
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
       ImageIO.write(destination, "jpeg", baos);

       System.out.println("data in mem = "+baos.size());
       baos.close();

     }
    // EOF temp outupt file bit

    // load file from users HD method
      public void getImage(){
     JFileChooser dlg = new JFileChooser();
     //disable the file dialog from showing all
     dlg.setAcceptAllFileFilterUsed(false);
     dlg.addChoosableFileFilter(new DialogFilter());

     int r = dlg.showDialog(this, "Load Image");

     if( r == JFileChooser.CANCEL_OPTION){
      return;
     }
     try{
      File f = dlg.getSelectedFile();
      java.net.URL url = f.toURL();
      ImageIcon icn = new ImageIcon(url);

      System.out.println(icn.getImageLoadStatus());

      //gets the size of the local file
      long sizeLocal = f.length();
      System.out.println("local size of file from dialog

    "+sizeLocal);
      Image fi = icn.getImage();

      // draw the Image into a BufferedImage
      int w = fi.getWidth(null), h = fi.getHeight(null);
      //buffImage is being passed to the image processor class
      BufferedImage fBuff = new BufferedImage(w, h,

    BufferedImage.TYPE_INT_RGB);
      Graphics2D imageGraphics = fBuff.createGraphics();

      setTheImage(fBuff);
      scaleTheImage(fBuff);
      //end paste from main
     }
     catch(Exception e){
      System.out.println("could not load file");
     }

      }
    //end of load file method

    private Rectangle getAffectedArea(int oldX, int oldY, int newx, int newy,

    int width, int height)
    {
     int x = Math.min(oldX, newx);
     int y = Math.min(oldY, newy);
     int w = (Math.max(oldX, newx) + width) - x;
     int h = (Math.max(oldY, newy) + height) - y;
     return new Rectangle(x, y, w, h);
    }

     //if the image is being sent in from an extended class, then reset

    it here
     public void setTheImage(BufferedImage iImg){
      source = iImg;
      destination = source;
      repaint();
     }

     public void scaleTheImage(BufferedImage iImg){
      BufferedImageOp op;

      int w = iImg.getWidth();
      int h = iImg.getHeight();
      op = new

    AffineTransformOp(AffineTransform.getScaleInstance(.5, .5), null);
      destination = op.filter(source, null);
      source = destination;

     }

     //so an external class can get the image
     public BufferedImage retTheImage(){
      return source;
     }

     }
    //end of new image processor class
    //**********************

    class outTheImage2 extends newImgProc2{
      private BufferedImage theImage;

      public outTheImage2(BufferedImage theImage){
     super(theImage);
     scaleTheImage();

      }

      public void scaleTheImage(){
       //get the current image from the parent
     BufferedImage thisImg = super.retTheImage(), destImg;
       int w = thisImg.getWidth();
       int h = thisImg.getHeight();
       BufferedImageOp op;
       //transform the image
       op = new AffineTransformOp(AffineTransform.getScaleInstance(.5,

    .5), null);
       destImg = op.filter(thisImg, null);
       //set the image back to the parent
       super.setTheImage(destImg);

      }
    }

    //creates the frame of the whole application
    class ImageProcCanvas2 extends JFrame{

     public ImageProcCanvas2(outTheImage2 thisImage, int w, int h){

      JFrame.setDefaultLookAndFeelDecorated(true);
      try{

    UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel

    " );
      }
      catch(Exception e){
         System.out.println(e);
      }
      JFrame frame = new JFrame("OGRe Image Processor");

      frame.getContentPane().add(thisImage);
        int myH = h +200;
      frame.setSize(w, myH);
      frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
      frame.setVisible(true);

     }

    }

    //**********************
    public class BufferedImage002 {

      public static void main(String args[]){

     String filename = "graphics/desk001.jpg";
     String outFileName = "outImg.jpg";

     // get the image from hd or could be url

     ImageIcon icon = new ImageIcon(filename);
     Image i = icon.getImage();

     // draw the Image into a BufferedImage
     int w = i.getWidth(null), h = i.getHeight(null);
     //buffImage is being passed to the image processor class
     BufferedImage buffImage = new BufferedImage(w, h,

    BufferedImage.TYPE_INT_RGB);

     //create the image
     Graphics2D imageGraphics = buffImage.createGraphics();
     imageGraphics.drawImage(i, 0, 0, null);
     //get the height of the buffered image
     int width = buffImage.getWidth()+40;
     int height = buffImage.getHeight()+80;
     //scale the buffered image
     outTheImage2 i1 = new outTheImage2(buffImage);
     //set up a new frame to deal with the whole app
     ImageProcCanvas2 newOgre = new ImageProcCanvas2(i1, width, height);

      }
    }
    //**********************

    There are two other objects too. One for creating the buttons and one for

    filtering the dialog to show only images on the users HD. I think this

    maybe too much to take in in one go.. but thanks for taking the time to read

    this far.

    cheers
    Martin

    -- 
    ---------------
    http://www.nonstoploop.co.uk/ - dynamic websites
    http://www.rossanobacchin.be/ - fine art
    http://www.weycameras.co.uk/ - photographic supplies
    ---------------
    

  • Next message: Raymond DeCampo: "Re: help java"