Contents:
SceneEditor.javaimport java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
/**
A program that allows users to edit a scene composed
of items.
*/
public class SceneEditor extends JApplet
{
JPanel buttons;
ScenePanel panel;
public void make_editor()
{
panel = new ScenePanel();
JButton houseButton = new JButton("House");
houseButton.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
panel.add(new HouseShape(20, 20, 50));
}
});
JButton carButton = new JButton("Car");
carButton.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
panel.add(new CarShape(20, 20, 50));
}
});
JButton removeButton = new JButton("Remove");
removeButton.addActionListener(new
ActionListener()
{
public void actionPerformed(ActionEvent event)
{
panel.removeSelected();
}
});
buttons = new JPanel();
buttons.add(houseButton);
buttons.add(carButton);
buttons.add(removeButton);
}
public void init()
{
make_editor();
Container contentPane = getContentPane();
contentPane.add(panel, BorderLayout.CENTER);
contentPane.add(buttons, BorderLayout.NORTH);
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = frame.getContentPane();
SceneEditor scene = new SceneEditor();
scene.make_editor();
contentPane.add(scene.panel, BorderLayout.CENTER);
contentPane.add(scene.buttons, BorderLayout.NORTH);
frame.setSize(300, 300);
frame.setVisible(true);
}
}
ScenePanel.javaimport java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.util.*;
/**
A panel that shows a scene composed of shapes.
*/
public class ScenePanel extends JPanel
{
public ScenePanel()
{
shapes = new ArrayList<SceneShape>();
addMouseListener(new
MouseAdapter()
{
public void mousePressed(MouseEvent event)
{
mousePoint = event.getPoint();
for (int i = 0; i < shapes.size(); i++)
{
SceneShape s = (SceneShape) shapes.get(i);
if (s.contains(mousePoint))
s.setSelected(!s.isSelected());
}
repaint();
}
});
addMouseMotionListener(new
MouseMotionAdapter()
{
public void mouseDragged(MouseEvent event)
{
Point lastMousePoint = mousePoint;
mousePoint = event.getPoint();
for (int i = 0; i < shapes.size(); i++)
{
SceneShape s = (SceneShape) shapes.get(i);
if (s.isSelected())
s.translate(
mousePoint.getX() - lastMousePoint.getX(),
mousePoint.getY() - lastMousePoint.getY());
}
repaint();
}
});
}
/**
Adds a shape to the scene.
@param s the shape to add
*/
public void add(SceneShape s)
{
shapes.add(s);
repaint();
}
/**
Removes all selected shapes from the scene.
*/
public void removeSelected()
{
for (int i = shapes.size() - 1; i >= 0; i--)
{
SceneShape s = (SceneShape) shapes.get(i);
if (s.isSelected()) shapes.remove(i);
}
repaint();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (int i = 0; i < shapes.size(); i++)
{
SceneShape s = (SceneShape) shapes.get(i);
s.draw(g2);
if (s.isSelected())
s.drawSelection(g2);
}
}
private ArrayList<SceneShape> shapes;
private Point mousePoint;
}
SelectableShape.javaimport java.awt.*;
import java.awt.geom.*;
/**
A shape that manages its selection state.
*/
public abstract class SelectableShape implements SceneShape
{
public void setSelected(boolean b)
{
selected = b;
}
public boolean isSelected()
{
return selected;
}
private boolean selected;
}
SceneShape.javaimport java.awt.*;
import java.awt.geom.*;
/**
A shape that is a part of a scene.
*/
public interface SceneShape
{
/**
Draws this item.
@param g2 the graphics context
*/
void draw(Graphics2D g2);
/**
Draws the selection adornment of this item.
@param g2 the graphics context
*/
void drawSelection(Graphics2D g2);
/**
Sets the selection state of this item.
@param b true if this item is selected
*/
void setSelected(boolean b);
/**
Gets the selection state of this item.
@return true if this item is selected
*/
boolean isSelected();
/**
Translates this item by a given amount.
@param dx the amount to translate in x-direction
@param dy the amount to translate in y-direction
*/
void translate(double dx, double dy);
/**
Tests whether this item contains a given point.
@param p a point
@return true if this item contains p
*/
boolean contains(Point2D p);
}
HouseShape.javaimport java.awt.*;
import java.awt.geom.*;
/**
A house shape.
*/
public class HouseShape extends SelectableShape
{
/**
Constructs a house shape.
@param x the left of the bounding rectangle
@param y the top of the bounding rectangle
@param width the width of the bounding rectangle
*/
public HouseShape(int x, int y, int width)
{
this.x = x;
this.y = y;
this.width = width;
}
public void draw(Graphics2D g2)
{
Rectangle2D.Double base
= new Rectangle2D.Double(x, y + width, width, width);
// the left bottom of the roof
Point2D.Double r1
= new Point2D.Double(x, y + width);
// the top of the roof
Point2D.Double r2
= new Point2D.Double(x + width / 2, y);
// the right bottom of the roof
Point2D.Double r3
= new Point2D.Double(x + width, y + width);
Line2D.Double roofLeft
= new Line2D.Double(r1, r2);
Line2D.Double roofRight
= new Line2D.Double(r2, r3);
g2.draw(base);
g2.draw(roofLeft);
g2.draw(roofRight);
}
public void drawSelection(Graphics2D g2)
{
Rectangle2D.Double base
= new Rectangle2D.Double(x, y + width, width, width);
g2.fill(base);
}
public boolean contains(Point2D p)
{
return x <= p.getX() && p.getX() <= x + width
&& y <= p.getY() && p.getY() <= y + 2 * width;
}
public void translate(double dx, double dy)
{
x += dx;
y += dy;
}
private int x;
private int y;
private int width;
}
CarShape.javaimport java.awt.*;
import java.awt.geom.*;
/**
A car shape.
*/
public class CarShape extends SelectableShape
{
/**
Constructs a car shape.
@param x the left of the bounding rectangle
@param y the top of the bounding rectangle
@param width the width of the bounding rectangle
*/
public CarShape(int x, int y, int width)
{
this.x = x;
this.y = y;
this.width = width;
}
public void draw(Graphics2D g2)
{
Rectangle2D.Double body
= new Rectangle2D.Double(x, y + width / 6,
width - 1, width / 6);
Ellipse2D.Double frontTire
= new Ellipse2D.Double(x + width / 6, y + width / 3,
width / 6, width / 6);
Ellipse2D.Double rearTire
= new Ellipse2D.Double(x + width * 2 / 3,
y + width / 3,
width / 6, width / 6);
// the bottom of the front windshield
Point2D.Double r1
= new Point2D.Double(x + width / 6, y + width / 6);
// the front of the roof
Point2D.Double r2
= new Point2D.Double(x + width / 3, y);
// the rear of the roof
Point2D.Double r3
= new Point2D.Double(x + width * 2 / 3, y);
// the bottom of the rear windshield
Point2D.Double r4
= new Point2D.Double(x + width * 5 / 6, y + width / 6);
Line2D.Double frontWindshield
= new Line2D.Double(r1, r2);
Line2D.Double roofTop
= new Line2D.Double(r2, r3);
Line2D.Double rearWindshield
= new Line2D.Double(r3, r4);
g2.draw(body);
g2.draw(frontTire);
g2.draw(rearTire);
g2.draw(frontWindshield);
g2.draw(roofTop);
g2.draw(rearWindshield);
}
public void drawSelection(Graphics2D g2)
{
Rectangle2D.Double body
= new Rectangle2D.Double(x, y + width / 6,
width - 1, width / 6);
g2.fill(body);
}
public boolean contains(Point2D p)
{
return x <= p.getX() && p.getX() <= x + width
&& y <= p.getY() && p.getY() <= y + width / 2;
}
public void translate(double dx, double dy)
{
x += dx;
y += dy;
}
private int x;
private int y;
private int width;
}
Maintained by John Loomis, updated Mon Feb 26 09:09:46 2007