Best Projects

Bug Trackingsystem,Books online shopping,college management system,HR management system,Internet banking,Online chat room ,Online exam,Telephone billing system,Banking application,ATM database,airways reservation system,virtual network computing ,calculator,SMTP(simple mail transfer protocol)

Poor Man's PaintShop


mini draw is a Java MDI vector graphics creation program that allows the loading of saving of images in XML and exports pictures to PGN format. As a drawing program, it's one of the most typical inheritance projects to do for a programming course.




// DDocument.java

import java.awt.*;
import javax.swing.*;
import java.util.*;

import java.awt.event.*;

import java.io.*;

import javax.swing.table.*;



// Standard imports for XML
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import org.w3c.dom.*;

import com.sun.jimi.core.Jimi;
import com.sun.jimi.core.JimiException;
import com.sun.jimi.core.component.JimiCanvasLW;
import com.sun.jimi.core.util.GraphicsUtils;
import com.sun.jimi.core.util.ColorReducer;



// This is where the XmlDocument subclass lives
// -- see saveXML()
import org.apache.crimson.tree.*;

class DDocument extends JPanel implements DocPanel {

private DShape selected;
private JPanel canvas;
private boolean dirty;

private JButton JC_AddRect;
private JButton JC_AddOval;
private JButton JC_AddLine;
private JButton JC_SetColor;
private JButton JC_MoveToBack;
private JButton JC_MoveToFront;
private JButton JC_DeleteShape;

private JTable JC_Table;
private DrawTableModel tableModel;

private JButton JC_AddText;
private JCheckBox JC_BoldCheckBox;
private JCheckBox JC_ItalicCheckBox;
private JTextField JC_Text;

private JButton JC_Export;

// Messages for the doc model
public boolean getDirty() { return(dirty); }
public void setDirty(boolean dirty) {
this.dirty = dirty;
}

// These branch to the real code for the serial/XML cases
public void load(File file) {
if (isXML(file)) loadXML(file);
else loadSerial(file);
}
public void save(File file) {
if (isXML(file)) saveXML(file);
else saveSerial(file);
}

/*
Decides if a file is XML or serialized format.
Cheezy -- just uses the name.
*/
private boolean isXML(File file) {
return(file.getName().toLowerCase().endsWith(".xml"));
}

public void saveSerial(File file) {
try {
ObjectOutputStream out =
new ObjectOutputStream(new FileOutputStream(file));

// YOUR CODE HERE
Component[] components = canvas.getComponents();

out.writeObject(new Integer(components.length));
for(int i = 0; i < components.length; i++) {
out.writeObject(((DShape)components[i]).getModel());
}




}
catch (Exception e) {
e.printStackTrace();
}
}


private void loadSerial(File file) {
try {
ObjectInputStream in =
new ObjectInputStream(new FileInputStream(file));

// YOUR CODE HERE
// (add the models in reverse order)
Integer count = (Integer)in.readObject();
int i = count.intValue();
int j = 0;

while (j < i) {
DShapeModel temp = (DShapeModel)in.readObject();
//list[j] = temp;
addShape(temp);
j++;
}


}

catch (Exception e) {
System.err.println(e);
}
}


/*
XML constants
*/
public final static String DRAW = "draw";
public final static String SHAPE = "shape";
public final static String TYPE = "type";
public final static String X1 = "x1";
public final static String Y1 = "y1";
public final static String X2 = "x2";
public final static String Y2 = "y2";
public final static String COLOR = "color";
public final static String TEXT = "text";
public final static String BOLD = "bold";
public final static String ITALIC = "italic";

/*
Creates the XML node for a single shape.
*/
public Element createNode(Document doc, DShapeModel model) {
Element node = (Element) doc.createElement(SHAPE);
// YOUR CODE HERE

node.setAttribute(TYPE,new Character(model.getType()).toString());
node.setAttribute(X1, new Integer(model.getX1()).toString());
node.setAttribute(Y1, new Integer(model.getY1()).toString());
node.setAttribute(X2, new Integer(model.getX2()).toString());
node.setAttribute(Y2, new Integer(model.getY2()).toString());
node.setAttribute(COLOR, new Integer(model.getColor().getRGB()).toString());
if(model.getType() == 't') {
node.setAttribute(TEXT, ((DTextModel)model).getText());
if(((DTextModel)model).getBold()) {
node.setAttribute(BOLD, "1");
}
if(((DTextModel)model).getItalic()) {
node.setAttribute(ITALIC, "1");
}
}

return(node);
}


/*
Creates the whole XML doc object in memory representing the current
dots state.
Creates the root node and appends all the shape children to it.
*/
public Document createXMLDoc() {
// The following is the standard incantation to get a Document object
// (i.e. I copied this from the API docs)
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();

dbf.setValidating(false);

DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
}

Document doc = db.newDocument();

// YOUR CODE HERE
Element root = doc.createElement(DRAW);
doc.appendChild(root);


Component[] components = canvas.getComponents();

for(int i = 0; i < components.length; i++) {
Element leaf = createNode(doc, ((DShape)components[i]).getModel());
root.appendChild(leaf);
}

return(doc);
}


/*
Create an XML document for out state, and ask it to write itself out.
*/
public void saveXML(File file) {
try {
Writer out = new OutputStreamWriter (new FileOutputStream(file));
Document doc = createXMLDoc();

// trick: cast Down to XmlDocument
((XmlDocument)doc).write(out, "UTF-8"); // XMLDoc knows how to write itself

out.close();
setDirty(false);
}
catch (Exception e) {
System.err.println("Save XML err:" + e);
}
}



/*
Inverse of saveXML.
Loads the XML tree into memory, iterates over the
to build the right structure in the DDocument.
*/
private void loadXML(File file) {

try {
// The following is the standard incantation to get a Document object
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();

dbf.setValidating(false);

DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
}

// Parse the XML to build the whole doc tree
Document doc = db.parse(file);

// Get the root
Element root = doc.getDocumentElement();

// Get all the SHAPE children
NodeList nodes = root.getElementsByTagName(SHAPE);

// YOUR CODE HERE
for(int i = 0; i < nodes.getLength(); i++) {
Element leaf = (Element) nodes.item(i);
char type = leaf.getAttribute(TYPE).charAt(0);
int x1 = Integer.parseInt(leaf.getAttribute(X1));
int x2 = Integer.parseInt(leaf.getAttribute(X2));
int y1 = Integer.parseInt(leaf.getAttribute(Y1));
int y2 = Integer.parseInt(leaf.getAttribute(Y2));
Color c = new Color(Integer.parseInt(leaf.getAttribute(COLOR)));

String str;
boolean bold = false;
boolean italic = false;

if(type == 't') {
str = leaf.getAttribute(TEXT);
bold = (leaf.getAttribute(BOLD).length() != 0);
italic = (leaf.getAttribute(ITALIC).length() != 0);

addShape(new DTextModel(type,x1,y1,x2,y2,c,bold,italic,str));
} else {
addShape(new DShapeModel(type,x1,y1,x2,y2,c));
}
}



}
catch (SAXException e) {
System.err.println("XML parse err:" + e.getMessage());
}
catch (IOException e) {
System.err.println("IO err:" + e.getMessage());
}
}

public DDocument(int width, int height, File file) {
super();

setLayout(new BorderLayout(6,6));

// Make drawing canvas
canvas = new JPanel();
canvas.setLayout(null);
canvas.setPreferredSize(new Dimension(width, height));
canvas.setBackground(Color.white);
add(canvas, BorderLayout.CENTER);


// Make control area
Box west = Box.createVerticalBox();
add(west, BorderLayout.WEST);
Box south = Box.createHorizontalBox();
add(south, BorderLayout.SOUTH);



// YOUR CODE HERE
JC_AddRect = new JButton("Add Rect");
JC_AddOval = new JButton("Add Oval");
JC_AddLine = new JButton("Add Line");
JC_SetColor = new JButton("Set Color");
JC_MoveToBack = new JButton("Move To Back");
JC_MoveToFront = new JButton("Move To Front");
JC_DeleteShape = new JButton("Delete Shape");

JC_AddRect.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
addShape(new DShapeModel('r'));
}
});

JC_AddOval.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
addShape(new DShapeModel('o'));
}
});

JC_AddLine.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
addShape(new DShapeModel('l'));
}
});

JC_SetColor.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(DDocument.this.selected == null) return;
Color color = JColorChooser.showDialog(DDocument.this, "Pick shape color", DDocument.this.selected.getModel().getColor());
DDocument.this.selected.getModel().setColor(color);
}
});

JC_MoveToBack.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(DDocument.this.selected == null) return;
DDocument.this.canvas.remove(DDocument.this.selected);
DDocument.this.canvas.add(DDocument.this.selected, -1);
DDocument.this.selected.repaint();
DDocument.this.tableModel.rearrange();
}
});

JC_MoveToFront.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(DDocument.this.selected == null) return;
DDocument.this.canvas.remove(DDocument.this.selected);
DDocument.this.canvas.add(DDocument.this.selected, 0);//DDocument.this.canvas.getComponentCount());
DDocument.this.selected.repaint();
DDocument.this.tableModel.rearrange();
}
});

JC_DeleteShape.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(DDocument.this.selected == null) return;

DDocument.this.canvas.remove(DDocument.this.selected);
DDocument.this.tableModel.remove(DDocument.this.selected.getModel());
DDocument.this.canvas.repaint(DDocument.this.selected.getBounds());
DDocument.this.selected = null;



// DDocument.this.canvas.add(DDocument.this.selected);
// DDocument.this.selected.repaint();
}
});


JC_AddText = new JButton("Add Text");
JC_AddText.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
addShape(new DTextModel('t'));
}
});

JC_BoldCheckBox = new JCheckBox("Bold");
JC_ItalicCheckBox = new JCheckBox("Italic");
JC_Text = new JTextField("Hello");
setSelected(null);

JC_BoldCheckBox.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(selected != null && selected.getModel().getType() == 't') {
((DTextModel)selected.getModel()).setBold(JC_BoldCheckBox.isSelected());
}
}
});
JC_ItalicCheckBox.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(selected != null && selected.getModel().getType() == 't') {
((DTextModel)selected.getModel()).setItalic(JC_ItalicCheckBox.isSelected());
}
}
});
JC_Text.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(selected != null && selected.getModel().getType() == 't') {
((DTextModel)selected.getModel()).setText(JC_Text.getText());

}
}
});

JC_Export = new JButton("Export Image");


JC_Export.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
ExportImage();
}
});

south.add(Box.createHorizontalStrut(175));
south.add(JC_Export);


west.add(JC_AddRect);
west.add(JC_AddOval);
west.add(JC_AddLine);
west.add(JC_AddText);
west.add(JC_BoldCheckBox);
west.add(JC_ItalicCheckBox);
west.add(JC_Text);
west.add(JC_SetColor);
west.add(JC_MoveToBack);
west.add(JC_MoveToFront);
west.add(JC_DeleteShape);


west.add(Box.createVerticalStrut(10));
tableModel = new DrawTableModel();
JC_Table = new JTable(tableModel);
JScrollPane scroller = new JScrollPane(JC_Table);
scroller.setPreferredSize(new Dimension(100,100));
west.add(scroller);


canvas.addMouseListener( new MouseAdapter() {
public void mousePressed(MouseEvent e) {
setSelected(null);
}
});


if (file!=null) load(file);


}

public void ExportImage() {
JFileChooser chooser = new JFileChooser(".");
chooser.setFileSelectionMode(chooser.FILES_ONLY);
int status = chooser.showSaveDialog(this);
if(status == JFileChooser.APPROVE_OPTION) {
try {
Image image = canvas.createImage(canvas.getWidth(),canvas.getHeight());
Graphics g = image.getGraphics();
canvas.paintAll(g);

com.sun.jimi.core.Jimi.putImage(image, chooser.getSelectedFile().getAbsolutePath());

}
catch (Exception ex) {
ex.printStackTrace();
}
}

}

public DShape getSelected() {
return(selected);
}

public void setSelected(DShape selected) {
// YOUR CODE HERE
this.selected = selected;
canvas.repaint();



if(selected != null && selected.getModel().getType() == 't') {
JC_BoldCheckBox.setEnabled(true);
JC_ItalicCheckBox.setEnabled(true);
JC_Text.setEnabled(true);
JC_BoldCheckBox.setSelected(((DTextModel)selected.getModel()).getBold());
JC_ItalicCheckBox.setSelected(((DTextModel)selected.getModel()).getItalic());
JC_Text.setText(((DTextModel)selected.getModel()).getText());
} else {
JC_BoldCheckBox.setEnabled(false);
JC_ItalicCheckBox.setEnabled(false);
JC_Text.setEnabled(false);
}



}

public void addShape(DShapeModel model) {
DShape temp = null;
if(model.getType() == 'r') temp = new DRect(model, this);
if(model.getType() == 'o') temp = new DOval(model, this);
if(model.getType() == 'l') temp = new DLine(model, this);
if(model.getType() == 't') temp = new DText(model, this);
canvas.add(temp);
tableModel.add(temp.getModel());
repaint();
}

// This is just a little test main()
// The real main is in DrawFrame
static public void main(String[] args)
{
JFrame frame = new JFrame("Draw Test Frame");
frame.setContentPane(new DDocument(300, 300, null));

frame.pack();
frame.setVisible(true);

frame.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);
}
public class DrawTableModel extends AbstractTableModel implements DShapeModelListener {
private Component[] components;
String[] names = new String[]{"X","Y","Width","Height"};

/** Creates new DrawTableModel */
public DrawTableModel() {
components = canvas.getComponents();
for(int i = 0; i < components.length; i++) {
((DShape)components[i]).getModel().addListener(this);
}
}

public int getRowCount() {
return components.length;
}

public Object getValueAt(int rowIndex, int columnIndex) {
DShapeModel mod = ((DShape)components[rowIndex]).getModel();
if(columnIndex == 0) return new Integer(mod.getLocX());
if(columnIndex == 1) return new Integer(mod.getLocY());
if(columnIndex == 2) return new Integer(mod.getWidth());
if(columnIndex == 3) return new Integer(mod.getHeight());
return null;
}

public String getColumnName(int columnIndex) {
return names[columnIndex];
}
public int getColumnCount() {
return 4;
}
public void shapeChanged(DShapeModel changed) {
int i;
for(i = 0; i < components.length; i++) {
if(((DShape)components[i]).getModel() == changed) break;
}
this.fireTableRowsUpdated(i,i);
}
public void add(DShapeModel mod) {
mod.addListener(this);
components = canvas.getComponents();
this.fireTableRowsInserted(components.length,components.length);
}
public void remove(DShapeModel mod) {
mod.removeListener(this);
int i;
for(i = 0; i < components.length; i++) {
if(((DShape)components[i]).getModel() == mod) break;
}
components = canvas.getComponents();
this.fireTableRowsDeleted(i,i);
}
public void rearrange() {
components = canvas.getComponents();
this.fireTableDataChanged();
}
}
}











// DocPanel.java

import java.io.*;

/*
DocPanel Interface

These are the methods that must be supported to
be in an InnerFrame. The class will also need to
be a subclass of Component so it can be added
to the InnerFrame, and it will need a ctor which
can take a file.
*/
public interface DocPanel {
public void save(File file);
public boolean getDirty();
}









/*
* DOval.java
*
* Created on February 25, 2002, 2:09 AM
*/

/**
*
* @author Lews Therin
* @version
*/

import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;

public class DOval extends DShape {

/** Creates new DOval */
public DOval(DShapeModel model, DDocument document) {
super(model, document);
}

public void paintShape(Graphics g) {
Color old = g.getColor();
g.setColor(model.getColor());
g.fillOval(model.getLocX()-this.getX(),model.getLocY()-this.getY(),model.getWidth(),model.getHeight());
g.setColor(old);
}

}







// DrawFrame.java

import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;

/*****************************************************************
Draw Cusomization.

From here down is the custom code to use the KDeskFrame / KInnerFrame system.

The code here is already properly set for MiniDraw --
the lines are marked with "DRAW".
Run the "main" in this class.
******************************************************************/


/*
Subclass KDeskFrame just to have it create the right sort of InnerFrame
and to provide a main.
*/
public class DrawFrame extends KDeskFrame {
protected DrawFrame(String[] argv) {
super(argv);
}

protected KInnerFrame createInnerFrame(File file) {
KInnerFrame inner = new DrawInnerFrame(file); // DRAW
return(inner);
}

public static void main(String[] argv) {
new DrawFrame(argv); // DRAW
}
}


/*
Subclass KInnerFrame to override createDocPanel to create
the right sort of panel.
*/
class DrawInnerFrame extends KInnerFrame {

public DrawInnerFrame(File file) {
// Use the file name as the window title if possible
// This has to be all squeezed in to the super() call
// since it must be the first line
super((file!=null?file.getName():"Draw Panel"), file);
}

protected void createDocPanel() {
document = new DDocument(300, 300, file); // DRAW
Container container = getContentPane();
container.add((Component)document);
}
}









/*
* DRect.java
*
* Created on February 25, 2002, 2:08 AM
*/

/**
*
* @author Lews Therin
* @version
*/
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;

public class DRect extends DShape {

/** Creates new DRect */
public DRect(DShapeModel model, DDocument document) {
super(model, document);
}

public void paintShape(Graphics g) {
//int x = model.getLocX();
//int y = model.getLocY();
//int w = model.getWidth();
//int h = model.getHeight();
Color old = g.getColor();
g.setColor(model.getColor());
//g.drawLine(x,y,x+w,y+h);
g.fillRect(model.getLocX()-this.getX(),model.getLocY()-this.getY(),model.getWidth(),model.getHeight());
g.setColor(old);
//g.drawLine(50,50,90,90);

}

}







// DShape.java
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;

abstract class DShape extends JComponent implements DShapeModelListener {
public final int KNOB = 3;

protected DShapeModel model;
protected DDocument document;

static final int MOUSE_MOVE =1;
static final int MOVE_PT1 =2;
static final int MOVE_PT2 =3;

private int mmode;
private Point mpos;
private Point npos;





public DShape(DShapeModel model, DDocument document) {
super();

this.model = model;
this.document = document;

// YOUR CODE HERE

synchToModel();

model.addListener(this);

addMouseListener( new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if(DShape.this.document.getSelected() != DShape.this) {
DShape temp = DShape.this.document.getSelected();
DShape.this.document.setSelected(DShape.this);

}
mpos = new Point(e.getX()+DShape.this.getX(), e.getY()+DShape.this.getY());
onKnob(mpos);
}
});

addMouseMotionListener( new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
if(mpos != null) {
int dx = e.getX()+DShape.this.getX() - mpos.x;
int dy = e.getY()+DShape.this.getY() - mpos.y;
mpos.x = e.getX()+DShape.this.getX();
mpos.y = e.getY()+DShape.this.getY();
switch(mmode) {
case MOVE_PT1:
{
DShape.this.model.applyDeltas(dx,dy,0,0);
break;
}
case MOVE_PT2:
{
DShape.this.model.applyDeltas(0,0,dx,dy);
break;
}
case MOUSE_MOVE:
{
DShape.this.model.applyDeltas(dx,dy,dx,dy);
break;
}
}
synchToModel();

}
}
});

}

private boolean onKnob(Point pt) {
Rectangle rect1 = new Rectangle(model.getX1()-KNOB,model.getY1()-KNOB,(KNOB*2)+1,(KNOB*2)+1);
Rectangle rect2 = new Rectangle(model.getX2()-KNOB,model.getY2()-KNOB,(KNOB*2)+1,(KNOB*2)+1);

if(rect1.contains(pt)) {mmode = MOVE_PT1; return true;}
if(rect2.contains(pt)) {mmode = MOVE_PT2; return true;}

mmode = MOUSE_MOVE;
return false;
}

public DShapeModel getModel() {
return(model);
}


public void shapeChanged(DShapeModel changed) {
synchToModel();
}

private void synchToModel() {
this.setBounds(model.getLocX()-KNOB,model.getLocY()-KNOB,model.getWidth()+1+KNOB*2,model.getHeight()+1+KNOB*2);
repaint();
//Rectangle rect = this.getBounds();
//model.applyDeltas(rect.x-model.getLocX(),rect.y-model.getLocY(),rect.x+rect.width-model.getLocX()-model.getWidth(),rect.y+rect.height-model.getLocY()-model.getHeight());
}

public abstract void paintShape(Graphics g);

public void paintComponent(Graphics g) {
//g.drawLine(0,0,50,50);

paintShape(g);

// draw knobs
if(document.getSelected() == this) {
Color old = g.getColor();
g.setColor(Color.black);
g.fillRect(model.getX1()-this.getX()-KNOB,model.getY1()-this.getY()-KNOB,(KNOB*2)+1,(KNOB*2)+1);
g.fillRect(model.getX2()-this.getX()-KNOB,model.getY2()-this.getY()-KNOB,(KNOB*2)+1,(KNOB*2)+1);

g.setColor(old);
}

}





}








// DShapeModel.java
/*
Store the data state for a single shape:
type, two points, color
Supports DShapeModelListeners.
*/
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.io.*;


class DShapeModel extends Object implements Serializable {

// The 5 standard things for a DShapeModel to store
private char type;
private int x1, y1;
private int x2, y2;
private Color fill;


// Construct a DShapeModel with default size and color
public DShapeModel(char type) {
this(type, 50, 50, 89, 89, Color.gray);
}


public DShapeModel(char type, int x1, int y1, int x2, int y2, Color fill) {
this.type = type;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.fill = fill;

listeners = null;
}

public char getType() { return(type); }

public int getX1() { return(x1); }
public int getY1() { return(y1); }
public int getX2() { return(x2); }
public int getY2() { return(y2); }


// TBD from here down

public void applyDeltas(int dx1, int dy1, int dx2, int dy2) {
x1+=dx1;
y1+=dy1;
x2+=dx2;
y2+=dy2;
notifyListeners();
}

int getWidth() {
int w = Math.abs(x1-x2);
if(w != 0) return w;
return 1;
}

int getHeight() {
int h = Math.abs(y1-y2);
if(h != 0) return h;
return 1;
}

int getLocX() {
return Math.min(x1,x2);
}

int getLocY() {
return Math.min(y1,y2);
}


public Color getColor() { return(fill); }
public void setColor(Color color) {
fill = color;
notifyListeners();
}


// NOTE: "transient" -- not serialized
transient private ArrayList listeners;

public void addListener(DShapeModelListener listener) {
if(listeners == null) {
listeners = new ArrayList();
}
listeners.add(listener);
}

public void removeListener(DShapeModelListener listener) {
if(listeners == null || listener == null) return;
if(listeners.contains(listener)) {
listeners.remove(listener);
}
}

protected void notifyListeners() {
if(listeners == null) return;
Iterator it = listeners.iterator();
while(it.hasNext()) {
DShapeModelListener elem = (DShapeModelListener)it.next();
elem.shapeChanged(this);
}
}

}








// DShapeModelListener.java
/*
Interface to listen for shape change notifications.
As a courtesy, the notification includes a pointer to the
model that changed. However, there is not detail about
what the exact change was.
*/

public interface DShapeModelListener {
public void shapeChanged(DShapeModel changed);
}









/*
* DText.java
*
* Created on February 25, 2002, 11:59 AM
*/

/**
*
* @author Lews Therin
* @version
*/

import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
public class DText extends DShape {
static final int CACHE_SIZE = 1000;
static int[] lookup = new int[CACHE_SIZE];
/** Creates new DText */
public DText(DShapeModel model, DDocument document) {
super(model, document);
}

public void paintShape(Graphics g) {
Font old = g.getFont();
Color oc = g.getColor();
g.setFont(computeFont(g));
g.setColor(this.getModel().getColor());

g.drawString(((DTextModel)this.getModel()).getText(),0,this.getHeight()-g.getFontMetrics().getDescent());
//g.drawString("Hello",model.getLocX()- this.getX(), model.getLocY() - this.getY());
g.setFont(old);
g.setColor(oc);
}

private Font computeFont(Graphics g) {
int style = 0;
double size = 0;
double prev_size = 0;
Font prev;
Font temp = null;
FontMetrics met;

if(((DTextModel)this.getModel()).getBold()) style |= Font.BOLD;
if(((DTextModel)this.getModel()).getItalic()) style |= Font.ITALIC;

// IMHO, a much better caching mechanism
// we store the final result with respect the bounding rect height
// instead of storing the intermediate steps and going through them
if(model.getHeight() < CACHE_SIZE && lookup[model.getHeight()] != 0) {
int i = model.getHeight();
return new Font("Dialog", style, lookup[model.getHeight()]);
}

do {
prev = temp;
prev_size = size;
size = (size*1.10)+1;
temp = new Font("Dialog", style, (int)size);
met = g.getFontMetrics(temp);
} while (met.getAscent() + met.getDescent() < model.getHeight());
int i =model.getHeight();
if(model.getHeight() < CACHE_SIZE && lookup[model.getHeight()] == 0) lookup[model.getHeight()] = (int)prev_size;
return prev;

}

}














/*
* DTextModel.java
*
* Created on February 25, 2002, 11:48 AM
*/

/**
*
* @author Lews Therin
* @version
*/
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.io.*;

public class DTextModel extends DShapeModel {
private boolean bold;
private boolean italic;
private String text;
/** Creates new DTextModel */
public DTextModel(char type) {
super(type);
bold = false;
italic = false;
text = "Hello";
}
public DTextModel(char type, int x1, int y1, int x2, int y2, Color fill, boolean bold, boolean italic, String text) {
super(type, x1, y1, x2, y2, fill);
this.bold = bold;
this.italic = italic;
this.text = text;
}

public void setBold(boolean val) {
if(bold == val) return;
bold = val;
this.notifyListeners();
}

public void setItalic(boolean val) {
if(italic == val) return;
italic = val;
this.notifyListeners();
}

public void setText(String str) {
if(text != null && str.equals(text)) return;
text = str;
this.notifyListeners();
}

public boolean getBold() {return bold;}
public boolean getItalic() {return italic;}
public String getText() {return text;}

}












// DeskFrame.java
/*
The KDeskFrame/KInnerFrame classes build a multiple-document-
interface (MDI) for you.
They handle the boring bookeeping of New, Open, Save, Close, Quit,
and the dirty bit. A Panel that wants to appear in a KInnerFrame
should implement the DocPanel interface which specs that the panel
will implement save() and getDirty().

Really, this should have been built into Swing, which is why
I put the "K" at the start of their names

To use these classes with your DocPanel class...

1. Your panel should implement the DocPanel interface
which will require a few methods...
-ctor(file)
-save(file)
-getDirty()

2. Subclass KInnerFrame and override createDocPanel
to create an install your desired type of DocPanel.

3. Subclass KDeskFrame and override createInnerFrame
to create your type of KInnerFrame from step 1.
*/
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;


/*
The outer desktop pane -- contains the menus and InnerFrames.
Supports the NEW, CLOSE, SAVE, SAVE AS and QUIT actions.
Override createInnerFrame() to define what sort of inner
frame is created.
*/
abstract class KDeskFrame extends JFrame {
protected JDesktopPane desktop;
protected int innerCount;
protected JMenu fileMenu;
protected AbstractAction quitAction;

/*
public KDeskFrame()
{
super("Desk Frame");

innerCount = 0;

createMenus();
desktop = new JDesktopPane();
desktop.setPreferredSize(new Dimension(500, 500));

setContentPane(desktop);

pack();
setVisible(true);
}
*/
public KDeskFrame(String[] argv) {
super("Poor Man's PaintShop");

innerCount = 0;

createMenus();
desktop = new JDesktopPane();
setSize(800,600);

setContentPane(desktop);

for (int i=0; i addInnerFrame(new File(argv[i]));
}

addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent event) {
quitAction.actionPerformed(null); // this quits

// if we get here, we need to cancel the quitting
throw new RuntimeException("necessary hack: exception to cancel quitting");
}
});

setVisible(true);
}



/*
ACTION OBJECTS
For each function of the out desktop, we create an AbstractAction
object to represent that action. The action object knows the
name string of the action, and responds to actionPerformed()
in the usual way.
*/


// New
// Create a new, empty InnerFrame
private class NewAction extends AbstractAction {
public NewAction() {
super ("New");
}
public void actionPerformed(ActionEvent e) {
addInnerFrame(null);
}
}



// OPEN
// Create a new inner frame inited from a file
private class OpenAction extends AbstractAction {
public OpenAction() {
super ("Open");
}
public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser(".");
int status = chooser.showOpenDialog(KDeskFrame.this);
if (status == JFileChooser.APPROVE_OPTION) {
addInnerFrame(chooser.getSelectedFile());
}
}
}



// SAVE
// Save the contents of the frontmost docframe
private class SaveAction extends AbstractAction {
public SaveAction() {
super ("Save");
}
public void actionPerformed(ActionEvent e) {
JInternalFrame[] frames =desktop.getAllFrames();
// trick: the 0th element is the frontmost
// (it's not clear from the docs I saw if this ordering is guaranteed).
if (frames.length>0) {
((KInnerFrame)frames[0]).save();

}
}
}



// SAVE AS
private class SaveAsAction extends AbstractAction {
public SaveAsAction() {
super ("Save as...");
}
public void actionPerformed(ActionEvent e) {
JInternalFrame[] frames =desktop.getAllFrames();
if (frames.length>0) {
((KInnerFrame)frames[0]).saveAs();

}
}
}



// QUIT
// Try to close each InnerFrame -- that way the dirty
// bit check / save thing happens for them all.
private class QuitAction extends AbstractAction {
public QuitAction() {
super ("Quit");
}
public void actionPerformed(ActionEvent e) {
JInternalFrame[] frames =desktop.getAllFrames();
boolean vetoed = false;
for (int i=0; i try {
frames[i].setClosed(true);
}
catch (PropertyVetoException ex) { // get here from cancel button
vetoed = true;
break;
}
}
if (!vetoed) {
System.exit(0);
}
}
}




/*
OVERRIDE
The key override point. Create the desired sublcass of InnerFrame,
and return a pointer to it.
Read the contents of the given file, or create an empty document
if files is null.
*/
protected abstract KInnerFrame createInnerFrame(File file);


/*
Offset new windows the given distance from the edge.
Newer windows go further in.
Just for fun, we'll use the classical "golden ratio"
to proportion the h and v of the offset.
*/
public final double GOLDEN_RATIO = 1.62;
public final int INNER_OFFSET = 30; // stride to inset each new window

/*
Utility bottleneck for creating new inner frames.
*/
private void addInnerFrame(File file) {
KInnerFrame inner = createInnerFrame(file);
innerCount++;
int hOffset = INNER_OFFSET*innerCount;
int vOffset = (int) (hOffset/GOLDEN_RATIO);
// Cute: we use the "golden ratio" to scale vOffset


/*
DeskFrame does not have a layout manager, so we have to
position the thing ourselves. (Not that this is documented of course.)
*/
Dimension size = inner.getPreferredSize();
inner.setBounds(hOffset, vOffset, size.width, size.height);
desktop.add(inner, 0);

try {
inner.setSelected(true);
}
catch (PropertyVetoException ignored) {}
}


// Utility to create the menus using the Action objects
protected void createMenus() {
JMenuBar menuBar = new JMenuBar();
getRootPane().setJMenuBar(menuBar);
fileMenu = new JMenu("File");
menuBar.add(fileMenu);
fileMenu.add(new NewAction());
fileMenu.add(new OpenAction());
fileMenu.add(new SaveAction());
fileMenu.add(new SaveAsAction());
fileMenu.add(quitAction = new QuitAction());
}


/*
Utility -- create an inner frame for each arg.
Call from main().
*/
protected void processCommandLine(String[] args) {
for (int i=0; i addInnerFrame(new File(args[i]));
}
}

}












// KInnerFrame.java

import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;

/*
A subclass of JInternalFrame specialized to work with KDeskFrame
to manage the dirty bit, saving, etc.. See KDeskFrame for more info.

Override createDocPanel() to create the right sort of DocPanel
and install it in the content area.

We always have a pointer to our document object.
The File pointer may or may not be null, depending on
whether a file has been saved to yet.
*/
abstract class KInnerFrame extends JInternalFrame {
protected DocPanel document;
protected File file;

/*
OVERRIDE
Create the document and add it to the content pane.
*/
protected abstract void createDocPanel();

public KInnerFrame(String title, File file) {
super(title,
true, // resize
true, // close
true, // maximize
true); // incon

this.file = file;

createDocPanel();

addVetoableChangeListener(new CloseListener());

setOpaque(true);

setVisible(true);
}


/*
Save the document.
Check to see if there is a selected file -- prompt
for one if necessary. Then ask the document to save.
*/
public void save() {
if (file == null) {
JFileChooser chooser = new JFileChooser(".");
int status = chooser.showSaveDialog(this);
if (status == JFileChooser.APPROVE_OPTION) {
file = chooser.getSelectedFile();
}
}

if (file!=null) {
document.save(file);
setTitle(file.getName());
}
}


/*
Force save() to prompt for a new file.
*/
public void saveAs() {
file = null;
save();
}


class CloseListener implements VetoableChangeListener {
// This notification gets sent on close.
// It gets sent again if the close is veoted --
// that's why we have to check for the false/true transition.
public void vetoableChange(PropertyChangeEvent e)
throws PropertyVetoException {
String name = e.getPropertyName();
if (document.getDirty() && name.equals(JInternalFrame.IS_CLOSED_PROPERTY)) {
Boolean old = (Boolean)e.getOldValue();
Boolean now = (Boolean)e.getNewValue();
if (!old.booleanValue() && now.booleanValue()) {
int result = JOptionPane.showConfirmDialog(
KInnerFrame.this,
"Save changes?",
"Save changes?",
JOptionPane.YES_NO_CANCEL_OPTION);
if (result==JOptionPane.CANCEL_OPTION) {
throw new PropertyVetoException("close cancelled", e);
}
else {
if (result==JOptionPane.YES_OPTION) save();
}
}
}
}
}
}


















1 comment:

Unknown said...

Free Cisco eBooks – Download
http://career-assessments.blogspot.com/2008/01/cisco-certifications-aspirants.html

Looking for Cisco Certification
http://career-assessments.blogspot.com/2008/01/cisco-certifications-newbies.html

Important Networking Information
http://ccnahelpguides.blogspot.com