mouse event handling code doesn't work

Why doesn't this code work, and what do I need to do to fix it?
What I want to happen is when the user right clicks, the popup menu should come up.  When the user left clicks, plyKey() should be called.  What's happening is when the user right clicks, the menu comes up, but plyKey() also executes.  And the method executes with a left click also.

public class PblKbd
   extends Canvas
   implements ActionListener
{  
...

   public PblKbd(...,...,...,...)
   {
      ...

         // Listen for mouse clicks.
         this.addMouseListener(new MouseAdapter(){});

         public void processMouseEvent(MouseEvent me)
         {
             int x = me.getX();
             int y = me.getY();
       
       
             if (true == me.isPopupTrigger())
             {
                 popMnu.show(this,x,y);
              }
              if (false == me.isPopupTrigger())
              {
                  plyKey(x,y);
               }
               me.consume();
         }

      ...

     }
...
}
castelloAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jan LouwerensSoftware EngineerCommented:
your problem is in the following line:

 this.addMouseListener(new MouseAdapter(){});

The MouseAdapter class is only a convenience class the implements all the methods in the MouseListener interface. However, all these methods do nothing by default. It is meant to be extended by a user class that only wants to implement one or a small number of methods defined by the MouseListener interface.
In your case, you will want to define your class like:

public class PblKbd extende Canvas implements MouseListener
{
....
(implement all methods of the MouseLintener interface within your class)
}
0
castelloAuthor Commented:
Now, I get no response from a left or right click.  Nothing happens.

I changed
implements ActionListener
to
implements ActionListener, MouseListener

and I got rid of

this.addMouseListener(new MouseAdapter(){});
and the processMouseEvent() method

and added

public void mousePressed(MouseEvent e)
    {
       int x = e.getX();
       int y = e.getY();
       
       
       if (true == e.isPopupTrigger())
       {
          popMnu.show(this,x,y);
       }
       if (false == e.isPopupTrigger())
       {
          plyKey(x,y);
       }
       e.consume();  
    }
    public void mouseClicked(MouseEvent e)
    {
    }
    public void mouseEntered(MouseEvent e)
    {
    }
    public void mouseExited(MouseEvent e)
    {
    }
    public void mouseReleased(MouseEvent e)
    {
    }
0
castelloAuthor Commented:
Now, I get no response from a left or right click.  Nothing happens.

I changed
implements ActionListener
to
implements ActionListener, MouseListener

and I got rid of

this.addMouseListener(new MouseAdapter(){});
and the processMouseEvent() method

and added

public void mousePressed(MouseEvent e)
    {
       int x = e.getX();
       int y = e.getY();
       
       
       if (true == e.isPopupTrigger())
       {
          popMnu.show(this,x,y);
       }
       if (false == e.isPopupTrigger())
       {
          plyKey(x,y);
       }
       e.consume();  
    }
    public void mouseClicked(MouseEvent e)
    {
    }
    public void mouseEntered(MouseEvent e)
    {
    }
    public void mouseExited(MouseEvent e)
    {
    }
    public void mouseReleased(MouseEvent e)
    {
    }
0
CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

OviCommented:
Try first to print to console the coordinates of the mouse, to see if you pass by there.
add this after you read the coordinates :

System.out.println("x : "+x+"\ny : "+y);
0
vladi21Commented:
7.5 Scribbling with Inner Classes
The Java 1.1 event model was designed to work well with another new Java 1.1 feature: inner classes. Example 7.3 shows what the applet looks like when the event listeners are implemented as anonymous inner classes. Note how succinct this representation is. This is perhaps the most common way to use the Java 1.1 event model, so you'll probably see a lot of code that looks like this. In this case, our simple applet is nothing but event-handling code, so this version of it consists almost entirely of anonymous class definitions.

Note that we've added a feature to the applet. It now includes a Clear button. An ActionListener object is registered with the button; it clears the scribble when the appropriate event occurs.

Example 7.3: Scribble: Using Inner Classes

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Scribble3 extends Applet {
  int last_x, last_y;
  public void init() {
    // Define, instantiate, and register a MouseListener object.
    this.addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        last_x = e.getX();
        last_y = e.getY();
      }
    });
    // Define, instantiate, and register a MouseMotionListener object.
    this.addMouseMotionListener(new MouseMotionAdapter() {
      public void mouseDragged(MouseEvent e) {
        Graphics g = getGraphics();
        int x = e.getX(), y = e.getY();
        g.setColor(Color.black);
        g.drawLine(last_x, last_y, x, y);
        last_x = x; last_y = y;
      }
    });
    // Create a clear button.
    Button b = new Button("Clear");
    // Define, instantiate, and register a listener to handle button presses.
    b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {  // clear the scribble
        Graphics g = getGraphics();
        g.setColor(getBackground());
        g.fillRect(0, 0, getSize().width, getSize().height);
      }
    });
    // And add the button to the applet.
    this.add(b);
  }
}

0
castelloAuthor Commented:
Ovi, I know that I get the right coordinates of the mouse.  I didn't mention (or post the code) but I have some debugging code in the applet that displays x and y.  Actually, for now, this particular code is taking the place of plyKey(), so when plyKey is called, x,y is displayed instead.  I did this because I wanted to debug from my appletviewer at home and not keep going to my web account online - plyKey() plays .au files.

vladi21, your suggestion is what I started with.  But it's not working because I'm using the show() method for the popup, which takes the component to display in as an argument.  When I use
popMnu.show(this,e.getX(),e.getY());
I get a compile error
Incompatible type for method.  Can't convert PblKbd.1 to java.awt.Component.
because 'this' refers to the annonymous inner class MouseListener. I was trying to figure out how to refer to the PblKbd as the component to display the popup in, and that's what led me to my original post. I was using a method outside the constructor so that I would have access to PblKbd via 'this'. (I see now that when I typed my original post I mistakenly put the processing method in the constructor.)

How to 1) refer to PblKbd in show() in an AIC, or 2) do the mouse listening using the interface and a method outside the constructor is what I need.

Here's the code that generated the error:

this.addMouseListener(new MouseAdapter(){
         public void mousePressed(MouseEvent e){
            int x = e.getX();
            int y = e.getY();
            if (true == e.isPopupTrigger())
            {
               popMnu.show(this,x,y);          
            }
            else
            {
               plyKey(x,y);
            }
            e.consume();
         }
});
0
vladi21Commented:
try
popMnu.show(PblKbd.this,x,y);          
           
0
JodCommented:
If I have understood correctly and you want to get a link back out to the outer class that has created your inner class then you need to know how an inner class is connected to it's outer class "container":

********************

Referring to the outer class object

If you need to produce the handle to the outer class object, you name the outer class followed by a dot and this. For example, in the class Sequence.SSelector, any of its methods can produce the stored handle to the outer class Sequence by saying Sequence.this. The resulting handle is automatically the correct type. (This is known and checked at compile time, so there is no run-time overhead.)

Sometimes you want to tell some other object to create an object of one of its inner classes. To do this you must provide a handle to the other outer class object in the new expression, like this:

//: Parcel11.java
// Creating inner classes
package c07.parcel11;

public class Parcel11 {
  class Contents {
    private int i = 11;
    public int value() { return i; }
  }
  class Destination {
    private String label;
    Destination(String whereTo) {
      label = whereTo;
    }
    String readLabel() { return label; }
  }
  public static void main(String[] args) {
    Parcel11 p = new Parcel11();
    // Must use instance of outer class
    // to create an instances of the inner class:
    Parcel11.Contents c = p.new Contents();
    Parcel11.Destination d =
      p.new Destination("Tanzania");
  }
} ///:~

To create an object of the inner class directly, you don’t follow the same form and refer to the outer class name Parcel11 as you might expect, but instead you must use an object of the outer class to make an object of the inner class:

Parcel11.Contents c = p.new Contents();


Thus, it’s not possible to create an object of the inner class unless you already have an object of the outer class. This is because the object of the inner class is quietly connected to the object of the outer class that it was made from. However, if you make a static inner class, then it doesn’t need a handle to the outer class object.

****************

So in your case, to get your link back to the PblKbd outer class you can do this:

this.addMouseListener(new MouseAdapter(){
         public void mousePressed(MouseEvent e){
            int x = e.getX();
            int y = e.getY();
            if (true == e.isPopupTrigger())
            {
               popMnu.show(PblKbd.this,x,y);          
            }
            else
            {
               plyKey(x,y);
            }
            e.consume();
         }
});


Thus, PblKbd.this gets you the reference to the outer class object that you need for the menu call.

Is this what you need to know?

0
vladi21Commented:
so u can submit answer
0
castelloAuthor Commented:
I tried
popMnu.show(PblKbd.this,x,y);
It compiled, but when I right click, plyKey() executes.
When I left click, plyKey() executes.
The menu doesn't come up when I right click.

What seems most odd is that plyKey() executes no matter which key is clicked even though it's part of an 'else'.......
0
vladi21Commented:
this.addMouseListener(new MouseAdapter(){
         public void mousePressed(MouseEvent e){
            int x = e.getX();
            int y = e.getY();
System.out.println(e.isPopupTrigger());
            if (true == e.isPopupTrigger())
            {
               popMnu.show(PblKbd.this,x,y);            
            }
            else
            {
               plyKey(x,y);
            }
            e.consume();
         }
});

post the result

0
vladi21Commented:
ur platform/OS ?
0
JodCommented:
I think the problem is in your check here, then:

if (true == e.isPopupTrigger())

Looks like this is always false. try what vladi suggests to see what value

e.isPopupTrigger()

has.

Even better, perhaps you should check for the right mouse button specifically. You can do this using the button mask, eg:

  if ( ( e.getModifiers() & InputEvent.BUTTON3_MASK ) == InputEvent.BUTTON3_MASK )
    System.out.println("You pressed the right mouse button!")

So in your case you can do:


this.addMouseListener(new MouseAdapter(){
         public void mousePressed(MouseEvent e) {
            int x = e.getX();
            int y = e.getY();
            System.out.println(e.isPopupTrigger());

            // this checks for the right mouse button regardless of ispopuptrigger
            if ( ( e.getModifiers() & InputEvent.BUTTON3_MASK ) == InputEvent.BUTTON3_MASK) {
               popMnu.show(PblKbd.this,x,y);            
            } else {
               plyKey(x,y);
            }
            e.consume();
         }
});
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
castelloAuthor Commented:
Ok, it says the right button is not the popup trigger, which is wierd, because when I was using slightly different code - posted above - a right click did cause the menu to pop up:


this.addMouseListener(new MouseAdapter(){});

                               public void processMouseEvent(MouseEvent me)
                               {
                                   int x = me.getX();
                                   int y = me.getY();
                             
                             
                                   if (true == me.isPopupTrigger())
                                   {
                                       popMnu.show(this,x,y);
                                    }
                                    if (false == me.isPopupTrigger())
                                    {
                                        plyKey(x,y);
                                     }
                                     me.consume();
                               }

Now I'm wondering how differently the mouse might act with different users on the webpage........

I'm using Windows 98 and the appletviewer from JDK1.1.8
and a Cirque touch pad, if that makes any difference.

So now, how do I figure put what the popup trigger is?
0
castelloAuthor Commented:
Oh.... wait a minute, I'm awake.
This solves the problem.  Thank you.

 if ( ( e.getModifiers() & InputEvent.BUTTON3_MASK ) ==
                      InputEvent.BUTTON3_MASK) {
                                     popMnu.show(PblKbd.this,x,y);              
                                  } else {
                                     plyKey(x,y);
                                  }

0
Jan LouwerensSoftware EngineerCommented:
be careful using BUTTON3_MASK

some platforms (like McIntosh) don't have a right button (at least in the general case), so you limit the user base of your app that way
0
vladi21Commented:
....
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.