In my JFrame I have this listener:
this.addKeyListener(new KeyAdapter(){
#Override
public void keyPressed(KeyEvent arg0) {
//do stuff
}
});
This has been working fine until about 10 minutes ago. Now when I press a key, keyPressed() never even gets called. I tested this with eclipse debugger.
I have no idea what happened. Any ideas?
EDIT #1: This is also happening with a button that I have set up. the action listener does not recognize when the button is clicked.
EDIT #2: Ok So I was able to narrow it down. I have a JFrame, this frame has a main panel and also 2 action listeners (keyListener, the problematic one, and a mouse click listener, working fine). The main panel has two subpanels a and b. panel a has 2 buttons, one is not set up yet. It seems that these buttons are somehow conflicting with the keylistener making it so the key listener and buttons do not work. either way the mouse click listener still works.
Edit #3: Ok here is some simplified code:
The button is working, but the keyListener is not. I am hearing about focus a lot, if this is the problem how can I fix it?
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ListenerTest extends JFrame {
private JPanel mainPanel;
private JPanel panelA;
private JPanel panelB;
private JButton buttonA;
private JButton buttonB;
public ListenerTest() {
mainPanel = new JPanel();
panelA = new JPanel();
panelB = new JPanel();
buttonA = new JButton("Button A");
buttonB = new JButton("Button B");
this.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent arg0) {
System.out.println(arg0.getKeyChar());
}
});
this.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
System.out.println(e.getX() + ", " + e.getY());
}
});
buttonA.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Button A pressed!");
}
});
panelA.add(buttonA);
panelA.add(buttonB);
mainPanel.add(panelA);
mainPanel.add(panelB);
this.add(mainPanel);
this.setSize(300, 300);
this.setVisible(true);
}
public static void main(String args[]) {
new ListenerTest();
}
}
When you add an action for a specific key (for example: F2) to panelA, this seems to work:
public ListenerTest() {
// Create components...
panelA.getActionMap().put("saveAction", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("F2");
}
});
//panelA.getInputMap().put(KeyStroke.getKeyStroke("F2"), "saveAction");
panelA.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke("F2"), "saveAction");
//this.addKeyListener(new KeyAdapter() {
//mainPanel.addKeyListener(new KeyAdapter() {
panelA.addKeyListener(new KeyAdapter() {
//buttonA.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent arg0) {
System.out.println("Panel A: " + arg0.getKeyChar());
}
});
// Rest of the code...
}
Adding the action also seems to have a side effect: the KeyListener seems to work again for panelA. The focus no longer goes to one of the buttons by default.
Note: when using panelA.getInputMap(), the key action only works when the buttons do not have the focus. Use panelA.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) to make sure the action works when one of the buttons has the focus.
Related
I am trying to develop a main menu for a game in java, but my JMenuItems wouldn't listen to the KeyEvents and I don't understand why. Note that I don't want to set any JMenuBars nor JMenus as this program is intended to be a game used with screen readers, so I don't want accessibility roles to be read. Furthermore, adding a menu complicates the access to the elements with the keyboard and I want the focus to start in the first option.
This is my code:
import java.util.Set;
import java.util.HashSet;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
public class Screen {
public Screen() {
// Accept arrow keys as focus traversal keys
Set<AWTKeyStroke> set = new HashSet<AWTKeyStroke>(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTrave rsalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
set.add(KeyStroke.getKeyStroke("DOWN"));
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,set);
set = new HashSet<AWTKeyStroke>(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
set.add(KeyStroke.getKeyStroke("UP"));
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,set);
// definition of Menu Items
JMenuItem mi=new JMenuItem("play");
JMenuItem mi2=new JMenuItem("exit");
mi.setFocusable(true);
mi2.setFocusable(true);
// Attempt with MenuKeyListener
mi.addMenuKeyListener(new MenuKeyListener() {
public void menuKeyReleased(MenuKeyEvent e) {
System.out.println("Play released");
}
public void menuKeyTyped(MenuKeyEvent e) {}
public void menuKeyPressed(MenuKeyEvent e) {}
});
// Attempt with ActionListener
mi2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
mi.setVisible(true);
mi2.setVisible(true);
JPanel mp = new JPanel();
JFrame mf = new JFrame("Game");
mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mp.add(mi);
mp.add(mi2);
mf.add(mp);
mf.setVisible(true);
}
public static void main(String args[]) {
new Screen();
}
}
I've tried with both ActionListener and MenuKeyListener, with and without the JPanel, changing visibilities... I also tried to use KeyEventDispatcher but I didn't know how to send a KeyEvent to the component that returns KeyboardFocusManager.getFocusOwner().
Please help.
There's a lot to help with in this case. For starters,
public static void main(String args[]) {
new Screen();
}
is wrong. It is not appropriate to perform any operation that alters the Swing layout or presentation on the main thread. Instead do
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Screen();
}
});
}
if you decide that you want to put swing calls into an object's constructor in this way.
Ideally your Screen would be a JFrame but one that is customized to meet your needs. That means you might want to create a new class GamePanel that extends JPanel
public class Screen extends JFrame {
public Screen() {
super("Game"); // to remind us that the JFrame is created
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(new GamePanel());
pack();
setVisible(true);
}
}
public class GamePanel extends JPanel {
public GamePanel() {
super();
}
}
Now, if you want that panel to listen to keys, you need to add a KeyListener interface. This only gives it the capability to listen, it doesn't make it listen.
public class GamePanel extends JPanel implements KeyListener {
...
public void keyTyped(KeyEvent e) {
System.out.println("KEY TYPED: " + e);
}
public void keyPressed(KeyEvent e) {
System.out.println("KEY PRESSED: " + e);
}
public void keyReleased(KeyEvent e) {
System.out.println("KEY RELEASED: " + e);
}
}
Now you can add your key listener to the Screen or to the GamePanel (it will listen to itself). Whenever the focus is in one of these items, and a key is pressed, the even will be routed to the listener.
public class GamePanel extends JPanel implements KeyListener {
public GamePanel() {
super();
addKeyListener(this);
}
...
}
Ideally, you might want to not combine your key listener with the panel itself, but make it a "Command Processor" of some sort. In that case, remove the KeyListener code from the JPanel and make a completely new CommmandHandler object that implements KeyListener.
As far as Actions go, they are convenience items that pre-configure menu entries with lots of things (icons, acceleration keys, text, callback functions). If you are avoiding menus for whatever reason, you will find that much of their utility in setting up menus is misdirected for your purpose. Effectively, they are configuration entries that configure the MenuItem objects to handle a key (through the KeyListener interface and then dispatch a swing Event object. This provide "better than key" tracking of items through an application as it converts a keyboard letter k to a class ActionEvent which is passed to the registered "action handler" typically a subclass of AbstractAction.
An example of an Action would be
public class MoveLeft extends AbstractAction { // which extends ActionListener
private final GameState gameState;
public MoveLeft(GameState gameState) {
super("move left", new ImageIcon(MoveLeft.class.getResource("/images/moveleft.png"));
putValue("SHORT_DESCRIPTION", "left");
putValue("MNEMONIC_KEY", "l");
this.gameState = gameState;
}
public void actionPerformed(ActionEvent e) {
gamestate.getSelected().moveLeft();
}
}
Assuming you wanted this convenience, you would initialize your CommandHandler with Actions, maybe like so:
public CommandHandler implements KeyListener {
private int actionId;
...
public void addAction(Action action) {
handlers.put(action.getValue("MNEMONIC_KEY")., action);
}
public void keyTyped(KeyEvent e) {
Action action = handlers.get(String.valueOf(e.getKeyChar());
ActionEvent event = new ActionEvent(this, id, action.getValue("NAME"));
action.actionPerformed( event );
}
}
As you can see, the added convenience of having Actions defined for the actions within your game is a balanced by making your components that use them be configured by them (and using them in the KeyListener implementations).
For large projects, the simplicity of having all your actions listed generally makes creating Actions well worth the effort; but, for smaller projects that are mostly using custom components, the added one-time-cost of making the KeyListener components use actions might outweigh the benefits.
Don't use JMenuItem this way, that's not how it's intended to be used
Instead, I'd start with JButton. The following makes use of your focus transversal code, the Action API and the key bindings API
import java.awt.AWTKeyStroke;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
Set<AWTKeyStroke> set = new HashSet<AWTKeyStroke>(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
set.add(KeyStroke.getKeyStroke("DOWN"));
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, set);
set = new HashSet<AWTKeyStroke>(KeyboardFocusManager.getCurrentKeyboardFocusManager().getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS));
set.add(KeyStroke.getKeyStroke("UP"));
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, set);
Action playAction = new AbstractAction("Play") {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("play");
}
};
playAction.putValue(Action.MNEMONIC_KEY, (int)'P');
Action exitAction = new AbstractAction("Exit") {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("exit");
}
};
exitAction.putValue(Action.MNEMONIC_KEY, (int)'x');
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_P, 0), "play");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, 0), "exit");
am.put("play", playAction);
am.put("exit", exitAction);
JButton playButton = new JButton(playAction);
JButton exitButton = new JButton(exitAction);
add(playButton, gbc);
add(exitButton, gbc);
}
}
}
Now, you could do something similar with JLabel, but, JLabel isn't focusable by default, nor does it render any kind of focus indication. Instead, I might be tempted to just strip down a JButton so it didn't paint its border or content/background instead
I'm trying to make it so that pressing the right arrow key does the same thing as pressing a JButton. I can bind the right arrow key to the button itself - but that means I have to have pressed the button before the right key works. Now I'm trying to see if binding to the actual JFrame is what I want, but I can't get anything to happen when I bind to the frame at all:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
onButtonPress();
}
private void formKeyPressed(java.awt.event.KeyEvent evt) {
if (evt.getKeyCode() == KeyEvent.VK_RIGHT){
onButtonPress();
}
}
private void onButtonPress() {
pressNum++;
jLabel1.setText("Button has been pressed " + pressNum + " times.");
}
As a general rule of thumb, you should avoid KeyListener. The main reason is, in order for a KeyListener to generate key events, the component it is registered to must be focusable AND have keyboard focus. In your case, this would probably mean adding a KeyListener to every component in your UI which "might" gain keyboard focus, not something which is practical in the real world.
Instead, you should make use of the Key Bindings API, which provides you the means to define the level of focus required in order for it to trigger the associated actions.
The Key Bindings API and the example make use of the Actions API, which allows me to define a single unit of work which can be applied to a number of "actionable" controls
The example also makes use of a delegate/callback/listener (namely CounterListener) which allows me to decouple the "side effects" from the action itself.
This basically means that the Action can do what it needs to do, but "other" interested parties can perform some other action when it changes. You could, equally attach an ActionListener to the Action, but this was just simpler and quicker to implement
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JLabel label = new JLabel("...");
MyAwesomeAction action = new MyAwesomeAction(new CounterListener() {
#Override
public void counterChanged(int count) {
label.setText("Button has been pressed " + count + " times");
}
});
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JButton button = new JButton(action);
add(button, gbc);
add(label, gbc);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "MakeItSo");
am.put("MakeItSo", action);
}
}
public interface CounterListener {
public void counterChanged(int count);
}
public class MyAwesomeAction extends AbstractAction {
private int count;
private CounterListener listener;
public MyAwesomeAction(CounterListener listener) {
putValue(NAME, "Make it so");
this.listener = listener;
}
#Override
public void actionPerformed(ActionEvent e) {
count++;
listener.counterChanged(count);
}
}
}
This example has a JButton with two listeners: an ActionListener and and a KeyListener. The key listener is implemented with the KeyAdapter abstract class. From the API documentation:
KeyAdapter is for receiving keyboard events. The methods in this class
are empty. This class exists as convenience for creating listener
objects.
Create a listener object using the extended class and then register it
with a component using the component's addKeyListener method. When a
key is pressed, released, or typed, the relevant method in the
listener object is invoked, and the KeyEvent is passed to it.
The example code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ButtonListeners {
private JLabel label;
private int counter;
public static void main(String [] args) {
new ButtonListeners().gui();
}
private void gui() {
JFrame frame = new JFrame();
frame.setTitle("JButton Listeners");
JButton button = new JButton("jButton1");
button.addActionListener(actionEvent -> displayLabel());
button.addKeyListener(new ButtonKeyPressListener());
label = new JLabel("Press button or -> key");
frame.add(button, BorderLayout.SOUTH);
frame.add(label, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(300, 150);
frame.setVisible(true);
}
private void displayLabel() {
label.setText("Action count: " + ++counter);
}
private class ButtonKeyPressListener extends KeyAdapter {
#Override public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT){
displayLabel();
}
}
}
}
I am having a checkbox and a button. I want that when i press ENTER to activate the button. It works as expected if i just press enter at run, but if i use the checkbox before, it doesn't work anymore.
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
public class Animation{
public Animation(){
JFrame frame = new JFrame();
Pane a = new Pane();
a.addKeyListener(a);
frame.add(a);
//frame.setUndecorated(true);
// frame.setOpacity(0.9f);
frame.setVisible(true);
frame.setSize(700, 300);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new Animation();
}
public class Pane extends JPanel implements KeyListener{
JButton buton = new JButton("BUTTON!!!! ");
JCheckBox c = new JCheckBox("Check");
public Pane(){
add(new JCheckBox("CHECKK"));
add(buton);
c.setFocusable(false);
buton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("Pressed!");
}
});
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public void keyPressed(KeyEvent arg0) {
if(arg0.getKeyCosw() == KeyEvent.VK_ENTER){
//if(buton.isDisplayable()){
System.out.println("pressed");
//buton.doClick();
//return;
//}
}
}
}
}
keyPressed is not called in this code sample. Is buton.addKeyListener( this ); missing?
If you use checkbox, it receives a focus. You can call setFocusable( false ) on that checkbox. So the only focused component will be the button. And it will always receive key events.
Otherwise, you can add key listener to checkbox too.
Also, take a llok at this answer to find out how to set a global key listener (if you don't want to deny focusing components or don't want to add a key listener to every component).
I have a JFrame, which represents the GUI for my Java application.
I have a custom button, derived from JComponent and created and placed on this JFrame. On pressing this button a modal dialog appears.
The problem is, that after modal dialog appears, the JFrame stops receiving mouse events from mouse. I opened Spy++ and found out that MouseEvents from Windows are passed to the JFrame. So they are switched off somewhere in Java.
I need to receive button events for one thing - when mouse enters my custom button area, button changes color. And I need to know when the mouse exits the button area, to change the button to it's original color. The same problem is with standard JButton - it remains hovered after modal dialog appears.
Of course I can track the opening of modal dialog myself, and make my button unhovered, but just curious, if there is standard solution.
You see, that the button on the JFrame remains hovered as the dialog appears.
package quixote.sscce;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class FrameTop extends JFrame implements MouseListener, ActionListener {
private JButton button;
public FrameTop() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(200, 200);
setLocation(100, 100);
setLayout(new BorderLayout());
button = new JButton("Click me");
add(button, BorderLayout.CENTER);
button.addActionListener(this);
addMouseListener(this);
}
#Override
public void actionPerformed(ActionEvent arg0) {
JDialog dialog = new JDialog(this, "dialog");
dialog.setModal(true);
dialog.setLocation(150, 150);
dialog.setSize(100, 100);
dialog.setVisible(true);
}
private int aaa = 0;
#Override
public void mouseClicked(MouseEvent arg0) {
System.out.println("XXX " + aaa);
}
#Override
public void mouseEntered(MouseEvent arg0) {
System.out.println("XXX " + aaa);
}
#Override
public void mouseExited(MouseEvent arg0) {
System.out.println("XXX " + aaa);
}
#Override
public void mousePressed(MouseEvent arg0) {
System.out.println("XXX " + aaa);
}
#Override
public void mouseReleased(MouseEvent arg0) {
System.out.println("XXX " + aaa);
}
public static void main(String args[]) {
final FrameTop top = new FrameTop();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
top.setVisible(true);
}
});
}
}
I think you might have forgot set opaque ie. setOpaque(true).
This will allow you to change background colour of frame and for button button.setOpaque(true).
Try it, it may help you.
Use non modal dialog, and call dialog.setAlwaysOnTop(true);
hope this helps
This question probably belies underlying lack of Swing knowledge, but I can't seem to pin down what I'm doing wrong. Essentially I want to detect mousePressed in one component, and then receive the mouseReleased for whatever component is under the mouse when it is released, rather than the original component.
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.event.MouseInputAdapter;
import net.miginfocom.swing.MigLayout;
public class TestMouseListener extends MouseInputAdapter {
public void mouseEntered(MouseEvent arg0) {System.out.println("Entered " + arg0.getComponent());}
public void mouseExited(MouseEvent arg0) {System.out.println("Exited " + arg0.getComponent());}
public void mousePressed(MouseEvent arg0) {System.out.println("Pressed " + arg0.getComponent());}
public void mouseReleased(MouseEvent arg0) {System.out.println("Released " + arg0.getComponent());}
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setLayout(new MigLayout());
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TestPanel panel1 = new TestPanel("Panel 1");
TestPanel panel2 = new TestPanel("Panel 2");
panel1.add(new JLabel("Text1"));
panel2.add(new JLabel("Text2"));
frame.add(panel1);
frame.add(panel2);
TestMouseListener listener = new TestMouseListener();
panel1.addMouseListener(listener);
panel1.addMouseMotionListener(listener);
panel2.addMouseListener(listener);
panel2.addMouseMotionListener(listener);
frame.setVisible(true);
}
}
class TestPanel extends JPanel {
String name;
TestPanel(String name){ this.name = name; }
public String toString(){ return name; }
}
So when I mouse over panel 1, click, drag to panel 2, release, I get the following:
Entered Panel 1
Pressed Panel 1
Exited Panel 1
Entered Panel 2
Released Panel 1
How do I get the panel I released over? I was hoping the mouseReleased event would fire for Panel 2 but obviously it does not.
Store a variable that holds your most recently entered component. Keep overwriting it every time you trigger a MouseEntered event. Then have a method, so that when you release the mouse button, you can use whatever your most recently entered component is.
Component lastEntered;
private void MouseEntered(MouseEvent e) {
lastEntered = e.getComponent;
}