提问人:stupidmoron 提问时间:5/16/2022 更新时间:5/16/2022 访问量:136
按键事件处理 - 按键未显示在 JLabel 上
Key event handling - key pressed doesn't show up on JLabel
问:
我正在一本书中做一个练习,你必须测试事件处理,其中之一是关键事件。我按照书中关于如何处理 keyPressed 事件的说明进行操作,但我的密钥事件处理程序没有像它应该的那样显示 JLabel 上按下的键。这是我的代码:
import java.awt.FlowLayout;
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.ListSelectionModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JCheckBox;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Events extends JFrame {
private JLabel insLabel;
private JLabel fontLabel;
private JLabel mouseLabel;
private JLabel resultLabel;
private JList fontList;
private static final String[] fontNames = {"Serif", "SansSerif", "Monospaced"};
private JCheckBox boldCb;
private JCheckBox italicCb;
private JButton submitButton;
private JPanel middlePanel;
private JPanel bottomPanel;
private String fontName;
private String fontStyle;
public Events() {
super("Demonstrating Events");
setLayout(new BorderLayout());
insLabel = new JLabel("Please feel free to click anywhere or press any key.");
fontLabel = new JLabel("Choose a font:");
fontList = new JList(fontNames);
fontList.setVisibleRowCount(3);
fontList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
add(new JScrollPane(fontList));
boldCb = new JCheckBox("Bold");
italicCb = new JCheckBox("Italic");
submitButton = new JButton("Submit");
mouseLabel = new JLabel("");
resultLabel = new JLabel("");
middlePanel = new JPanel();
middlePanel.setLayout(new FlowLayout());
bottomPanel = new JPanel();
bottomPanel.setLayout(new FlowLayout());
add(insLabel, BorderLayout.NORTH);
middlePanel.add(fontLabel);
middlePanel.add(fontList);
middlePanel.add(boldCb);
middlePanel.add(italicCb);
middlePanel.add(submitButton);
add(middlePanel, BorderLayout.CENTER);
bottomPanel.add(mouseLabel);
bottomPanel.add(resultLabel);
add(bottomPanel, BorderLayout.SOUTH);
// set up event handling
fontList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
fontName = fontNames[fontList.getSelectedIndex()];
}
});
CheckBoxHandler handler = new CheckBoxHandler();
boldCb.addItemListener(handler);
italicCb.addItemListener(handler);
submitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(fontStyle == "both") {
resultLabel.setFont(new Font(fontName, Font.BOLD + Font.ITALIC, 18));
resultLabel.setText("You chose " + fontName + " bold and italic");
} else if(fontStyle == "bold") {
resultLabel.setFont(new Font(fontName, Font.BOLD, 18));
resultLabel.setText("You chose " + fontName + " bold");
} else if(fontStyle == "italic") {
resultLabel.setFont(new Font(fontName, Font.ITALIC, 18));
resultLabel.setText("You chose " + fontName + " italic");
} else {
resultLabel.setFont(new Font(fontName, Font.PLAIN, 18));
resultLabel.setText("You chose " + fontName + " plain");
}
}
});
addMouseListener(new MouseClickHandler());
addMouseMotionListener(new MouseMotionHandler());
addKeyListener(new KeyHandler());
} // end constructor
private class CheckBoxHandler implements ItemListener {
public void itemStateChanged(ItemEvent e) {
if(boldCb.isSelected() && italicCb.isSelected())
fontStyle = "both";
else if(boldCb.isSelected())
fontStyle = "bold";
else if (italicCb.isSelected())
fontStyle = "italic";
else
fontStyle = "plain";
}
}
private class MouseClickHandler extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
int xPos = e.getX();
int yPos = e.getY();
mouseLabel.setText("Mouse clicked at (" + xPos + ", " + yPos + ")");
}
}
private class MouseMotionHandler extends MouseMotionAdapter {
public void mouseMoved(MouseEvent e) {
int xPos = e.getX();
int yPos = e.getY();
mouseLabel.setText("Mouse moved at (" + xPos + ", " + yPos + ")");
}
}
private class KeyHandler extends KeyAdapter {
public void keyPressed(KeyEvent e) {
resultLabel.setText("You pressed " + KeyEvent.getKeyText(e.getKeyCode()));
}
}
}
答:
0赞
MadProgrammer
5/16/2022
#1
KeyListener
臭名昭著,以不回应关键事件而闻名 - 在一些研究中,你会发现它被问了很多。问题是,为了让组件生成 (via ),该组件必须既可聚焦又具有键盘焦点。A不太可能满足这两个要求,再加上你有其他组件的问题,这些组件会“偷走”焦点,你正处于一个永无止境的冲突中。KeyEvent
KeyListener
JFrame
解决方案取决于您要解决的问题。通常优先使用键绑定
举个简单的例子,你可以创建一个可聚焦的组件和监视器,例如......KeyEvents
public class KeyInputPane extends JPanel {
private JLabel instructionsLabel;
private JLabel keyLabel;
public KeyInputPane() {
setBorder(new CompoundBorder(new LineBorder(Color.GRAY, 1), new EmptyBorder(3, 3, 3, 3)));
setFocusable(true);
instructionsLabel = new JLabel("Waiting for focus...");
keyLabel = new JLabel(" ");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
add(instructionsLabel, gbc);
add(keyLabel, gbc);
addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
setBorder(new CompoundBorder(new LineBorder(Color.BLUE, 1), new EmptyBorder(3, 3, 3, 3)));
instructionsLabel.setText("Type something");
keyLabel.setText("...");
}
@Override
public void focusLost(FocusEvent e) {
setBorder(new CompoundBorder(new LineBorder(Color.GRAY, 1), new EmptyBorder(3, 3, 3, 3)));
instructionsLabel.setText("Waiting for focus...");
keyLabel.setText(" ");
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
requestFocusInWindow();
}
});
addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
keyLabel.setText(Character.toString(e.getKeyChar()));
}
});
}
}
可运行示例...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new EventsPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class KeyInputPane extends JPanel {
private JLabel instructionsLabel;
private JLabel keyLabel;
public KeyInputPane() {
setBorder(new CompoundBorder(new LineBorder(Color.GRAY, 1), new EmptyBorder(3, 3, 3, 3)));
setFocusable(true);
instructionsLabel = new JLabel("Waiting for focus...");
keyLabel = new JLabel(" ");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gbc.REMAINDER;
add(instructionsLabel, gbc);
add(keyLabel, gbc);
addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
setBorder(new CompoundBorder(new LineBorder(Color.BLUE, 1), new EmptyBorder(3, 3, 3, 3)));
instructionsLabel.setText("Type something");
keyLabel.setText("...");
}
@Override
public void focusLost(FocusEvent e) {
setBorder(new CompoundBorder(new LineBorder(Color.GRAY, 1), new EmptyBorder(3, 3, 3, 3)));
instructionsLabel.setText("Waiting for focus...");
keyLabel.setText(" ");
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
requestFocusInWindow();
}
});
addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
keyLabel.setText(Character.toString(e.getKeyChar()));
}
});
}
}
public class EventsPane extends JPanel {
private JLabel insLabel;
private JLabel fontLabel;
private JLabel mouseLabel;
private JLabel resultLabel;
private JList fontList;
private static final String[] fontNames = {"Serif", "SansSerif", "Monospaced"};
private JCheckBox boldCb;
private JCheckBox italicCb;
private JButton submitButton;
private JPanel middlePanel;
private JPanel bottomPanel;
private String fontName;
private String fontStyle;
public EventsPane() {
setLayout(new BorderLayout());
insLabel = new JLabel("Please feel free to click anywhere or press any key.");
fontLabel = new JLabel("Choose a font:");
fontList = new JList(fontNames);
fontList.setVisibleRowCount(3);
fontList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
add(new JScrollPane(fontList));
boldCb = new JCheckBox("Bold");
italicCb = new JCheckBox("Italic");
submitButton = new JButton("Submit");
mouseLabel = new JLabel("");
resultLabel = new JLabel("");
middlePanel = new JPanel();
middlePanel.setLayout(new FlowLayout());
bottomPanel = new JPanel();
bottomPanel.setLayout(new FlowLayout());
add(insLabel, BorderLayout.NORTH);
middlePanel.add(fontLabel);
middlePanel.add(fontList);
middlePanel.add(boldCb);
middlePanel.add(italicCb);
middlePanel.add(submitButton);
middlePanel.add(new KeyInputPane());
add(middlePanel, BorderLayout.CENTER);
bottomPanel.add(mouseLabel);
bottomPanel.add(resultLabel);
add(bottomPanel, BorderLayout.SOUTH);
// set up event handling
fontList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
fontName = fontNames[fontList.getSelectedIndex()];
}
});
CheckBoxHandler handler = new CheckBoxHandler();
boldCb.addItemListener(handler);
italicCb.addItemListener(handler);
submitButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (fontStyle == "both") {
resultLabel.setFont(new Font(fontName, Font.BOLD + Font.ITALIC, 18));
resultLabel.setText("You chose " + fontName + " bold and italic");
} else if (fontStyle == "bold") {
resultLabel.setFont(new Font(fontName, Font.BOLD, 18));
resultLabel.setText("You chose " + fontName + " bold");
} else if (fontStyle == "italic") {
resultLabel.setFont(new Font(fontName, Font.ITALIC, 18));
resultLabel.setText("You chose " + fontName + " italic");
} else {
resultLabel.setFont(new Font(fontName, Font.PLAIN, 18));
resultLabel.setText("You chose " + fontName + " plain");
}
}
});
addMouseListener(new MouseClickHandler());
addMouseMotionListener(new MouseMotionHandler());
addKeyListener(new KeyHandler());
} // end constructor
private class CheckBoxHandler implements ItemListener {
public void itemStateChanged(ItemEvent e) {
if (boldCb.isSelected() && italicCb.isSelected()) {
fontStyle = "both";
} else if (boldCb.isSelected()) {
fontStyle = "bold";
} else if (italicCb.isSelected()) {
fontStyle = "italic";
} else {
fontStyle = "plain";
}
}
}
private class MouseClickHandler extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
int xPos = e.getX();
int yPos = e.getY();
mouseLabel.setText("Mouse clicked at (" + xPos + ", " + yPos + ")");
}
}
private class MouseMotionHandler extends MouseMotionAdapter {
public void mouseMoved(MouseEvent e) {
int xPos = e.getX();
int yPos = e.getY();
mouseLabel.setText("Mouse moved at (" + xPos + ", " + yPos + ")");
}
}
private class KeyHandler extends KeyAdapter {
public void keyPressed(KeyEvent e) {
resultLabel.setText("You pressed " + KeyEvent.getKeyText(e.getKeyCode()));
}
}
}
}
评论
KeyListener
臭名昭著,以不回应关键事件而闻名 - 在一些研究中,你会发现它被问了很多。问题是,为了让组件生成 (via ),该组件必须既可聚焦又具有键盘焦点。A不太可能满足这两个要求,再加上你有其他组件的问题,这些组件会“偷走”焦点,你正处于一个永无止境的冲突中。KeyEvent
KeyListener
JFrame
KeyListener
KeyListener