Removing MouseListener when something happens - java

In the game that I'm currently making I have three different mousePressed methods, one for single fire, one for automatic fire and one for melee attacks. Because the one for automatic fire uses a swing Timer I can override it in the other mousePressed methods by using timer.stop(); in them.
But the single fire mousePressed calls the fire() method directly so I can't override it in any way from the other mousePressed. The code below shows the method for the fireing (bullet is a ArrayList).
public void fire(){
if(!power.getChainsaw()){
bullet.add(new Bullet(x, y));
}
}
When the player gets a melee weapon I therefor need to remove the MouseListener for the single fireing. I have tried the code below but it didn't work.
removeMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
player.mousePressed2(e);
}
)};
I add the single fire and melee MouseListener in the exact same way as this. This is hwo the acctual mousePressed methods lok like.
public void mousePressed2(MouseEvent e){
if(SwingUtilities.isLeftMouseButton(e)){
timer.stop();
fire();
}
}
public void mousePressed3(MouseEvent e){
if(SwingUtilities.isLeftMouseButton(e)){
timer.stop();
}
}
mousePressed2 is the single fire method and mousePressed3 is the melee method

removeMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
player.mousePressed2(e);
}
)};
Look at what you are doing here. You are removing an instance of MouseAdapter created in place. This means that a new instance of mouse adapter will be created and then removed, but because the specific listener instance is not binded to any button, nothing will happen.
Pass the correct listener to the removeMouseListener method and it will work.
MouseAdapter myListener = new MouseAdapter() {
public void mousePressed(MouseEvent e){
player.mousePressed2(e);
}
};
someButton.addMouseListener(myListener);
// then when you want to remove it, use the same referenece.
someButton.removeMouseListener(myListener);

Related

Java 2D Game - MouseClicked & MouseMoved methods

Problem
I have two MouseEvent handlers (mouseClicked and mouseMoved), and they both work, but only separately.
If I click the mouse, the action gets processed fine. (bullet gets fired)
If I move the mouse, the action gets processed fine. (the sprite moves)
The problem occurs when I do both actions at the same time (moving mouse whilst clicking). The mouseMoved event goes through fine, but the mouseClicked event doesn't get called.
The below code is in my Game class constructor, which is extending JPanel.
this.addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e){
//This creates a new bullet, and adds to an array to get drawn.
bullet = new Bullet(105, e.getY()+5, bulletTexture);
bulletsOnScreen.add(bullet);
e.consume();
}
});
this.addMouseMotionListener(new MouseAdapter(){
#Override
public void mouseMoved(MouseEvent e){
//This increments the sprites position on the screen.
player.setYPosition(e.getY()-50);
e.consume();
};
});
What I've tried
I have tried using SwingWorker objects to run the mouseMoved in a background thread, but the results are the same (bullet doesn't fire).
#Override
public void mouseMoved(MouseEvent e){
SwingWorker myWorker = new SwingWorker<Void, Void>(){
#Override
protected Void doInBackground() throws Exception {
player.setYPosition(e.getY()-50);
e.consume();
return null;
}
};
myWorker.execute();
};
I have also tried to check for a mouseClick within the mouseMoved method, again to no success.
public void mouseMoved(MouseEvent e){
if(e.getButton() == MouseEvent.MOUSE_CLICKED){
//Create bullet and add to array (but this never gets called)
}
player.setYPosition(e.getY()-50);
e.consume();
};
If anyone has any ideas or pointers, it would be great thanks.
Here's some code I cooked to have full working example of behavior you described.
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
System.out.println("Pressed");
}
#Override
public void mouseClicked(MouseEvent e) {
System.exit(1);
}
});
frame.addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
System.out.println("Moved");
}
});
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(100, 100);
frame.setVisible(true);
}
});
}
}
As you will see when moving around frame you will get lots of "Moved" events.
Most interesting for you will be part that when you press mouse button down you will see "Pressed". If you release without moving there will be clicked event ( app will exit ). Closing app might be a bit extreme but we have to be sure that we don't miss that event.
But when you press down mouse button, hold it and move, you won't see any move event triggered. Then, when you release, you won't get clicked event fired either.
I'm not sure about this part but it looks like mouseClicked will be triggered only if mousePressed and mouseReleased event occur one after another.
In your game, when you click and move your mouse at the same time you basically do
mousePressed -> mouseMoved -> mouseReleased
but this doesn't fire mouseClicked as a result.
My advice on that would be that you handle mousePressed instead of mouseClicked or try to adapt MouseAdapter#mouseDragged method to your needs.

Gridlayout and mouse listeners

hi i am trying to build a grid-layout GUI with mouse listener. SO when a particular cell is clicked in a grid ,information would be displayed. I don't know where to start, any help would be good
thankyou
I believe you have a class that inherits from JPanel or JFrame and there is whole GUI in it. Then, this class should implement mouseListener. Then your class should have similar code:
#override
public void mouseClicked(MouseEvent e){}
#override
public void mousePressed(MouseEvent e){}
#override
public void mouseEntered(MouseEvent e){}
#override
public void mouseReleased(MouseEvent e){
/*This method is being called when you release your click. It's better
then mouseClicked because mouseClicked is only called when you press
and release on the same pixel or Object (not sure about it)
*/
}
#override
public void mouseExiteded(MouseEvent e){}
In each method you can get source of
MouseEvent e
using
Object source = e.getSource();
if (source == button1){
//Do sth
}if (source == button2){
//Do sth else
}if (source == radioButton1){
//Do whatever you want
}
Then you have reference to the source, so you can modify what you want.
In your gridlayout, set all grids with some Component such as Button or Label. You can set listeners on the components added and display information when a component is clicked
To use properly a gridbaglayout, you should first work on the gridbagconstraints. Then, you should use the ActionListener interface to handle the mouse clicks. If the cells are of the type Labels, you coud hide the text by using myLabel.setText("") and putting the text by using myLabel.setText("information to display"). If you need more help, just ask :D and +1 if it helps ^^

Adding MouseListeners for JToolBar (events are consumed?)

When adding a MouseListener to a JToolBar,
jToolbar.addMouseListener(new MouseInputAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
log.debug(e.getPoint());
}
});
The event only fires when clicked outside the JToolBar's gripper.
If I override BasicToolBarUI's createDockingListener():
#Override
protected MouseInputListener createDockingListener() {
return new MouseInputAdapter() {
#Override
public void mousePressed(MouseEvent evt) {
log.debug(e.getPoint());
}
}
}
The event will fire when clicked on the gripper.
So my question is, why? Is the MouseEvent consumed in the dockingListener? But I don't see any code that consumes the event.
The MouseEvent is being automatically consumed by the Container at a number of points for a number of different reasons (some relating to how the native peer needs to deal with the event)...
Most notably in the private method Container#processMouseEvent, but it could be consumed before then
This basically means, when you attach a MouseListener to any component, it will consume all mouse events going to any component (or part thereof) that it resides above.
Think of mouse events like rain. When a raindrop hits something, it stops.

Can you use an Adapter inside of a Listener class?

I was wondering if you can use an adapter, say a MouseAdapter inside of a class that implements MouseListener.
I know I can use the Adapter as an anonymous Listener
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
panel.setBackground(Color.BLACK);
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
panel.setBackground(Color.WHITE);
repaint();
}
});
But I was wondering if I can define a separate Listener class without having to override all the other abstract methods, like Below
private class myListener implements MouseListener {
#Override
public void mousePressed(MouseEvent e) {
panel.setBackground(Color.BLACK);
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
panel.setBackground(Color.WHITE);
repaint();
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
Sure you can, because:
public abstract class MouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener
It does implement MouseListener.
from http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/awt/event/MouseAdapter.java :
An abstract adapter class for receiving mouse events. The methods in this class are empty. This class exists as convenience for creating listener objects.
Mouse events let you track when a mouse is pressed, released, clicked, moved, dragged, when it enters a component, when it exits and when a mouse wheel is moved.
Extend this class to create a MouseEvent (including drag and motion events) or/and MouseWheelEvent listener and override the methods for the events of interest. (If you implement the MouseListener, MouseMotionListener interface, you have to define all of the methods in it. This abstract class defines null methods for them all, so you can only have to define methods for events you care about.)
Create a listener object using the extended class and then register it with a component using the component's addMouseListener addMouseMotionListener, addMouseWheelListener methods. The relevant method in the listener object is invoked and the MouseEvent or MouseWheelEvent is passed to it in following cases:
when a mouse button is pressed, released, or clicked (pressed and
released)
when the mouse cursor enters or exits the component
when the mouse wheel rotated, or mouse moved or dragged
EDIT:
If your application only needs to know whether the mouse is pressed or released over a component, the other three methods will be empty and ignored. Those methods are unnecessary code. The adapter classes can help reduce the amount of code you must write when your application needs only a small subset of all interface methods. Each adapter class fully implements its associated interface (or interfaces). Then, if you want a listener for a subset of associated methods, you just have to provide that subset. No empty stubs required. Here is just such an adapter for the required MouseListener previously described.
MouseListener mouseListener = new MouseAdapter() {
public void mousePressed(MouseEvent mouseEvent) {
System.out.println("I'm pressed: " + mouseEvent);
}
public void mouseReleased(MouseEvent mouseEvent) {
System.out.println("I'm released: " + mouseEvent);
}
};
https://blogs.oracle.com/CoreJavaTechTips/entry/listeners_vs_adapters

Adding MouseMotionListeners

I currently have an abstract class which extends JComponent. In this class I have defined a method as follows:
public void makeMouseOverListener(){
System.out.println("Inside make mouseover...");
MouseMotionListener ret = new MouseMotionListener(){
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
System.out.println("Mouse Moved");
}
};
this.addMouseMotionListener(ret);
}
I extend this abstract class with a few other objects, and in the constructors of each of those objects I call this method. I always see the first println, but the "Mouse Moved" line never shows up in my console. I also tried directly creating this MouseMotionListener in each constructor, but with the same results. So ultimately my question is, How can I ensure that I get a working motion listener into my objects? Thank you in advance!
The code inside of the new MouseMotionListener( code ) it seems like this ..
**
MouseMotionListener ret = new MouseMotionListener(
public void mouseDragged(MouseEvent e) {
}
public void mouseMoved(MouseEvent e) {
System.out.println("Mouse Moved");
}
});
**
If you're invoking makeMouseOverListener in the constructor of your custom components, then its very likely that the mouse position is never positioned over the component itself. Ensure that the dimension of the component is great than 0 x 0. This can be achieved by using a layout manager. e.g. position the component at BorderLayout.CENTER location.

Categories