Java Event listeners (mouse and keyboard) - java

So everything in my program works, except for the mouse and the keyboard listeners.
I've got a couple actionListeners working on Jbuttons that do exactly what I'm trying to do here, but the assignment says it has to work with all three.
So I would like to know why it compiles, but doesn't work. Am I doing something wrong?
panel.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_UP){
shape.addSides();
}
if(e.getKeyCode() == KeyEvent.VK_DOWN){
shape.subSides();
}
}
#Override
public void keyReleased(KeyEvent e) {
}
}
);
panel.addMouseListener(new MouseListener(){
#Override
public void mouseEntered(MouseEvent e){
if(e.getButton() == MouseEvent.BUTTON1){
shape.addSides();
}
if(e.getButton() == MouseEvent.BUTTON3){
shape.subSides();
}
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
);

Regarding KeyListener: it won't work unless the listened-to component is focusable and has focus. So you will want to call setFocusable(true) and requestFocusInWindow() on your JPanel. As for the MouseListener -- something else may be taking the mouse event and preventing it from reaching your JPanel. To debug this you need to post a minimal, compilable, runnable example program.
Also regarding your MouseListener, you're checking getButton() in a mouseEntered event which makes no sense. The buttons are not involved in this type of event. Are you instead meaning to check mouseDragged(...) of a MouseMotionListener?

Related

How to assign a method to a button when pressed or released with ActionListener in Java?

I am new to coding GUIs in Java and I am trying to just print a message on the terminal when a button is pressed and another one when it is released.
This is what I have for a regular button pressing.
leftButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("Pressed");
}
});
I did this with the help of IntelliJ IDEA. I want to make the button send a message when pressed and a different thing when released.
You can just add a simple MouseAdapter, like this:
MouseAdapter ma = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
System.out.println("Pressed");
}
public void mouseReleased(MouseEvent e) {
System.out.println("Released");
}
};
leftButton.addMouseListener(ma);
frame.add(button);
This will detect when it is the mouse is pressed on the button or released on the button.
If you want, you can also add a mouseClicked() method, mouseExited(), mouseEntered(), mouseMoved(), and (many) more methods in your MouseAdapter. Check out this JavaDoc
Use custom class and use it
leftButton.getModel().addChangeListener(new BtnCusttomListener());
private class BtnCusttomListener implements ChangeListener {
private boolean pressed = false; // holds the last pressed state of the button
#Override
public void stateChanged(ChangeEvent e) {
ButtonModel Buttonmodel = (ButtonModel) e.getSource();
// if the current state differs from the previous state
if (model.isPressed() != pressed) {
String text = "Button pressed: " + model.isPressed() + "\n";
textArea.append(text);
pressed = model.isPressed();
}
}
}
You can use a MouseListener instead:
leftButton.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
// The mouse button was pressed and released
}
#Override
public void mousePressed(MouseEvent e) {
// The mouse button was pressed
}
#Override
public void mouseReleased(MouseEvent e) {
// The mouse button was released
}
#Override
public void mouseEntered(MouseEvent e) {
// The cursor entered the bounds of the button (i.e. hovering)
}
#Override
public void mouseExited(MouseEvent e) {
// The cursor exited the bounds of the button
}
});

How do I simplify MouseListener so that I don't have all these unused methods?

Below I have the following code, so that when someone clicks on the "Close", the window will close. Below that is another exit button on the same menu bar, simply for redundancy (it'll be changed later to be something else, but the point stands as follows). My question is, is there any way to make this more simplistic? I mean there are four unused methods for every menu, and I'm going to need to do a few more. Any ideas on how to fix this?
closeFile.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent arg0) {
System.exit(0);
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
});
exit.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent arg0) {
System.exit(0);
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
});
Also, ActionListener wouldn't work for me, so I can't use that (don't believe I'm supposed to either).
Use a MouseAdapter and override the methods that you want.
closeFile.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent arg0) {
System.exit(0);
}
});
closeFile.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
//your code
}
});
Note: You dont have to write 'implements MouseListener' during class definition.
For more information, search for adapter classes, more specifically for MouseAdapter class.

How to set up mouse and keyboard input

Hi I'm trying to program a game using java. This is my first time using java, I am used to C#. In C# I would call Mouse.getLocation() and create a rect using the mouses location. Then by using if(Mouse.Left().toString() == "Pressed") I would then check if the mouse rect intersected with any other objects and act accordingly.
I've noticed in java you aren't provided with methods like these. So I was wondering, is the best way to approach mouse input simply to add listeners on all my clickable objects? I understand listeners and have a good idea how to use them but I was just wanting to check if there are more efficient ways to handle input or ways geared more towards what I'm most conformable with.
let your frame implement the MouseListener interface
implement all abstract methods, but in your case it is probably the mouseClicked event
identify if the button clicked is a left click, using the SwingUtilities class
if it is a left click, then set the x and y, which is the location of your click relative to the frame, not the screen.
public class MouseListeningObject extends JFrame implements MouseListener {
int x, y;
public MouseListeningObject () {
addMouseListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e)){
x = e.getX();
y = e.getY();
}
}
#Override
public void mousePressed(MouseEvent e) {
// Some codes here
}
#Override
public void mouseReleased(MouseEvent e) {
// Some codes here
}
#Override
public void mouseEntered(MouseEvent e) {
// Some codes here
}
#Override
public void mouseExited(MouseEvent e) {
// Some codes here
}
}
You want your frame to implement MouseListener then add it in the constructor.
class MyFrame extends JFrame implements MouseListener {
MyFrame() {
addMouseListener(this);
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
}

addKeyListener to Jpanel

I want to addKeyListener to a JPanel but when I press two keys at the same time, just one of them executes. What is the solution to this problem - press two keys at the same time?
I have a class that extends JPanel
this.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {
upPlayer2();
} if (e.getKeyCode() == KeyEvent.VK_A ){
leftPlayer2();
}
}
});
Thanks.
Don't use a KeyListener. Swing was designed to be used with Key Bindings.
See Motion Using the Keyboard for more information and solutions.

Passing events to parent

I'd like to create an app where some events are supposed to be handled as if they were delivered to parent containers. For example I've got a JPanel which contains JLabel. The top JPanel implements mousepress and dragging right now. What do I need to do, in order to make the events look like they arrived to JPanel instead of the label itself. (changing source object is important)
Is there some better solution than actually implementing the events and replicating them in the parent? (this would get tedious after some objects with >5 children).
At your event listener, you can dispatch the event to the parent component.
Being myEvent the event handling function argument:
Component source=(Component)myEvent.getSource();
source.getParent().dispatchEvent(myEvent);
But this solution implies creating a new EventListener for each element to add.
So, you could create a single event handler and reuse it, adding it to all the chosen children, like this:
final Container parent=this; //we are a the parent container creation code
MouseListener myCommonListener=new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
parent.dispatchEvent(e);
}
#Override
public void mouseEntered(MouseEvent e) {
parent.dispatchEvent(e);
}
#Override
public void mouseExited(MouseEvent e) {
parent.dispatchEvent(e);
}
#Override
public void mousePressed(MouseEvent e) {
parent.dispatchEvent(e);
}
#Override
public void mouseReleased(MouseEvent e) {
parent.dispatchEvent(e);
}
};
JLabel label=new JLabel("This is the first Label");
label.addMouseListener(myCommonListener);
JLabel label2=new JLabel("This is the second Label");
label2.addMouseListener(myCommonListener);
//... and so on
You should convert event before dispatching it to the parent. Conversion includes coordinates translation to parent-relative.
public class RedispatchingMouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener{
public void mouseClicked(MouseEvent e) {
redispatchToParent(e);
}
public void mousePressed(MouseEvent e) {
redispatchToParent(e);
}
public void mouseReleased(MouseEvent e) {
redispatchToParent(e);
}
public void mouseEntered(MouseEvent e) {
redispatchToParent(e);
}
public void mouseExited(MouseEvent e) {
redispatchToParent(e);
}
public void mouseWheelMoved(MouseWheelEvent e){
redispatchToParent(e);
}
public void mouseDragged(MouseEvent e){
redispatchToParent(e);
}
public void mouseMoved(MouseEvent e) {
redispatchToParent(e);
}
private void redispatchToParent(MouseEvent e){
Component source = (Component) e.getSource();
MouseEvent parentEvent = SwingUtilities.convertMouseEvent(source, e, source.getParent());
source.getParent().dispatchEvent(parentEvent);
}
}
Mouse events are automatically targeted to the deepest component that has mouse listeners.
Because of this, to achieve your goal, you can simply remove all mouse listeners on the JLabel and it will never get picked as the target for mouse events.
The following code will disable mouse listeners on the given components and their children recursively:
public static void disableMouseForComponent(Component... components) {
for (Component c : components) {
if (c instanceof Container) {
disableMouseForComponent(((Container) c).getComponents());
}
for (MouseListener l : c.getMouseListeners()) {
c.removeMouseListener(l);
}
for (MouseMotionListener l : c.getMouseMotionListeners()) {
c.removeMouseMotionListener(l);
}
}
}

Categories