import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.util.*; public class Shape3DTest extends JApplet { private Set shapeSet; private JTextField numShapesField; private int numShapes; private final int PROXIMITY=20; private CustomPanel drawPanel; private JTextArea debug; public void init() { Container container = getContentPane(); container.setLayout( new BorderLayout() ); JPanel northPanel = new JPanel(); northPanel.setLayout( new FlowLayout() ); container.add( northPanel, BorderLayout.NORTH ); drawPanel = new CustomPanel(); drawPanel.setBackground( Color.WHITE ); drawPanel.setBorder( BorderFactory.createLineBorder( Color.RED ) ); container.add( drawPanel, BorderLayout.CENTER ); shapeSet = new HashSet(); debug = new JTextArea(10,10); //northPanel.add( new JScrollPane( debug ) ); JLabel numShapesLabel = new JLabel( "Number of shapes" ); northPanel.add( numShapesLabel ); numShapesField = new JTextField( "", 4 ); northPanel.add( numShapesField ); numShapesField.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent event ) { try { numShapes = Integer.parseInt( numShapesField.getText() ); } catch (NumberFormatException e) { numShapes = 0; } if ( numShapes > 0 ) { shapeSet.clear(); //throw away the previous set for (int i=1; i<=numShapes; i++) switch ( (int)(Math.random() * 4) ) { case 0: shapeSet.add( new Cone( (int)(Math.random() * 20), (int)(Math.random() * 20) + 10)); break; case 1: shapeSet.add( new Sphere( (int)(Math.random() * 20) + 10 )); break; case 2: shapeSet.add( new Cylinder( (int)(Math.random() * 20) + 10, (int)(Math.random() * 20) + 10)); break; case 3: shapeSet.add( new Cube( (int)(Math.random() * 20) + 10) ); break; default: break; } drawPanel.draw(); //repaint(); } } } ); } public void start() { numShapesField.requestFocusInWindow(); } public void paint( Graphics g ) { super.paint( g ); showStatus( "Click for data. Drag to move"); } //find the shape object near the x,y coord, if any private Shape3D findShape( Set shapeSet, int x, int y ) { Shape3D shape=null; boolean found=false; Iterator iter = shapeSet.iterator(); debug.append("**"+x+","+y+"\n"); while ( iter.hasNext() && !found ) { shape = (Shape3D)iter.next(); debug.append(""+shape.getX()+","+shape.getY()+"\n"); //getX, Y is upperleft. need whole area... //if ( Math.abs(shape.getX()-x) <= PROXIMITY && // Math.abs(shape.getY()-y) <= PROXIMITY ) if ( x>=shape.getX() && x<=shape.getX()+(int)shape.dim1() && y>=shape.getY() && y<=shape.getY()+(int)shape.dim2() ) found = true; } if ( found ) return shape; else return null; } private class CustomPanel extends JPanel { private int mousePressX; private int mousePressY; private int lastX; private int lastY; //custompanel will listen for mouse events in it //so coords are relative to it, not applet CustomPanel() { addMouseListener( new MouseAdapter() { public void mousePressed (MouseEvent event) { mousePressX = event.getX(); mousePressY = event.getY(); lastX = event.getX(); //for drag line lastY = event.getY(); } public void mouseReleased (MouseEvent event) { if ( event.getX() != mousePressX ) { //release of a drag Shape3D shape; shape = findShape( shapeSet, mousePressX, mousePressY ); if ( shape != null ) { shape.setX( event.getX() ); shape.setY( event.getY() ); draw(); } } } public void mouseClicked( MouseEvent event) { if ( event.getX() == mousePressX ) { //not part of a drag Shape3D shape; shape = findShape( shapeSet, event.getX(), event.getY() ); if ( shape != null ) if ( ! event.isMetaDown() ) showStatus( "Area=" + shape.getArea() ); else showStatus( "Volume=" + shape.getVolume() ); else showStatus( "Not near any object" ); } } } ); addMouseMotionListener( new MouseMotionAdapter() { public void mouseDragged( MouseEvent event) { //make trail... Graphics g = getGraphics(); g.drawLine( lastX, lastY, event.getX(), event.getY() ); lastX = event.getX(); lastY = event.getY(); } } ); } public void paintComponent( Graphics g ) { super.paintComponent( g ); Iterator iter = shapeSet.iterator(); while ( iter.hasNext() ) ((Shape3D)iter.next()).draw( g ); showStatus( "Click for data. Drag to move"); } public void draw() { repaint(); } } }