import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class ShapeTest
{ public static void main(String[] args)
{ JFrame frame = new ShapeTestFrame();
frame.show();
}
}
class ShapeTestFrame extends JFrame
implements ActionListener
{ public ShapeTestFrame()
{ setTitle("ShapeTest");
setSize(300, 300);
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0);
}
} );
Container contentPane = getContentPane();
panel = new ShapePanel();
contentPane.add(panel, "Center");
comboBox = new JComboBox();
comboBox.addItem(new LineMaker());
comboBox.addItem(new RectangleMaker());
comboBox.addItem(new RoundRectangleMaker());
comboBox.addItem(new EllipseMaker());
comboBox.addItem(new ArcMaker());
comboBox.addItem(new PolygonMaker());
comboBox.addItem(new QuadCurveMaker());
comboBox.addItem(new CubicCurveMaker());
comboBox.addActionListener(this);
contentPane.add(comboBox, "North");
}
public void actionPerformed(ActionEvent event)
{ ShapeMaker shapeMaker =
(ShapeMaker)comboBox.getSelectedItem();
panel.setShapeMaker(shapeMaker);
}
private JComboBox comboBox;
private ShapePanel panel;
}
class ShapePanel extends JPanel
implements MouseListener, MouseMotionListener
{ public ShapePanel()
{ addMouseListener(this);
addMouseMotionListener(this);
current = -1;
}
public void setShapeMaker(ShapeMaker aShapeMaker)
{ shapeMaker = aShapeMaker;
int n = shapeMaker.getPointCount();
points = new Point2D[n];
for (int i = 0; i < n; i++)
{ double x = generator.nextDouble() * getWidth();
double y = generator.nextDouble() * getHeight();
points[i] = new Point2D.Double(x, y);
}
repaint();
}
public void paintComponent(Graphics g)
{ super.paintComponent(g);
if (points == null) return;
Graphics2D g2 = (Graphics2D)g;
for (int i = 0; i < points.length; i++)
{ double x = points[i].getX() - SIZE / 2;
double y = points[i].getY() - SIZE / 2;
g2.fill(new Rectangle2D.Double(x, y, SIZE, SIZE));
}
g2.draw(shapeMaker.makeShape(points));
}
public void mousePressed(MouseEvent event)
{ Point p = event.getPoint();
for (int i = 0; i < points.length; i++)
{ double x = points[i].getX() - SIZE / 2;
double y = points[i].getY() - SIZE / 2;
Rectangle2D r = new Rectangle2D.Double(x, y, SIZE, SIZE);
if (r.contains(p))
{ current = i;
return;
}
}
}
public void mouseReleased(MouseEvent event)
{ current = -1;
}
public void mouseEntered(MouseEvent event)
{
}
public void mouseExited(MouseEvent event)
{
}
public void mouseClicked(MouseEvent event)
{
}
public void mouseMoved(MouseEvent event)
{
}
public void mouseDragged(MouseEvent event)
{ if (current == -1) return;
points[current] = event.getPoint();
repaint();
}
private Point2D[] points;
private static Random generator = new Random();
private static int SIZE = 10;
private int current;
private ShapeMaker shapeMaker;
}
abstract class ShapeMaker
{ public ShapeMaker(int aPointCount)
{ pointCount = aPointCount;
}
public int getPointCount()
{ return pointCount;
}
public abstract Shape makeShape(Point2D[] p);
public String toString()
{ return getClass().getName();
}
private int pointCount;
}
class LineMaker extends ShapeMaker
{ public LineMaker() { super(2); }
public Shape makeShape(Point2D[] p)
{ return new Line2D.Double(p[0], p[1]);
}
}
class RectangleMaker extends ShapeMaker
{ public RectangleMaker() { super(2); }
public Shape makeShape(Point2D[] p)
{ Rectangle2D s = new Rectangle2D.Double();
s.setFrameFromDiagonal(p[0], p[1]);
return s;
}
}
class RoundRectangleMaker extends ShapeMaker
{ public RoundRectangleMaker() { super(2); }
public Shape makeShape(Point2D[] p)
{ RoundRectangle2D s
= new RoundRectangle2D.Double(0, 0, 0, 0, 20, 20);
s.setFrameFromDiagonal(p[0], p[1]);
return s;
}
}
class EllipseMaker extends ShapeMaker
{ public EllipseMaker() { super(2); }
public Shape makeShape(Point2D[] p)
{ Ellipse2D s = new Ellipse2D.Double();
s.setFrameFromDiagonal(p[0], p[1]);
return s;
}
}
class ArcMaker extends ShapeMaker
{ public ArcMaker() { super(4); }
public Shape makeShape(Point2D[] p)
{ double centerX = (p[0].getX() + p[1].getX()) / 2;
double centerY = (p[0].getY() + p[1].getY()) / 2;
double width = Math.abs(p[1].getX() - p[0].getX());
double height = Math.abs(p[1].getY() - p[0].getY());
double distortedStartAngle
= Math.toDegrees(Math.atan2(-(p[2].getY() - centerY)
* width, (p[2].getX() - centerX) * height));
double distortedEndAngle
= Math.toDegrees(Math.atan2(-(p[3].getY() - centerY)
* width, (p[3].getX() - centerX) * height));
double distortedAngleDifference
= distortedEndAngle - distortedStartAngle;
if (distortedStartAngle < 0)
distortedStartAngle += 360;
if (distortedAngleDifference < 0)
distortedAngleDifference += 360;
Arc2D s = new Arc2D.Double(0, 0, 0, 0,
distortedStartAngle, distortedAngleDifference,
Arc2D.OPEN);
s.setFrameFromDiagonal(p[0], p[1]);
GeneralPath g = new GeneralPath();
g.append(s, false);
Rectangle2D r = new Rectangle2D.Double();
r.setFrameFromDiagonal(p[0], p[1]);
g.append(r, false);
Point2D center = new Point2D.Double(centerX, centerY);
g.append(new Line2D.Double(center, p[2]), false);
g.append(new Line2D.Double(center, p[3]), false);
return g;
}
}
class PolygonMaker extends ShapeMaker
{ public PolygonMaker() { super(6); }
public Shape makeShape(Point2D[] p)
{ GeneralPath s = new GeneralPath();
s.moveTo((float)p[0].getX(), (float)p[0].getY());
for (int i = 1; i < p.length; i++)
s.lineTo((float)p[i].getX(), (float)p[i].getY());
s.closePath();
return s;
}
}
class QuadCurveMaker extends ShapeMaker
{ public QuadCurveMaker() { super(3); }
public Shape makeShape(Point2D[] p)
{ return new QuadCurve2D.Double(p[0].getX(), p[0].getY(),
p[1].getX(), p[1].getY(), p[2].getX(), p[2].getY());
}
}
class CubicCurveMaker extends ShapeMaker
{ public CubicCurveMaker() { super(4); }
public Shape makeShape(Point2D[] p)
{ return new CubicCurve2D.Double(p[0].getX(), p[0].getY(),
p[1].getX(), p[1].getY(), p[2].getX(), p[2].getY(),
p[3].getX(), p[3].getY());
}
}
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class ShapeTest
{ public static void main(String[] args)
{ JFrame frame = new ShapeTestFrame();
frame.show();
}
}
class ShapeTestFrame extends JFrame
implements ActionListener
{ public ShapeTestFrame()
{ setTitle("ShapeTest");
setSize(300, 300);
addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0);
}
} );
Container contentPane = getContentPane();
panel = new ShapePanel();
contentPane.add(panel, "Center");
comboBox = new JComboBox();
comboBox.addItem(new LineMaker());
comboBox.addItem(new RectangleMaker());
comboBox.addItem(new RoundRectangleMaker());
comboBox.addItem(new EllipseMaker());
comboBox.addItem(new ArcMaker());
comboBox.addItem(new PolygonMaker());
comboBox.addItem(new QuadCurveMaker());
comboBox.addItem(new CubicCurveMaker());
comboBox.addActionListener(this);
contentPane.add(comboBox, "North");
}
public void actionPerformed(ActionEvent event)
{ ShapeMaker shapeMaker =
(ShapeMaker)comboBox.getSelectedItem();
panel.setShapeMaker(shapeMaker);
}
private JComboBox comboBox;
private ShapePanel panel;
}
class ShapePanel extends JPanel
implements MouseListener, MouseMotionListener
{ public ShapePanel()
{ addMouseListener(this);
addMouseMotionListener(this);
current = -1;
}
public void setShapeMaker(ShapeMaker aShapeMaker)
{ shapeMaker = aShapeMaker;
int n = shapeMaker.getPointCount();
points = new Point2D[n];
for (int i = 0; i < n; i++)
{ double x = generator.nextDouble() * getWidth();
double y = generator.nextDouble() * getHeight();
points[i] = new Point2D.Double(x, y);
}
repaint();
}
public void paintComponent(Graphics g)
{ super.paintComponent(g);
if (points == null) return;
Graphics2D g2 = (Graphics2D)g;
for (int i = 0; i < points.length; i++)
{ double x = points[i].getX() - SIZE / 2;
double y = points[i].getY() - SIZE / 2;
g2.fill(new Rectangle2D.Double(x, y, SIZE, SIZE));
}
g2.draw(shapeMaker.makeShape(points));
}
public void mousePressed(MouseEvent event)
{ Point p = event.getPoint();
for (int i = 0; i < points.length; i++)
{ double x = points[i].getX() - SIZE / 2;
double y = points[i].getY() - SIZE / 2;
Rectangle2D r = new Rectangle2D.Double(x, y, SIZE, SIZE);
if (r.contains(p))
{ current = i;
return;
}
}
}
public void mouseReleased(MouseEvent event)
{ current = -1;
}
public void mouseEntered(MouseEvent event)
{
}
public void mouseExited(MouseEvent event)
{
}
public void mouseClicked(MouseEvent event)
{
}
public void mouseMoved(MouseEvent event)
{
}
public void mouseDragged(MouseEvent event)
{ if (current == -1) return;
points[current] = event.getPoint();
repaint();
}
private Point2D[] points;
private static Random generator = new Random();
private static int SIZE = 10;
private int current;
private ShapeMaker shapeMaker;
}
abstract class ShapeMaker
{ public ShapeMaker(int aPointCount)
{ pointCount = aPointCount;
}
public int getPointCount()
{ return pointCount;
}
public abstract Shape makeShape(Point2D[] p);
public String toString()
{ return getClass().getName();
}
private int pointCount;
}
class LineMaker extends ShapeMaker
{ public LineMaker() { super(2); }
public Shape makeShape(Point2D[] p)
{ return new Line2D.Double(p[0], p[1]);
}
}
class RectangleMaker extends ShapeMaker
{ public RectangleMaker() { super(2); }
public Shape makeShape(Point2D[] p)
{ Rectangle2D s = new Rectangle2D.Double();
s.setFrameFromDiagonal(p[0], p[1]);
return s;
}
}
class RoundRectangleMaker extends ShapeMaker
{ public RoundRectangleMaker() { super(2); }
public Shape makeShape(Point2D[] p)
{ RoundRectangle2D s
= new RoundRectangle2D.Double(0, 0, 0, 0, 20, 20);
s.setFrameFromDiagonal(p[0], p[1]);
return s;
}
}
class EllipseMaker extends ShapeMaker
{ public EllipseMaker() { super(2); }
public Shape makeShape(Point2D[] p)
{ Ellipse2D s = new Ellipse2D.Double();
s.setFrameFromDiagonal(p[0], p[1]);
return s;
}
}
class ArcMaker extends ShapeMaker
{ public ArcMaker() { super(4); }
public Shape makeShape(Point2D[] p)
{ double centerX = (p[0].getX() + p[1].getX()) / 2;
double centerY = (p[0].getY() + p[1].getY()) / 2;
double width = Math.abs(p[1].getX() - p[0].getX());
double height = Math.abs(p[1].getY() - p[0].getY());
double distortedStartAngle
= Math.toDegrees(Math.atan2(-(p[2].getY() - centerY)
* width, (p[2].getX() - centerX) * height));
double distortedEndAngle
= Math.toDegrees(Math.atan2(-(p[3].getY() - centerY)
* width, (p[3].getX() - centerX) * height));
double distortedAngleDifference
= distortedEndAngle - distortedStartAngle;
if (distortedStartAngle < 0)
distortedStartAngle += 360;
if (distortedAngleDifference < 0)
distortedAngleDifference += 360;
Arc2D s = new Arc2D.Double(0, 0, 0, 0,
distortedStartAngle, distortedAngleDifference,
Arc2D.OPEN);
s.setFrameFromDiagonal(p[0], p[1]);
GeneralPath g = new GeneralPath();
g.append(s, false);
Rectangle2D r = new Rectangle2D.Double();
r.setFrameFromDiagonal(p[0], p[1]);
g.append(r, false);
Point2D center = new Point2D.Double(centerX, centerY);
g.append(new Line2D.Double(center, p[2]), false);
g.append(new Line2D.Double(center, p[3]), false);
return g;
}
}
class PolygonMaker extends ShapeMaker
{ public PolygonMaker() { super(6); }
public Shape makeShape(Point2D[] p)
{ GeneralPath s = new GeneralPath();
s.moveTo((float)p[0].getX(), (float)p[0].getY());
for (int i = 1; i < p.length; i++)
s.lineTo((float)p[i].getX(), (float)p[i].getY());
s.closePath();
return s;
}
}
class QuadCurveMaker extends ShapeMaker
{ public QuadCurveMaker() { super(3); }
public Shape makeShape(Point2D[] p)
{ return new QuadCurve2D.Double(p[0].getX(), p[0].getY(),
p[1].getX(), p[1].getY(), p[2].getX(), p[2].getY());
}
}
class CubicCurveMaker extends ShapeMaker
{ public CubicCurveMaker() { super(4); }
public Shape makeShape(Point2D[] p)
{ return new CubicCurve2D.Double(p[0].getX(), p[0].getY(),
p[1].getX(), p[1].getY(), p[2].getX(), p[2].getY(),
p[3].getX(), p[3].getY());
}
}