What links a click/tap position to select an object on screen?

JAVA GUI PROGRAMMING program code

  • I need you to write four .java files: Chaser.java, Runner.java, Random.java, and Custom.java that produce the characteristics given below. There is a base class Creature, with source code in Creature.java. Four classes derived from Creature shall be as follows: Notes for CreatureWorld.java This program exhibits the behavior of 4 types of "creatures" as they interact with each other in a world consisting of a region on your terminal screen. It can be thought of as a simple "artificial life" simulation of the interaction of these creatures in their small world. To keep it simple, the interaction between the creatures is restricted in a way that is described below. Each creature is implemented as a Java object, and so it is an instance of some Java class. The code I have already written is below. They are the files CreatureWorld.java and Creature.java. When writing the code please try to keep at a level at which I can understand. I do not consider myself an advanced programmer and want to be able to interpret the code given to me instead of just having a program that compiles. a. The "Chaser" class. A Chaser tries to catch other creatures. When it gets a chance to interact with another Creature, a Chaser moves to a location which, of all its neighboring locations on the screen, is nearest to the other creature. A Chaser creature appears on the screen as a red filled circle 15 pixels in diameter, with its center at the Chaser's location. b. The "Runner" class. A Runner tries to escape from other creatures. In each interaction with another creature, a Runner moves to a location which, of all its neighboring locations, is farthest from the other creature. A Runner creature appears on the screen as a green filled square 15 pixels on a side, with its center at the Runner's location. c. The "Random" class. A Random doesn't care about other creatures. When it gets a chance to interact with another creature, a Random creature moves to a randomly selected location, no matter where the other creature is. The new location must be no more than 20 pixels horizontally and 20 pixels vertically of its previous location. A Random creature appears on the screen as a blue 'X', with the center of the X at the Random's location. The 'X' should be 15 pixels high and 15 pixels wide. d. Here you get to use your imagination. A Custom creature can respond to the other creature in any way you like, as long as the way it does this is different from what the other 3 types of creature do, and as long as it does something. In addition, it can display itself in any way you like, as long as it is different from the other 3 types, and as long as it displays visibly, at its current location. Within these constraints, anything is fine, so have fun. In any case, no creature (even a Custom one) should ever move outside the boundaries of the "world"; when it gets to an edge, it should move as best it can within the constraints of the boundary. (This must be true even if the Creature it is reacting to is somehow outside the boundary) When the program runs, the user is given the opportunity to select the types of Creature to observe, their initial location, and how many steps to run the simulation. To exit the simulation, the user can close the application window. The base class constructor in Creature.java may handle all of the initialization you need; but since constructors are not inherited, you have to define your own in the derived classes. The constructor must take 2 int arguments, the initial x and y coordinates of the Creature. Override the reactTo() and paint() methods to do the appropriate thing for each derived class; the ones in the base class are abstract, so do not include method bodies. (the base class instance variables have protected visibility, so they are directly accessible within methods of derived classes.) These methods will be called from the CreatureWorld application, after the user clicks the START button to begin the simulation. The basic animulation loop in CreatureWorld looks like this (some pseudocode here): // loop for the right number of animation steps for(int step = 1; step<=steps; step++) { // get a Rectangle specifying the size of the "world" Rectangle r = Rectangle_For(world); // react each pair of Creatures in order of their indices int nCreatures = Number_Of_Creatures(); for(int ic1 = 0; ic1 < nCreatures; ic1++) { for(int ic2 = 0; ic2 < nCreatures; ic2++) { // make Creature indexed ic1 move in reaction to // creature indexed ic2; but don't bother if ic1 == ic2 if (ic1 == ic2) continue; Creature c1 = Creature_Indexed(ic1); Creature c2 = Creature_Indexed(ic2); c1.reactTo(c2,r); } } // display the Creatures at their new location Graphics g = Graphics_For(world); for(int ic = 0; ic < nCreatures; ic++) { Creature c1 = Creature_Indexed(ic); c1.paint(g); } } The loop structure ensures that each Creature gets to reactTo() every other one before the result of each animation step is displayed; but the order in which these reactions take place depends on the order in which the Creatures were added, and different behaviors can happen as a result. If there are more than 2 Creatures involved, their interactions can be hard to predict (that's why simulations are useful). To implement the paint() method, note that a java.awt.Graphics object is passed as argument. The Graphics class defines lots of instance methods for doing graphics. Here are some suggested prototypes for some of the methods that I would prefer you to use: public void drawLine(int x1, int y1, int x2, int y2); public void drawOval(int x, int y, int width, int height); public void drawRect(int x, int y, int width, int height); public void drawString(String str, int x, int y); public void fillOval(int x, int y, int width, int height); public void fillRect(int x, int y, int width, int height); public void setColor(Color c); Note that the x, y location for rectangles and ovals is the upper left "corner" of the rectangle or oval. Make the reactTo() method take two arguments: a Creature to react to, and a Rectangle that specifies the limits of allowed movement. The Creature must not move outside that Rectangle. Rectangle is a class in the java.awt package. It is a somewhat unusual class, in that its instance variables are public: public int x; // The x coordinate of the upper left corner of the rectangle. public int y; // The y coordinate of the rectangle. public int width; // The width of the rectangle. public int height; // The height of the rectangle. Rectangle also defines many instance methods. One you may find useful has this prototype: //Checks whether this rectangle contains the point at the specified location (x, y) public boolean contains(int x, int y) The hard part is coming up with an algorithm for finding a "best" position for a Chaser or a Runner creature to move to, when it reacts to another creature. Here's a hint for one possible way to do this. A creature has a certain x,y location on the "world Canvas". The neighboring locations are the 9 pixels with coordinates x-1,y-1 x,y-1 x+1,y-1 x-1,y x,y x+1,y x-1,y+1 x,y+1 x+1,y+1 So, all combinations of offsets from the current x and y coordinates can be tried with a doubly-nested for loop. You can pick the one that is "best" according to whether the creature wants to be closer or farther from the location of the other creature (but remember to stay within the boundaries of the Rectangle passed to the reactTo() method). import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Vector; /*********************************************************** * class CreatureWorld * CreatureWorld extends JFrame to create a GUI "artificial life" simulation. ***********************************************************/ public class CreatureWorld extends JFrame { /** * Initialize the application JFrame. */ public CreatureWorld() { super("Creature World"); // initialize JFrame, with a title // set size and location of the application JFrame setBounds(APPLOC_X,APPLOC_Y,APPFRAMEWIDTH,APPFRAMEHEIGHT); // get the JFrame's contentPane, to add JComponents to Container thisPane = getContentPane(); // create panel for North region of Frame // holds messageLabel JPanel northPanel = new JPanel(); JPanel messagePanel = new JPanel(); messageLabel = new JLabel("Welcome to the Creature World! Place Creatures, then START"); northPanel.add(messageLabel); thisPane.add(northPanel,BorderLayout.NORTH); // create panel for South region of Frame // holds two further JPanels: // one for steps JTextField and its associated JLabels, // one for Creature placement buttons JPanel southPanel = new JPanel(); southPanel.setLayout(new GridLayout(2,1)); // set up the panel for displaying steps info JPanel stepsPanel = new JPanel(); stepsPanel.add(new JLabel("Steps:",JLabel.RIGHT)); stepsField = new JTextField(" 100"); stepsPanel.add(stepsField); stepsPanel.add(new JLabel(" Steps done: ",JLabel.RIGHT)); stepsLabel = new JLabel("0 ",JLabel.LEFT); stepsPanel.add(stepsLabel); // set up the panel for displaying Creature placement buttons // ActionListener for a Creature placement button will just // call startCreaturePlacement(ActionEvent e) ActionListener startCreaturePlacement = new ActionListener() { // anon. inner class public void actionPerformed(ActionEvent e) { startCreaturePlacement(e); }}; JPanel buttonPanel = new JPanel(); buttonPanel.add(new JLabel("Creature types: ")); JButton chaserButton = new JButton("Chaser"); JButton chaserButton = new JButton("Chaser"); chaserButton.setBackground(Color.red); buttonPanel.add(chaserButton); chaserButton.addActionListener(startCreaturePlacement); JButton runnerButton = new JButton("Runner"); runnerButton.setBackground(Color.green); buttonPanel.add(runnerButton); runnerButton.addActionListener(startCreaturePlacement); JButton randomButton = new JButton("Random"); randomButton.setBackground(Color.blue); buttonPanel.add(randomButton); randomButton.addActionListener(startCreaturePlacement); JButton customButton = new JButton("Custom"); buttonPanel.add(customButton); customButton.addActionListener(startCreaturePlacement); southPanel.add(buttonPanel); southPanel.add(stepsPanel); thisPane.add(southPanel,BorderLayout.SOUTH); // put Start button in East region JButton startButton = new JButton("START"); thisPane.add(startButton,BorderLayout.EAST); startButton.addActionListener(new ActionListener () { public void actionPerformed(ActionEvent e) { doSimulation(); }}); // put Clear button in West region JButton clearButton = new JButton("CLEAR"); thisPane.add(clearButton,BorderLayout.WEST); clearButton.addActionListener(new ActionListener () { // anon. inner class public void actionPerformed(ActionEvent e) { // implement actionPerformed doClear(); // to call our private method }}); // create the world JPanel. Use an anonymous inner class to // override the paintComponent() method to display such Creatures as // may exist world = new JPanel() { public void paintComponent(Graphics g) { super.paintComponent(g); // superclass version clears background // Ask each Creature to draw itself for(int i=0; i<creatureVec.size(); i++) { Creature c = (Creature) creatureVec.get(i); c.paint(g); } } }; world.setBackground(Color.white); world.setSize(WORLDWIDTH, WORLDHEIGHT); // the world gets a MouseListener world.addMouseListener(new MouseAdapter() { // anon. inner class public void mouseClicked(MouseEvent e) { // override mouseClicked handleMouseClicked(e); // to call our private method }}); thisPane.add(world,BorderLayout.CENTER); // give the overall Frame a WindowListener to handle closing events addWindowListener(new WindowAdapter() { // anonymous inner class public void windowClosing(WindowEvent e) { dispose(); System.exit(0); }}); } // a mouse clicked event handler for the world: place a Creature private void handleMouseClicked(MouseEvent e) { // if we're not placing a Creature, explain and return if(placeCreatureType == NONE) { announce("Select a Creature type first, then click to place!"); return; } // okay, now we're placing a kind of Creature. // get the x,y coordinates of the mouse click int x = e.getX(); int y = e.getY(); // pointer to the new creature we will create Creature newCreature = null; // create a new Creature of the appropriate type switch(placeCreatureType) { case CHASER: newCreature = new Chaser(x,y); break; case RUNNER: newCreature = new Runner(x,y); break; case RANDOM: newCreature = new Random(x,y); break; case CUSTOM: newCreature = new Custom(x,y); break; default: System.err.println("Shouldn't happen! Bad creature type: " + placeCreatureType); System.exit(-1); } // put it in the creatures vector creatureVec.add(newCreature); // display the new creature, and finish up world.paintImmediately(world.getVisibleRect()); // done placing placeCreatureType = NONE; setCursor(Cursor.getDefaultCursor()); announce("Place another creature, or push START."); } // user wants to place a Creature private void startCreaturePlacement(ActionEvent e) { // we use CROSSHAIR_CURSOR to indicate placement mode setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); String label = e.getActionCommand(); // user wants to place a Chaser if(label.equals("Chaser")) { placeCreatureType = CHASER; announce("Click to place a Chaser..."); } // user wants to place a Runner if(label.equals("Runner")) { placeCreatureType = RUNNER; announce("Click to place a Runner..."); } // user wants to place a Random if(label.equals("Random")) { placeCreatureType = RANDOM; announce("Click to place a Random..."); } // user wants to place a Custom if(label.equals("Custom")) { placeCreatureType = CUSTOM; announce("Click to place a Custom..."); } } // user wants to clear the world of Creatures private void doClear() { // get rid of current Creatures creatureVec.clear(); // indicate we are not in creature-placement mode placeCreatureType = NONE; setCursor(Cursor.getDefaultCursor()); stepsLabel.setText("0"); // clear the world display world.paintImmediately(world.getVisibleRect()); announce("Welcome to the Creature World! Place some Creatures, then START"); } private void doSimulation() { if (creatureVec.size() < 2) { announce("You need at least 2 creatures. Please place more!"); return; } int steps = 0; // read the text in the stepsField to find how many steps in the animation try{ steps = Integer.parseInt(stepsField.getText().trim()); } catch (NumberFormatException ex) { announce("Formatting error in Steps text field. Try again"); return; } announce("Running..."); // loop for the right number of animation steps for(int step = 1; step<=steps; step++) { // get a Rectangle specifying the size of the "world" Rectangle r = new Rectangle(world.getSize().width,world.getSize().height); // react each pair of Creatures for(int ic1 = 0; ic1 < creatureVec.size(); ic1++) { for(int ic2 = 0; ic2 < creatureVec.size(); ic2++) { // make Creature indexed ic1 move in reaction to // creature indexed ic2; but don't bother if ic1 == ic2 if (ic1 == ic2) continue; Creature c1 = (Creature) creatureVec.get(ic1); Creature c2 = (Creature) creatureVec.get(ic2); c1.reactTo(c2,r); } } // display the Creatures at their new location world.paintImmediately(r); // show how many steps we've done stepsLabel.setText(Integer.toString(step)); // guess we have to explicitly repaint the JLabel..? stepsLabel.paintImmediately(stepsLabel.getVisibleRect()); // sleep for a short interval so everything doesn't happen at once try { Thread.sleep(msBetweenFrames); } catch (Exception ex) {} } // done! announce("Click START to continue, CLEAR to start over"); } // print a string in the messageLabel private void announce(String s) { messageLabel.setText(s); } // just paint the world with the background color private void clearWorld() { int width = world.getSize().width; int height = world.getSize().height; world.getGraphics().clearRect(0,0,width,height); } // named constants corresponding to the Creature types public static final int NONE = 0; public static final int CHASER = 1; public static final int RUNNER = 2; public static final int RANDOM = 3; public static final int CUSTOM = 4; // initial dimensions of the application frame private static final int APPFRAMEWIDTH = 600; private static final int APPFRAMEHEIGHT = 400; // initial location of the application frame on the display private static final int APPLOC_X = 50; private static final int APPLOC_Y = 50; // initial dimensions of the world panel private static final int WORLDWIDTH = 400; private static final int WORLDHEIGHT = 300; // milliseconds to pause between frames of the animation private int msBetweenFrames = 60; private JPanel world; private Vector creatureVec = new Vector(); private int placeCreatureType = NONE; private JTextField stepsField; private JLabel stepsLabel; private JLabel messageLabel; /** * Start the CreatureWorld application */ public static void main(String args[]) { (new CreatureWorld()).setVisible(true); } } import java.awt.*; /*********************************************************** * class Creature * Creature is a base class intended to be subclassed to * model various kinds of creatures. See the README for details. ***********************************************************/ public abstract class Creature { /** * Initialize a Creature with a x,y location. */ protected Creature(int x, int y) { this.x = x; this.y = y; } /** * Change this Creature's location to respond to * the other Creature. * This method is abstract; it * must be overridden in derived classes. The Creature must * never move outside the limits of the given Rectangle. * @param other The other creature. * @param world A rectangle that specifies the limits of the world. */ public abstract void reactTo(Creature other, Rectangle world); /** * Display the Creature at its current location on the * given Graphics object. This method is abstract; it * must be overridden in derived classes * @param g The Graphics object to use for display. */ public abstract void paint(Graphics g); /** * return the current x coordinate of the Creature's location. */ public final int getLocationX() { return x; } /** * return the current y coordinate of the Creature's location. */ public final int getLocationY() { return y; } /** return, as a double, the distance in pixels * between this Creature and another. */ public double distanceTo(Creature other) { double dx = this.x - other.x; double dy = this.y - other.y; return Math.sqrt(dx*dx + dy*dy); } /** return, as a double, the angle in radians * between this Creature and another. */ public double angleTo(Creature other) { double dx = this.x - other.x; double dy = this.y - other.y; return Math.atan2(dy,dx); } protected int x; // current x coordinate of Creature protected int y; // current y coordinate of Creature }

  • Answer:

    As always, please use the "Request Clarification" button to request clarification or solicit additional features or functionality before rating this answer. I've interpreted the question to mean that you are looking for something fairly simple, rather than a fancy animation with many features and sophisticated graphics. I've implemented the constraints in the files: Creature.java CreatureWorld.java Custom.java Random.java Chaser.java Runner.java Because it is kind of messy to cut and paste java code here, I have placed them in the URLs: http://www.rbnn.com/google/Creature.java http://www.rbnn.com/google/CreatureWorld.java http://www.rbnn.com/google/Custom.java http://www.rbnn.com/google/Random.java http://www.rbnn.com/google/Chaser.java http://www.rbnn.com/google/Runner.java I did not change CreatureWorld at all. I modified Creature by adding the single method: public double distance2FromPoint(int x, int y){ return Math.pow(x-this.x,2)+Math.pow(y-this.y,2); } This gives the square of the distance of a creature from a given point, and is used by Runner, Chaser, and Custom. (If it is not allowed to change Creature.java, just move this method to the classes where it is used.) The Custom creature displays as a black rectangle. It moves diagonally and changes direction when either it hits a wall or if it is within a distance 10 of another creature. Note that two creatures can be on the same coordinate (and two Chaser creatures often are).

wcryder-ga at Google Answers Visit the source

Was this solution helpful to you?

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.