mouseDragged not returning appropriate button down - java

How can I know the button that was pressed from within a mouseDragged event?
I'm having an issue in mouseDragged() because the received MouseEvent returns 0 for getButton(). I have no problem with the mouse location, or even detecting mouse clicks. The mouseClicked() event returns the appropriate button for getButton().
Any suggestions on how I can do this? I assume I could do a work-around using mouseClicked, or mousePressed, but I would prefer to keep this all within mouseDragged.
Thanks for your time and answers.

As pointed out in comments and other answers, SwingUtilities provides three methods for cases like this, which should work for all MouseEvents:
SwingUtilities.isLeftMouseButton(aMouseEvent);
SwingUtilities.isRightMouseButton(aMouseEvent);
SwingUtilities.isMiddleMouseButton(aMouseEvent);
As for what the problem with your approach is, the javadoc of getButton() says:
Returns which, if any, of the mouse buttons has changed state.
Since the state of the button doesn't change while it is being held down, getButton() will usually return NO_BUTTON in mouseDragged. To check the state of buttons and modifiers like Ctrl, Alt, etc. in mouseDragged, you can use getModifiersEx(). As an example, the below code checks that BUTTON1 is down but BUTTON2 is not:
int b1 = MouseEvent.BUTTON1_DOWN_MASK;
int b2 = MouseEvent.BUTTON2_DOWN_MASK;
if ((e.getModifiersEx() & (b1 | b2)) == b1) {
// ...
}

Jacob's right that getButton() doesn't get you the button by design. However, I found a cleaner solution than bit operations on getModifiersEx(), that you can also use within mouseDragged:
if (SwingUtilities.isLeftMouseButton(theMouseEvent)) {
//do something
}
Similar methods exist for the middle button and the right button.

int currentMouseButton = -1;
#Override
public void mousePressed(MouseEvent e) {
currentMouseButton = e.getButton();
}
#Override
public void mouseReleased(MouseEvent e) {
currentMouseButton = -1;
}
#Override
public void mouseDragged(MouseEvent e) {
if (currentMouseButton == 3) {
System.out.println("right button");
}
}

This could be possibly a problem of your java sandbox.
The following code works well all the time (almost, as you can see).
#Override
public void mouseDragged(MouseEvent e) {
e.getButton();
}
Please try your code on a different machine.

Related

Fire ActionEvent first

I have extended JTextField. There are multiple ActionListeners attached to my class, but I need one in particular to always fire first. Is there a way to ensure that a particular ActionEvent always first first?
Note that I do have a reference to my ActionListener. I am assuming I need to override a method, but I am not sure which one that is.
Is there a way to ensure that a particular ActionEvent always first first?
The Java spec does not guarantee the order in which events are fired.
However, I believe the default implementation is that the last ActionListener added to a component is first first.
Edit:
I use the mouse listener
Why are you using a MouseListener? What happens when the user tabs to/from the field? Don't assume mouse usage. A FocusListener will handle either keyboard or mouse activity in this case.
The problem comes into play when the user presses enter on the text field.
What happens if the user doesn't press enter and they just tab to the next field? That's what I would do.
This needs to happen before other action listners do their thing.
What other ActionListeners? A tgext field would only have a single listener.
Anyway do maybe answer your question you can effectively change the order of execution by using SwingUtilities.invokeLater(...) to place your code on the end of the Event Dispatch Thread so it executes after all other events:
public void actionPerformed(ActionEvent e)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
// add your code here
}
});
}
Again, any solution that depends on the order of events is not a good solution. The order of event could be different on different platforms.
Try to override fireActionPerformed from JTextField. Add custom ActionListener in new class and call him before call super.fireActionPerformed()
Ps: sorry for bad english.
Edit:
public class CustomTextField extends JTextField {
private List<ActionListener> listeners;
public synchronized void addPriorityActionListener(ActionListener l) {
if(l == null) {
return;
}
if(listeners == null) {
listeners = new ArrayList<>();
}
listeners.add(l);
}
public synchronized void removePriorityActionListener(ActionListener l) {
if(l == null || listeners == null) {
return;
}
listeners.remove(l);
}
protected void firePriorityActionPerformed() {
if(listeners == null) {
return;
}
ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, getText());
for(ActionListener listener: listeners) {
listener.actionPerformed(event);
}
}
#Override
protected void fireActionPerformed() {
firePriorityActionPerformed();
super.fireActionPerformed();
}
}

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.

Java Netbeans - Key Listener doesn't work

After searching on internet why it's happening and trying to change my code in any possible way that I know, it still doesn't work. Basiclly i want to make my JFrame appear when shift is hold. That's my code:
public DesktopMenu() {
initComponents();
setFocusable(true);
//Listening to the mouse movement to change position of the window
this.addMouseMotionListener(new MouseAdapter(){
#Override
public void mouseMoved(MouseEvent e){
xPos = e.getX();
yPos = e.getY();
setLocation((e.getXOnScreen()-xPos),(e.getYOnScreen()-yPos));
}
});
//This should listen to the key, when it's pressed window just appear.
this.addKeyListener(new KeyListener(){
#Override
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_SHIFT){
setVisible(true);
}else{
setVisible(false);
}
};
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
});
}
I run the window in standard Java Class with new DesktopMenu().setVisible(false); 'cause i want to make it just appear when SHIFT is pressed and hold. Thanks in advance.
If you've searched KeyListeners, you'll find that one of the most common problems (other than that they usually should be avoided with Swing applications) is that they won't work if the component that is listened to doesn't have focus. Well the problem you're having is similar but on a bigger scale: the KeyListener won't work if the application listened to doesn't have focus and isn't even visible.
In short, what you are trying to do cannot be done in core Java. Consider using another utility that can do this for you, such as AutoIt if you are running in a Windows environment.
It all depends on the details of what you're trying to do, what environment, and so on. But AutoIt can listen to global keypresses. You can tie it into your Java app by one of several ways, but the easiest is to simply send messages to each other via the standard input and output sockets. And then when AutoIt detects the correct keypress, it sends a message to the Java via ConsoleWrite(...), and the Java app responds by reading it in via, say a Scanner.
I do know that I would never use the shift key as the hotkey since that will make the user's computer completely non-functionable.

MouseListener in Java Swing sometimes not respond

I've implemented right mouse click for open menu listener on my main Jframe, it works fine except one problem. One out of 5 (give or take) clicks it not responding, this can be very annoying for the user. Here is my code:
contentPane = new JPanel();
contentPane.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3)
{
//Do Stuff
}
}
});
Can you please help me
You won't get clicks from sub-components of contentPane.
I think your problem is that you have added things to your panel. When the user clicks at regions occupied by a sub-component, that sub-component get's the click event.
Quick fix: I would recommend you to add the same mouse listener to all sub-components.
You are not "clicking"
A click is when the mouse is pressed and release really quickly. If you are not careful you might get events for (for instance) "pressed, moved, released" instead of "clicked".
Quick fix: use mouseReleased event instead.
Use this Code instead:
private MouseAdapter listener = new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
if (downer) {
downer = false;
if (new Rectangle(e.getComponent().getLocationOnScreen(), e.getComponent().getSize())
.contains(e.getLocationOnScreen())) {
downer = false;
// CODE
new Thread(new Runnable(){
public void run(){
//Your Listener code
}
}).start();
/// COde
}
}
}
boolean downer = false;
public void mousePressed(java.awt.event.MouseEvent e) {
downer = true;
}
};
This code only reacts if you press on the component and release on the component AND starts a new Thread for the custom task. This should work allways, because the AWT Thread isnt blocked with long calculations.

Categories