Trying to do a mouse event assignment. The idea is that when the user clicks the mouse the program draws a small green dot, when the mouse is released it should create a small orange dot 5 pixels down and 5 pixels right of it. The assigment requires the three programs, Dots, DotsPanel, and DrawDots. The program should also have a counter of total dots. Right now the programs compile, but the program completely breaks and gives me tons of errors when I try to run it. I'm a bit lost right now as I'm new to this GUI and user mouseEvents. Thank you! I specifically have trouble of how to get past the casting the Dots class as a Point.
Here is a copy of the instructions:
Modify the “Dots” example. Include a Dots class that contains a constructor to initialize the color and point location of the dot. The Dots class should also include two accessor methods. The ArrayList will now contain a list of the dots to draw instead of points. When the mouse is pressed, the program draws a green circle (as in the original design). When the mouse is released, the program draws a yellow circle translated 5 pixels right and 5 pixels down from the released location. Be sure to keep track of the total number of dots. You should have three files: Dots, DotsPanel, DrawDots. (10 points)
/**
* #(#)Dots.java
*
*
* #author
* #version 1.00 2015/5/16
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Dots
{
Point p;
Color col;
public Dots(Color c, Point x)
{
p=x;
col=c;
}
public Point getPointP()
{
return p.getLocation();
}
public Color getPointC()
{
return col;
}
}
....
//represents the primary panel for the Dots program on which the
//dots are drawn
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class DotsPanel extends JPanel
{
private final int WIDTH = 300, HEIGHT = 300;
private final int RADIUS = 6;
private ArrayList<Dots> pointList;
private int count;
//Sets up this panel to listen for mouse events.
public DotsPanel()
{
pointList = new ArrayList<Dots>();
count = 0;
addMouseListener(new DotsListener());
setBackground(Color.black);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
}
//Draws all of the dots stored in the list
public void paintComponent(Graphics page)
{
super.paintComponent(page);
//Retrieve an iterator for the ArrayList of points
Iterator pointIterator = pointList.iterator();
while(pointIterator.hasNext())
{
page.setColor(Color.green);
Point drawPoint = (Point) pointIterator.next();
page.fillOval(drawPoint.x - RADIUS, drawPoint.y - RADIUS,
RADIUS * 2, RADIUS * 2);
page.setColor(Color.yellow);
Point drawPoint2 = (Point) pointIterator.next();
page.fillOval(drawPoint2.x - RADIUS+5, drawPoint2.y - RADIUS+5,
RADIUS * 2, RADIUS * 2);
}
page.drawString("Count: " + count, 5, 15);
}
//represents the lister for mouse events
private class DotsListener implements MouseListener
{
//Adds the current point to the list of points and redraws
//whenever the mouse button is pressed
public void mousePressed(MouseEvent event)
{
Dots dot1 = new Dots(Color.GREEN, event.getPoint());
pointList.add(dot1);
count++;
repaint();
}
public void mouseReleased(MouseEvent event)
{
Dots dot2 = new Dots(Color.YELLOW, event.getPoint());
pointList.add(dot2);
count++;
repaint();
}
//Provide empty definitions for unused event methods
public void mouseClicked(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
}
}
.....
//demonstrates mouse events and drawing on a panel
import javax.swing.*;
public class DrawDots
{
//Creates and displays the application frame
public static void main(String[] args)
{
JFrame dotsFrame = new JFrame("Dots");
dotsFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
dotsFrame.getContentPane().add(new DotsPanel());
dotsFrame.pack();
dotsFrame.setVisible(true);
}
}
First you should use Iterator<Dots> pointIterator = pointList.iterator();. This helps the compiler to warn you in case of uncastable types (this is the first error you got). In your paintComponent method you should use Point drawPoint = pointIterator.next().getPointP(); and Point drawPoint2 = pointIterator.next().getPointP(); a view lines later.After that modifications the program runs (at least on my machine).
Related
I have an array list that keeps track of the "dots" and am using an array to keep track of the different sizes. The size is changed via a mouseWheelListener and the change is saved in that array. However for some reason ALL of the dots are resized which is not what I want. After running through it a few times everything looks like it should work but I must be missing something simple. My code as follows.
//********************************************************************
// DotsPanel.java
// Represents the primary panel for the Dots program.
//********************************************************************
import java.util.ArrayList;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.*;
public class DotsPanel extends JPanel
{
private int SIZE = 10; // radius of each dot
private int[] dotSizes = new int[10000];
int i = 0;
private ArrayList<Point> pointList;
//-----------------------------------------------------------------
// Constructor: Sets up this panel to listen for mouse events.
//-----------------------------------------------------------------
public DotsPanel()
{
pointList = new ArrayList<Point>();
addMouseListener (new DotsListener());
addMouseMotionListener(new DotsListener());
addMouseWheelListener(new DotsListener());
setBackground(Color.red);
setPreferredSize(new Dimension(300, 200));
}
//-----------------------------------------------------------------
// Draws all of the dots stored in the list.
//-----------------------------------------------------------------
public void paintComponent(Graphics page)
{
super.paintComponent(page);
page.setColor(Color.cyan);
for (Point spot : pointList)
//change size to sizes[n]
page.fillOval(spot.x-dotSizes[pointList.size()-1], spot.y-dotSizes[pointList.size()-1], dotSizes[pointList.size()-1]*2, dotSizes[pointList.size()-1]*2);
page.drawString("Count: " + pointList.size(), 5, 15);
}
//*****************************************************************
// Represents the listener for mouse events.
//*****************************************************************
private class DotsListener implements MouseListener, MouseMotionListener, MouseWheelListener
{
//--------------------------------------------------------------
// Adds the current point to the list of points and redraws
// the panel whenever the mouse button is pressed.
//--------------------------------------------------------------
public void mousePressed(MouseEvent event)
{
pointList.add(event.getPoint());
repaint();
}
//--------------------------------------------------------------
// Provide empty definitions for unused event methods.
//--------------------------------------------------------------
public void mouseClicked(MouseEvent event) {}
public void mouseReleased(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
#Override
public void mouseDragged(MouseEvent event)
{
pointList.add(event.getPoint());
dotSizes[pointList.size()-1] = SIZE;
//store size of dot here
repaint();
}
#Override
public void mouseMoved(MouseEvent event) {}
#Override
public void mouseWheelMoved(MouseWheelEvent event)
{
SIZE -= event.getWheelRotation();
repaint();
}
}
}
In this code:
for (Point spot : pointList)
//change size to sizes[n]
page.fillOval(spot.x-dotSizes[pointList.size()-1], spot.y-dotSizes[pointList.size()-1], dotSizes[pointList.size()-1]*2, dotSizes[pointList.size()-1]*2);
you are using a single dot size for all the dots: the size of the last dot that was added. (There's even a comment there to fix the problem!) You need to iterate with an index so you can index into the dotSizes array as well as the pointList ArrayList:
for (int i = 0; i < pointList.size(); ++i) {
Point spot = pointList.get(i);
int size = dotSizes[i];
page.fillOval(spot.x-size, spot.y-size, size*2, size*2);
}
It would be much better to define your own "point with size" class that encapsulates a Point and a size:
class Spot extends Point {
public int size;
public Spot(int x, int y, int size) {
super(x, y);
this.size = size;
}
}
Then change your pointList to an ArrayList<Spot> and you can go back to iterating over a single list:
for (Spot spot : pointList)
page.fillOval(spot.x-spot.size, spot.y-spot.size, 2*dot.size, 2*dot.size);
Of course, you'll also have to update the code that adds points to the list accordingly.
As an aside, it seems to me that your mousePressed handler has a bug: it does not add a size when it adds a point. Switching to a Spot class would also help avoid that kind of problem.
for (Point spot : pointList)
//change size to sizes[n]
page.fillOval(spot.x-dotSizes[pointList.size()-1], spot.y-dotSizes[pointList.size()-1], dotSizes[pointList.size()-1]*2, dotSizes[pointList.size()-1]*2);
Here is your problem. You aren't changing the size to size[n] but you are changing the size of every one to size[pointList.size()-1] or in other words, the last one. You will probably have to use a regular for loop unless you want to find the index of the current point.
This program is about creating components and moving them randomly in JApplet and removing the components if required. Every mouse click creates a new component. After creating component we can click on it and drag it where ever we want. Double clicking on the component removes it. I was successful in creating, moving and removing components.
For example i created three components on the JApplet by clicking three times randomly at different places on the JApplet.Please click here to view created components I moved them randomly around the screen. Please click here to view JApplet after randomly moving them around screen My goal is to write the final coordinates(x,y) of their position on the screen for all components created in to a text file by clicking a write button. I have no idea about mouseReleased method. Please help me with this. Thank you. Your help is very much appreciated.
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.awt.geom.*;
import javax.swing.*;
This is my main class
public class MouseTest extends JApplet
{
public void init()
{
EventQueue.invokeLater(new Runnable() {
public void run()
{
MousePanel panel = new MousePanel();
add(panel);
}
});
}
public static void main(String[] args)
{
EventQueue.invokeLater(new mainThread());
}
}
class mainThread implements Runnable
{
public void run()
{
JPanel panel = new MousePanel();
JFrame frame = new JFrame("MouseTest");
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300,200);
frame.setVisible(true);
}
}
class MousePanel extends JPanel
{
public MousePanel()
{
squares = new ArrayList<Rectangle2D>();
current = null;
addMouseListener(new MouseHandler());
addMouseMotionListener(new MouseMotionHandler());
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// draw all squares
for (Rectangle2D r : squares)
g2.draw(r);
}
/**
* Finds the first square containing a point.
* #param p a point
* #return the first square that contains p
*/
public Rectangle2D find(Point2D p)
{
for (Rectangle2D r : squares)
{
if (r.contains(p)) return r;
}
return null;
}
/**
* Adds a square to the collection.
* #param p the center of the square
*/
public void add(Point2D p)
{
double x = p.getX();
double y = p.getY();
current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH,
SIDELENGTH);
squares.add(current);
repaint();
}
/**
* Removes a square from the collection.
* #param s the square to remove
*/
public void remove(Rectangle2D s)
{
if (s == null) return;
if (s == current) current = null;
squares.remove(s);
repaint();
}
private static final int SIDELENGTH = 10;
private ArrayList<Rectangle2D> squares;
private Rectangle2D current;
// the square containing the mouse cursor
these are methods for defining and dragging and removing the object
private class MouseHandler extends MouseAdapter
{
public void mousePressed(MouseEvent event)
{
// add a new square if the cursor isn't inside a square
current = find(event.getPoint());
if (current == null) add(event.getPoint());
}
public void mouseClicked(MouseEvent event)
{
// remove the current square if double clicked
current = find(event.getPoint());
if (current != null && event.getClickCount() >= 2) remove(current);
}
}
private class MouseMotionHandler implements MouseMotionListener
{
public void mouseMoved(MouseEvent event)
{
// set the mouse cursor to cross hairs if it is inside
// a rectangle
if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor());
else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
public void mouseDragged(MouseEvent event)
{
if (current != null)
{
int x = event.getX();
int y = event.getY();
// drag the current rectangle to center it at (x, y)
current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);
repaint();
}
}
}
}
Why do you keep changing the requirement???? See original question: How to find final coordinates(x & y) of the objects position in JApplet and write them to a text file
First you wanted to write out the location of the moved component after the drag was finished.
Then you wanted to write out the location of "all" components after the drag was finished.
Now you want to write out the location of all the components after a "button" is clicked.
I have no idea about mouseReleased method.
What does this have to do with anything? That was the suggestion for your requirement in your last question. Since your requirement has changed it is no longer needed.
My goal is to write the final coordinates(x,y) of their position on the screen for all components created in to a text file by clicking a write button.
Then you need to add an ActionListener to the button. You have already been given a link to the Swing tutorial on How to Write an ActionListener so I guess the question is what code should be included in the ActionListener?
In you last question you stated:
I know how to get the location of a component
I know how to write data to a file
So the only remaining problem is how to get all the components on the panel? To do this you can use the Container.getComponents() method on your panel containing all the dragged components. The basic code for your ActionListener would be something like:
for (Component component: panel.getComponents())
{
Point location = component.getLocation();
// write the location to the file
}
I'll let you add the code for opening/closing the file.
I am having a problem with the following code. My intent is to store the coordinates of a mouse click into an arraylist using getPoint, and then draw a rectangle at each location that the user has clicked. I have searched high and low for how to extract the x and y coordinates individually from a getPoint object to no avail. I am new to java, the line that is giving me trouble at compile time is:
g2.drawRect(coordinateList(j).getHeight(),coordinateList(j.getWidth(),3,3);
I know that I am probably way off, but how can I extract the x and y coordinates of a point individually from an array list, one item of the array by one in order to repaint a rectangle at the new click point and also all the previous clicks as well?
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.event.MouseListener;
import java.awt.Point;
import java.util.*;
public class ClickCloud extends JPanel
{
private int pointxy;
//private Rectangle2D.Double r1;
private boolean mouseClick;
private int count;
//private Point[] points;
private Point coordinates = new Point(0, 0);
private ArrayList<Point> coordinateList = new ArrayList<Point>();
public ClickCloud() {
this.setPreferredSize(new Dimension(500,500));
this.addMouseListener(new MyMouseListener());
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (int j = 0; j < count; j++) {
g2.setStroke(new BasicStroke(1.0f));
g2.setPaint(Color.BLUE);
g2.drawRect(coordinateList(j).getHeight(),coordinateList(j.getWidth(),3,3);
}
}
private class MyMouseListener implements MouseListener {
public void mouseClicked(MouseEvent me) {
count++;
coordinates.setLocation(me.getPoint());
coordinateList.add(coordinates.getLocation());
repaint();
}
public void mousePressed(MouseEvent me) { }
public void mouseReleased(MouseEvent me) { }
public void mouseEntered(MouseEvent me) { }
public void mouseExited(MouseEvent me) { }
}
public static void main(String[] args) {
JFrame f = new JFrame("ClickCloud demo");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLayout(new FlowLayout());
f.add(new ClickCloud());
f.pack();
f.setVisible(true);
}
}
Thanks,
T
Forget all the getLocation and setLocation. It's redundant. Just store me.getPoint() in your coordinateList.
Then you can get the x and y coordinates with point.getX() and point.getY() respectively.
In paintComponent, there is an easier way to iterate over a list of points:
for (Point coordinate : coordinateList) { //"for each coordinate in coordinateList"
//do something with coordinate.getX() and coordinate.getY()
}
You are not getting properly the points from the ArrayList.
g2.drawRect(coordinateList(j).getHeight(),coordinateList(j.getWidth(),3,3);
To get the item at index j with an ArrayList, you simply use the method get():
Point point = coordinateList.get(j);
Then the problem is that pointonly represents, well, points... They only have X and Y coordinates, not width and height. If I try to guess what you want to do and assume that you want to draw 3x3 rectangles where the user has clicked, you would call drawRect() like this:
g2.drawRect(point.getX(), point.getY(), 3, 3);
Also:
You don't need to handle a count variable to know the number of points you have in your ArrayList. Just use the size() method of coordinateList or even better, use an enhanced for loop.
You can use MouseAdapter instead of MouseListener to only override the events you need.
You don't need the coordinates member and the get/setLocation stuff. Just write coordinateList.add(me.getPoint());
Hey guys I need help I am trying to make a program where I can draw in a window with the mouse. So far I have it to where when I click a dot appears but I need to add a drag method so that when I drag the mouse across the page it draws stuff. Can someone look at my code and help me out where you can?
Here is my code:
import javax.swing.*;
import java.awt.event.*;
public class mouse {
private static int x,y;
private static draw object = new draw ();
public static void main(String[] args){
JFrame frame = new JFrame ("Mouse");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,400);
frame.add(object);
object.addMouseListener(new AL());
}
static class AL extends MouseAdapter{
public void mousePressed(MouseEvent e){
x = e.getX();
y = e.getY();
object.drawing(x, y);
}
public void mouseDragged( MouseEvent e) {
x= e.getX();
y= e.getY();
object.drawing(x, y);
}
}
}
and
import javax.swing.*;
import java.awt.*;
public class draw extends JPanel {
private static int x,y;
public void drawing (int xx, int yy){
x=xx;
y=yy;
repaint();
}
public void paintComponent (Graphics g){
g.setColor(Color.black);
g.fillOval(x, y, 10, 10);
}
}
One idea that I have is to add your mouse coordinates each to a separate list whenever the mouse is clicked and draw based on the size of the lists, however since you are using mouse dragged you could just use Path2D.lineTo(x, y) and use e.getX() and e.getY() for the x and y coords. After this use Path2D.moveTo(x, y) to make sure line path is appended for each pixel the mouse moves (this makes sure that each movement doesn't look like a straight line, but rather like a line moving whatever direction you're "drawing" in). Also, a few tips:
The void mouseDragged usually works better when used in mouseMotionAdapter because from my experience it usually doesn't register the event in just mouseAdapter.
Since this is a drawing program, personally I'd set a variable for the size of your circle to be used in the future if you actually are planning to expand this into something bigger (example: g.fillOval(x, y, brushSize, brushSize)).
I'm working on these online Stanford lessons on Java, and we just made the leap to events, and I'm having difficulty wrapping my head around it. I'm playing around with a program that is in the "Art and Science of Java" book. This program will move a rectangle and oval around on the canvas if you click on them.
I modified the run method to try and get the listener to only work on the rectangle, but I was surprised to see even with my changes, both objects are being listened to...why?
Original run method:
public void run() {
GRect rect = new GRect(100, 100, 150, 100);
rect.setFilled(true);
rect.setColor(Color.RED);
add(rect);
GOval oval = new GOval(300, 115, 100, 70);
oval.setFilled(true);
oval.setColor(Color.GREEN);
add(oval);
addMouseListeners();
}
My changed program (with the MouseListener in the private createRectangle method):
import java.awt.*;
import java.awt.event.*;
import acm.graphics.*;
import acm.program.*;
/** This class displays a mouse-draggable rectangle and oval */
public class DragObjects extends GraphicsProgram {
public void run() {
createRectangle();
createOval();
}
private void createOval(){
GOval oval = new GOval(300, 115, 100, 70);
oval.setFilled(true);
oval.setColor(Color.GREEN);
add(oval);
}
private void createRectangle(){
GRect rect = new GRect(100, 100, 150, 100);
rect.setFilled(true);
rect.setColor(Color.RED);
add(rect);
addMouseListeners();
}
/** Called on mouse press to record the coordinates of the click */
public void mousePressed(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
gobj = getElementAt(lastX, lastY);
}
/** Called on mouse drag to reposition the object */
public void mouseDragged(MouseEvent e) {
if (gobj != null) {
gobj.move(e.getX() - lastX, e.getY() - lastY);
lastX = e.getX();
lastY = e.getY();
}
}
/** Called on mouse click to move this object to the front */
public void mouseClicked(MouseEvent e) {
if (gobj != null) gobj.sendToFront();
}
/* Instance variables */
private GObject gobj; /* The object being dragged */
private double lastX; /* The last mouse X position */
private double lastY; /* The last mouse Y position */
}
It would be helpful if you would point out that the method addMouseListeners() is in the superclass, GraphicsProgram. What it does is adds the listener to the canvas, not just to the individual shape. From there, you'll need to somehow determine whether the mouseclick occurred in the rectangle or in the oval.
Or there might be a way to add the listener just to a single shape. Check the Javadoc for the GRect and GOval classes. I'm assuming those are also in one of the acm.* packages, which means they're not built in to the Java language. (This is why I recommend using an IDE like Eclipse that can automatically import each class automatically, instead of importing an entire package.)
It might also be helpful to post a link to the online lessons you're following.
I haven't looked at the source other than what you have posted. But you will need to other modify gOval and gRect or a superclass to accept a mouseListener, or in your listener do something like the following.
in the MouseClicked, MouseMoved, etc. methods. Get the point of the event, and then go through your Objects and query them to see if the point exists withing their bounds.
You would need a list of objects to loop through and then call something like gRect.containsPoint(myPoint) in this method check to see if the point exists in the shape. You will still have issues where shapes overlap, so you will need some concept of a z-axis or depth to determine which shape is on top.
You need to post the source for the addMouseListeners.
If you take a look at this post over here you might get some ideas on how listeners can work (if you post the addMouseListener source we can help with your specific question of course!)