This is a sample of a larger program used to draw rectangles. A rectangle object is drawn on screen already. what I am attempting to do with the mousedPressed object is get the coordinates of the mouse, and compare it with that of the rectangle's (which are initially set to (100, 100, 200, 200)). The mouseDragged event should take the coordinates obtained in the mousePressed section and run code with them; however, it seems that no matter what, the coordinates are always 0 in the mouseDragged event. I added test code (as marked) to each event to simply change the color of the square when the coordinates are at a certain point. The test code in mousedPressed works just fine, but the test code in mouseDragged can never run. I have tried with many, many different values, and determined that the coordinates will always equal 0 in the mouseDragged event. If someone could help me understand why the int values are not being passed, despite referencing the same variable, I would appreciate it.
public class PointListener implements MouseListener, MouseMotionListener {
private int mousex, mousey;
//in case that a user presses using a mouse,
//record the point where it was pressed.
public void mousePressed (MouseEvent event) {
//getPoint() returns a Point object containing the x & y-coordinates
currentPoint = event.getPoint();
mousex = event.getPoint().x;
mousey = event.getPoint().y;
repaint();
if (mousex > 250) {
currentColor = Color.GREEN;
repaint();
} //The test, which can easily be triggered as expected
}
public void mouseClicked(MouseEvent event) {}
public void mouseReleased(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
public void mouseMoved(MouseEvent event) {}
public void mouseDragged(MouseEvent event) {
if (95 < mousex && mousex < 105) {
currentColor = Color.BLUE;
repaint();
}
if (mousex > 150) {
currentColor = Color.RED;
repaint();
} // The test, which can never be triggered
} //mouseDragged()
} //PointListener
Related
The code I made won't change the coordinates of the ball every time I click on it.
public class AimTrainerPanel extends JPanel implements MouseListener {
static final int WIDTH = 1300;
static final int HEIGHT = 750;
static final int SIZE = 10;
Random rand;
JLabel cd;
int x;
int y;
boolean running = false;
Timer timer;
AimTrainerPanel() {
rand = new Random();
this.setPreferredSize(new Dimension(WIDTH, HEIGHT));
this.setBackground(Color.black);
this.setFocusable(true);
this.setLayout(null);
this.addMouseListener(this);
startGame();
}
public void startGame() {
newDot();
running = true;
timer = new Timer();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
draw(g);
}
public void draw(Graphics g) {
if (running) {
g.setColor(Color.white);
g.fillOval(x, y, SIZE, SIZE);
}
}
public void newDot() {
x = rand.nextInt((int)(WIDTH/SIZE)) * SIZE;
y = rand.nextInt((int)(HEIGHT/SIZE)) * SIZE;
}
#Override
public void mouseClicked(MouseEvent e) {
int mx = e.getX();
int my = e.getY();
if (mx >= x && mx <= x + 10) {
if (my >= y && my <= y + 10) {
newDot();
}
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
The newDot() method is suppose to create new coordinates every time it is called but the ball won't change places. I don't know if it's because I misswrote something or because my what I did doesn't change the coordinates or if I'm suppose to add something.
I'm not sure what your Timer is supposed to be doing, but it doesn't appear to be a Swing Timer, and since this is a Swing GUI I'd get rid of it.
Now to the crux of your problems:
You're using mouseClicked which isn't called if the mouse moves even slightly between mouse pressed and mouse released, and so often it is better to use mousePressed or mouseReleased methods and not mouseClicked
You don't call repaint() after changing the state of your program. Swing won't know that a repaint is needed unless you suggested, and so in your mouseListener or in code called by it, you should call this method after changing GUI state. Here you can call it at the end of the newDot(...) method or in the mouse listener after you call the same method.
Your if blocks within your mouse listener appear to be quite restrictive as to where they will allow the listener to respond to a mouse click -- is it too restrictive? I don't know since I'm not familiar with your requirements, but possibly.
I am trying to figure out how to complete the assignment below
Write a method void move(Point p) for your Circle class that takes a Point and moves the circle so its center is at that point.
In the CirclePanel constructor, create a CirclesListener object and make it listen for both mouse events and mouse motion events.
Make the CirclesListener class implement the MouseMotionListener interface in addition to the MouseListener interface. This requires two steps: Note in the header that CirclesListener implements MouseMotionListener. Add bodies for the two MouseMotionListener methods, mouseDragged and mouseMoved. In mouseDragged, simply move the circle to the point returned by the getPoint method of the MouseEvent and repaint. Provide an empty body for mouseMoved.
I know what I need to do (for the most part), I just can't figure out how to do it. (New to programming). Thank you!
public class circlePanel extends JPanel {
private final int WIDTH = 600, HEIGHT = 400;
private Circle circle;
// -------------------------------------------------------------------
// Sets up this panel to listen for mouse events.
// -------------------------------------------------------------------
public circlePanel() {
addMouseListener(new CirclesListener());
setPreferredSize(new Dimension(WIDTH, HEIGHT));
}
// -------------------------------------------------------------------
// Draws the current circle, if any.
// -------------------------------------------------------------------
public void paintComponent(Graphics page) {
super.paintComponent(page);
if (circle != null)
circle.draw(page);
}
// ******************************************************************
// Represents the listener for mouse events.
// ******************************************************************
private class CirclesListener implements MouseListener, MouseMotionListener {
// ---------------------------------------------------------------
// Creates a new circle at the current location whenever the
// mouse button is pressed and repaints.
// ---------------------------------------------------------------
public void mousePressed(MouseEvent event) {
if (circle == null) {
circle = new Circle(event.getPoint());
} else if (circle.isInside(event.getPoint())) {
circle = null;
} else {
circle.move(getMousePosition());
}
repaint();
}
// -----------------------------------------------------------------
// Provide empty definitions for unused event methods.
// -----------------------------------------------------------------
public void mouseClicked(MouseEvent event) {
}
public void mouseReleased(MouseEvent event) {
}
public void mouseEntered(MouseEvent event) {
setBackground(Color.white);
}
public void mouseExited(MouseEvent event) {
setBackground(Color.blue);
}
}
}
Here is the circles class
public class Circles {
// ----------------------------------------------------------------
// Creates and displays the application frame.
// ----------------------------------------------------------------
public static void main(String[] args) {
JFrame circlesFrame = new JFrame("Circles");
circlesFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
circlesFrame.getContentPane().add(new circlePanel());
circlesFrame.pack();
circlesFrame.setVisible(true);
}
}
aannnddddd...here is the Circle class
public class Circle {
private int centerX, centerY;
private int radius;
private Color color;
static Random generator = new Random();
// ---------------------------------------------------------
// Creates a circle with center at point given, random radius and color
// -- radius 25..74
// -- color RGB value 0..16777215 (24-bit)
// ---------------------------------------------------------
public Circle(Point point) {
radius = Math.abs(generator.nextInt()) % 50 + 25;
color = new Color(Math.abs(generator.nextInt()) % 16777216);
centerX = point.x;
centerY = point.y;
}
// ---------------------------------------------------------
// Draws circle on the graphics object given
// ---------------------------------------------------------
public void draw(Graphics page) {
page.setColor(color);
page.fillOval(centerX - radius, centerY - radius, radius * 2,
radius * 2);
}
public void move(Point p) {
centerX = p.x;
centerY = p.y;
}
public boolean isInside(Point p) {
if (Math.sqrt(Math.pow(p.x - this.centerX, 2) + Math.pow(p.y -
this.centerY, 2)) < this.radius) {
return true;
} else {
return false;
}
}
}
So, basically, based on you code example, you need:
Implement the functionality of the MouseMotionListener, this will include the mouseDragged method
You need to register the CirclesListener to the circlePanel (JPanel#addMouseMotionListener)
When mouseDragged is called, you need to take the Point from the MouseEvent and call Circle#move and repaint the component
If you get stuck, best place to start is How to Write a Mouse Listener
So what I want to do is after one click is keep the mousePressed method 'on' even though im not holding it down myself. Then after another click it will turn it 'off'
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
// save coord x,y when mouse is pressed
oldX = e.getX();
oldY = e.getY();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
// coord x,y when drag mouse
currentX = e.getX();
currentY = e.getY();
if (g2 != null) {
// draw oval if g2 context not null
g2.drawOval(oldX, oldY, width, height);
g2.fillOval(oldX, oldY, width, height);
// refresh draw area to repaint
repaint();
// store current coords x,y as olds x,y
oldX = currentX;
oldY = currentY;
}
}
});
Handle the mousePressed() event. Then keep a variable in your class (lets say "clickCounter") that you increment every time the event is generated.
Then you will need to handle the mouseMoved() event to know when the mouse is moving.
So now your logic in the mouseMoved() event can check if the variable is odd, which would indicate the mouse has just been clicked:
if (clickCounter % 2 == 1)
{
add your logic here
}
Or you could keep a boolean variable that you toggle off/on for every mouse click.
I have a JComponent with JMenuBar in it. I would like to be able to drag the component by clicking on it and dragging the mouse to the desired location. I have already implemented this functionality by adding the MouseInputAdapter methods to its Border and it works great.
However, I would like to apply the same functionality on the JMenuBar, the mouseDragged() method does not get called.
Here is the menu listener (stripped version for testing):
menuBar.addMouseListener(new MouseInputAdapter() {
private Point startPos = null;
#Override
public void mousePressed(MouseEvent me) {
startPos = me.getPoint();
// works fine
System.out.println("startPos: " + startPos.toString());
}
#Override
public void mouseDragged(MouseEvent me) {
// this does not get called...
System.out.println("dragging.............");
}
});
I dont think that this is the problem, but here is the Listener used for the whole component. Could these two listeners somehow collide? I tried removingthis listener but it did not solve anything:
// this works with the border
this.addMouseListener(resizeListener);
MouseInputListener resizeListener = new MouseInputAdapter() {
#Override
public void mouseEntered(MouseEvent me) {
// put this widget on top when mouse moves across it
putOnTop();
}
#Override
public void mouseMoved(MouseEvent me) {
// put this widget on top when mouse moves across it
putOnTop();
WidgetBorder border = (WidgetBorder) getBorder();
setCursor(Cursor.getPredefinedCursor(border.getResizeCursor(me)));
}
#Override
public void mouseExited(MouseEvent mouseEvent) {
setCursor(Cursor.getDefaultCursor());
}
private int cursor;
private Point startPos = null;
#Override
public void mousePressed(MouseEvent me) {
WidgetBorder border = (WidgetBorder) getBorder();
cursor = border.getResizeCursor(me);
startPos = me.getPoint();
}
#Override
public void mouseDragged(MouseEvent me) {
if (startPos != null) {
// widget cant be resized under its minimum size
if (widget.getWidth() < WidgetConstants.MIN_WIDTH) {
widget.setBounds(widget.getX(), widget.getY(), WidgetConstants.MIN_WIDTH + 1, widget.getHeight());
return;
}
if (widget.getHeight() < WidgetConstants.MIN_HEIGHT) {
widget.setBounds(widget.getX(), widget.getY(), widget.getWidth(), WidgetConstants.MIN_HEIGHT + 1);
return;
}
int dx = me.getX() - startPos.x;
int dy = me.getY() - startPos.y;
switch (cursor) {
case Cursor.SE_RESIZE_CURSOR:
setBounds(getX(), getY(), getWidth() + dx, getHeight() + dy);
startPos = me.getPoint();
repaintParent();
break;
case Cursor.MOVE_CURSOR:
Rectangle bounds = getBounds();
bounds.translate(dx, dy);
setBounds(bounds);
repaintParent();
}
// cursor shouldn't change while dragging
setCursor(Cursor.getPredefinedCursor(cursor));
}
}
#Override
public void mouseReleased(MouseEvent mouseEvent) {
startPos = null;
}
};
What am I missing here? Thanks for any help...
MouseInputAdapter implements many interfaces (e.g. MouseListener, MouseMotionListener etc.).
You have to add this with multiple methods, e.g. with Component.addMouseListener() if you want mouseClicked() to be called, Component.addMouseMotionListener() if you want mouseDragged() to be called and Component.addWheelListener() if you want mouseWheelMoved() to be called.
You can pass the same reference of course, but you have to add your listener implementation with multiple methods. The reason is because for example Component.addMouseListener() expects a MouseListener interface, and will only call the methods defined in the MouseListener interface, even if you pass an object that implements other methods from other interfaces.
I put a aintComponent() method in a JPanel. This method draws a tree using Graphics.drawLine().
I put a JButton from which a Listener is used to zoom on this tree. At the end I use the repaint() method, and my tree is repainted bigger, so no problem there.
// Add Listeners on Zooming buttons
bPlus.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent event){
Node.setZoom(1);
repaint();
}
});
However, I used a MouseMotionListener for moving this tree inside its JPanel.
Then when I call repaint(), it does not erase the previous printed trees, so I end up with duplicated trees.
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
if(mouseHolded) {
x += e.getX() - mouseX;
mouseX = e.getX();
y += e.getY() - mouseY;
mouseY = e.getY();
repaint(); // <===
}
}
}
);
What am I doing wrong ? While the previous trees will be erased when I use the repaint() for zooming, why wont it do so when I move the tree?