Java - 代码编译但动作未被识别
Java - Code compiles but action is not recognised
由于焦点问题,我在 Java 中遇到了一些关键侦听器问题,所以我阅读了相关内容,许多网站建议改用键绑定。
我的代码在下面,我正在尝试将 space 键映射到动作 TestAction。面板对象只是 JPanel 的扩展。
public class Template_Main {
static Boolean quit = false;
public static void main(String[] args) {
Window window = new Window();
while(!quit) {
window.update();
}
System.exit(0);
}
}
.
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
public class Window {
public Frame frame;
public Panel panel;
public Window() {
frame = new Frame();
panel = new Panel();
Action pressedAction = new TestAction();
Action releasedAction = new TestAction();
pressedAction.setEnabled(true);
releasedAction.setEnabled(true);
panel.getInputMap().put(KeyStroke.getKeyStroke("SPACE"),"pressed");
panel.getInputMap().put(KeyStroke.getKeyStroke("released SPACE"),"released");
panel.getActionMap().put("pressed",pressedAction);
panel.getActionMap().put("released",releasedAction);
frame.add(panel);
frame.pack();
}
public void update() {
Logic.update();
updateImages();
sleep();
}
public void updateImages() {
panel.removeAll();
for (int i = 0; i < Imgs.array.size(); ++i) {
Img img = Imgs.get(i);
addImage(img.name, img.x, img.y, img.width, img.height);
}
panel.repaint();
}
public void addImage(String name, int x, int y, int width, int height) {
panel.add(newImageLabel(name, x, y, width, height));
}
public static JLabel newImageLabel(String imageName, int x, int y, int width, int height) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
java.net.URL iconUrl = ClassLoader.getSystemResource("resources/"+imageName);
Image image = toolkit.createImage(iconUrl);
JLabel label = new JLabel(new ImageIcon(image));
label.setBounds(x, y, width, height);
return label;
}
static void sleep() {
try {
Thread.sleep(Math.round(10));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
.
import javax.swing.JFrame;
public class Frame extends JFrame {
public Frame() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle(Config.TITLE);
setResizable(Config.RESIZABLE);
setVisible(true);
}
}
.
import java.awt.Dimension;
import javax.swing.JPanel;
public class Panel extends JPanel {
public Panel() {
setPreferredSize(new Dimension(Config.WIDTH,Config.HEIGHT));
setLayout(null);
setBackground(Config.BG_COLOR);
setFocusable(true);
}
}
.
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
public class TestAction extends AbstractAction {
public TestAction() {
}
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("ACTION PERFORMED");
}
}
问题是虽然它编译没有错误,但当我按下 space 栏时没有任何反应。
我认为您的问题正如 William Morrison 在 JPanel 未获得焦点时所说的那样。
尝试在添加面板时调用 requestFocus()。如果您可以 post 一个包含的小代码示例,我们可以为您提供更多帮助。
以您的代码为基础,这有效。
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class App extends JFrame
{
public static void main( String args[] )
{
new App();
}
public App()
{
super( "Test App" );
setLocationRelativeTo( null );
setSize( 600, 450 );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
getContentPane().add( new KeyBindingPane() );
setVisible( true );
}
private class KeyBindingPane extends JPanel
{
public KeyBindingPane()
{
this.getInputMap().put( KeyStroke.getKeyStroke( "SPACE" ), "pressed" );
this.getInputMap().put( KeyStroke.getKeyStroke( "released SPACE" ), "released" );
getActionMap().put( "pressed", new SpaceBarAction() );
getActionMap().put( "released", new SpaceBarAction() );
requestFocus();
}
}
public class SpaceBarAction extends AbstractAction
{
@Override
public void actionPerformed( ActionEvent e )
{
System.out.println( "ACTION PERFORMED (SPACE BAR)" );
}
}
}
感谢大家的帮助!
你是对的,面板没有聚焦,包含它的框架才是。
添加 panel.requestFocus();
修复它!
由于焦点问题,我在 Java 中遇到了一些关键侦听器问题,所以我阅读了相关内容,许多网站建议改用键绑定。 我的代码在下面,我正在尝试将 space 键映射到动作 TestAction。面板对象只是 JPanel 的扩展。
public class Template_Main {
static Boolean quit = false;
public static void main(String[] args) {
Window window = new Window();
while(!quit) {
window.update();
}
System.exit(0);
}
}
.
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
public class Window {
public Frame frame;
public Panel panel;
public Window() {
frame = new Frame();
panel = new Panel();
Action pressedAction = new TestAction();
Action releasedAction = new TestAction();
pressedAction.setEnabled(true);
releasedAction.setEnabled(true);
panel.getInputMap().put(KeyStroke.getKeyStroke("SPACE"),"pressed");
panel.getInputMap().put(KeyStroke.getKeyStroke("released SPACE"),"released");
panel.getActionMap().put("pressed",pressedAction);
panel.getActionMap().put("released",releasedAction);
frame.add(panel);
frame.pack();
}
public void update() {
Logic.update();
updateImages();
sleep();
}
public void updateImages() {
panel.removeAll();
for (int i = 0; i < Imgs.array.size(); ++i) {
Img img = Imgs.get(i);
addImage(img.name, img.x, img.y, img.width, img.height);
}
panel.repaint();
}
public void addImage(String name, int x, int y, int width, int height) {
panel.add(newImageLabel(name, x, y, width, height));
}
public static JLabel newImageLabel(String imageName, int x, int y, int width, int height) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
java.net.URL iconUrl = ClassLoader.getSystemResource("resources/"+imageName);
Image image = toolkit.createImage(iconUrl);
JLabel label = new JLabel(new ImageIcon(image));
label.setBounds(x, y, width, height);
return label;
}
static void sleep() {
try {
Thread.sleep(Math.round(10));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
.
import javax.swing.JFrame;
public class Frame extends JFrame {
public Frame() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle(Config.TITLE);
setResizable(Config.RESIZABLE);
setVisible(true);
}
}
.
import java.awt.Dimension;
import javax.swing.JPanel;
public class Panel extends JPanel {
public Panel() {
setPreferredSize(new Dimension(Config.WIDTH,Config.HEIGHT));
setLayout(null);
setBackground(Config.BG_COLOR);
setFocusable(true);
}
}
.
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
public class TestAction extends AbstractAction {
public TestAction() {
}
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("ACTION PERFORMED");
}
}
问题是虽然它编译没有错误,但当我按下 space 栏时没有任何反应。
我认为您的问题正如 William Morrison 在 JPanel 未获得焦点时所说的那样。
尝试在添加面板时调用 requestFocus()。如果您可以 post 一个包含的小代码示例,我们可以为您提供更多帮助。
以您的代码为基础,这有效。
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class App extends JFrame
{
public static void main( String args[] )
{
new App();
}
public App()
{
super( "Test App" );
setLocationRelativeTo( null );
setSize( 600, 450 );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
getContentPane().add( new KeyBindingPane() );
setVisible( true );
}
private class KeyBindingPane extends JPanel
{
public KeyBindingPane()
{
this.getInputMap().put( KeyStroke.getKeyStroke( "SPACE" ), "pressed" );
this.getInputMap().put( KeyStroke.getKeyStroke( "released SPACE" ), "released" );
getActionMap().put( "pressed", new SpaceBarAction() );
getActionMap().put( "released", new SpaceBarAction() );
requestFocus();
}
}
public class SpaceBarAction extends AbstractAction
{
@Override
public void actionPerformed( ActionEvent e )
{
System.out.println( "ACTION PERFORMED (SPACE BAR)" );
}
}
}
感谢大家的帮助!
你是对的,面板没有聚焦,包含它的框架才是。
添加 panel.requestFocus();
修复它!