application Structure

N

news.skynet.be

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
ProcButt pB = new ProcButt();
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 procButt implements ActionListener, UndoableEditListener{
class ProcButt 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
 
A

Andrew Thompson

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

The best group for Java beginners is described here..
I have been writing an imaging application as a way of learning Java.

You are in way over your head on this one,
I suggest you cut it back to a much smaller
project and post code for that.

In a cursory glance of your code, I observed
what appeared to be glaring errors, or at the
very least, poorly written code, but I generally
compile code before I seriously examine it..
I have got little bits working and tied them together in an application.

Holy crap! A 557 line code post and you call it 'little'?
..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.

Why read when you can compile!
import java.awt.*;
....
(copy/paste over 500 lines to my editor)
//**********************

There are two other objects too.

What! You're kidding right?! You have posted
over 500 lines of code for people to 'just peruse',
looking for your mistakes, and it is not even
compileable?

In future, please keep code examples under
200 lines and make them self-contained, ready
for others to compile. Check here for tips
on trimming code for public presentation..
<http://www.physci.org/codes/sscce.jsp>

--
Andrew Thompson
http://www.PhySci.org/codes/ Web & IT Help
http://www.PhySci.org/ Open-source software suite
http://www.1point1C.org/ Science & Technology
http://www.lensescapes.com/ Images that escape the mundane
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,737
Latest member
Georgeengab

Latest Threads

Top