电子队列系统中KeyListener的keyPressed等方法未触发问题求助
Hey there! Let's tackle your KeyListener issue first, then walk through a much cleaner approach to triggering the admin login in your queue system.
Why isn't your KeyListener working?
In Swing, KeyListener only fires events if the component it's attached to has keyboard focus. You added the listener to your JFrame, but as soon as the app starts, the focus defaults to the Login button. Any keyboard events will go to the button instead of the frame, which is why your keyPressed()/keyReleased() methods never get called. Even if you force the frame to take focus, clicking the button will yank it right back—this approach is super unreliable.
The better solution: Check modifier keys directly in the button click
You don't even need a KeyListener for this! When a user clicks the button, the ActionEvent already carries info about which modifier keys (like Shift) were pressed during the click. You can check that directly, no need to track key states manually.
Here's your revised, cleaner code:
package net.koya.pleasewait; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.InputEvent; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; public class PleaseWait implements ActionListener { public static void main(String[] args) { PleaseWait pleaseWait = new PleaseWait(); JFrame admin = new JFrame("Queue admin"); JPanel loginPanel = new JPanel(); JButton login = new JButton("Login"); login.setAlignmentX(0.5f); login.addActionListener(pleaseWait); loginPanel.setLayout(new BoxLayout(loginPanel, BoxLayout.Y_AXIS)); loginPanel.add(login); admin.setContentPane(loginPanel); admin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); admin.setBounds(0, 0, 200, 200); admin.setVisible(true); } @Override public void actionPerformed(ActionEvent e) { // Check if Shift was pressed when the button was clicked if ((e.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) != 0) { JOptionPane.showMessageDialog( null, "Admin mode!", "Hello, World!", JOptionPane.WARNING_MESSAGE); } } }
Bonus: If you need global keyboard triggers (no button click required)
If you ever want to pop up the admin panel without clicking the button—say, with a keyboard shortcut like Shift+L—use Swing's Key Bindings instead of KeyListener. It's the recommended way to handle keyboard events in Swing, since it works regardless of which component has focus.
Add this to your main method to set it up:
import javax.swing.AbstractAction; import javax.swing.JComponent; import java.awt.event.KeyEvent; // ... loginPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( KeyStroke.getKeyStroke(KeyEvent.VK_L, InputEvent.SHIFT_DOWN_MASK), "adminLogin"); loginPanel.getActionMap().put("adminLogin", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog( null, "Admin mode!", "Hello, World!", JOptionPane.WARNING_MESSAGE); } });
This follows Swing's design principles and is way more reliable than messing with KeyListener focus issues.
内容的提问来源于stack exchange,提问作者korochun

