gpt4 book ai didi

java - 尽管可见,启用为 true,但子 JComponent 不会获得焦点

转载 作者:行者123 更新时间:2023-11-30 04:35:20 24 4
gpt4 key购买 nike

我正在解决一个问题,但我似乎无法关注 Japplet 的 JComponent 子组件。我需要聚焦该组件,以便我可以使用键盘监听器来注册多个屏幕元素(游戏)的按键。

代码如下:

class TestApplet extends JApplet { 
public void init(){
setSize(400, 800);
new test class();
setFocusable(true);
setVisible(true);
}
}


public class testclass extends JPanel {
public testclass() {
grabFocus();
requestFocus();
requestFocusInWindow();

System.out.println("visible: " + isVisible());
System.out.println("Enbled " + isEnabled());
System.out.println("Focusable " + isFocusable());
System.out.println(isFocusOwner());
}
}

输出计算结果为

visible: true
Enbled true
Focusable true
false

尽管事实上我已经为子组件使用了所有可能的焦点抓取组合。如果我将相同的代码放入 Japplet 中,我创建的键盘监听器确实可以工作,但当我使用子组件时则不起作用...

这对于我的应用程序来说非常重要,因为我在分层拓扑中有许多 JPanel。

注意,有人建议这可能是 macOS 特定的错误 - 我正在使用 Intellij CE11.1。虽然我无法验证这一点。

更新:我还必须创建程序应响应 mb1,2 和鼠标中键的功能 - 显然,如果没有焦点,这是不可能的?

最佳答案

我创建了自己的 SSCCE,在测试中,似乎无论使用什么技术,小程序仍然必须请求并获得焦点才能工作。我已经使用两个组合中的任何一个成功地在我的 Windows 系统上工作,包括在 xxx 毫秒后请求焦点的 javax.swing.Timer ,或覆盖 JApplet 的 paint(...) 。第一次调用 Paint 时(以及刚刚渲染小程序时)请求焦点的方法。例如,显示两个拼凑件(只需要一个)以及键绑定(bind)和 SSCCE 的示例:

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.lang.reflect.InvocationTargetException;

import javax.swing.*;

@SuppressWarnings("serial")
public class KeyBindingEg extends JApplet {
protected static final int TIMER_DELAY = 100;
private boolean firstPane = true;

@Override
public void init() {
createAndShowGui();
}

private void createAndShowGui() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
TestClass test = new TestClass();
getContentPane().add(test);

// a kludge to get focus on the GUI some time after it has been created
new Timer(TIMER_DELAY, new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
requestFocusInWindow();
((Timer)e.getSource()).stop();
}
}).start();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}

@Override
public void paint(Graphics g) {
super.paint(g);
// another kludge to get focus on the GUI after it is
// first rendered
if (firstPane) {
requestFocusInWindow();
firstPane = false;
}
}
}

@SuppressWarnings("serial")
class TestClass extends JPanel {
public TestClass() {
setLayout(new BorderLayout());
add(new JLabel("TestClass", SwingUtilities.CENTER));

int condition = WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();

for (KeyInfo keyInfo : KeyInfo.values()) {
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyInfo.getKeyCode(), 0);
inputMap.put(keyStroke , keyInfo.toString());
actionMap.put(keyInfo.toString(), new AbstractAction() {

@Override
public void actionPerformed(ActionEvent evt) {
System.out.println("key press: " + evt.getActionCommand());
}
});
}
}
}

enum KeyInfo {
UP(KeyEvent.VK_W), DOWN(KeyEvent.VK_S), LEFT(KeyEvent.VK_A), RIGHT(KeyEvent.VK_D);
private int keyCode;

private KeyInfo(int keyCode) {
this.keyCode = keyCode;
}

public int getKeyCode() {
return keyCode;
}

}

上面的代码使用了 AncestorListener:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.*;
import java.lang.reflect.InvocationTargetException;

import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;

@SuppressWarnings("serial")
public class KeyBindingEg extends JApplet {
protected static final int TIMER_DELAY = 100;
private boolean firstPane = true;

@Override
public void init() {
createAndShowGui();
}

private void createAndShowGui() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
TestClass test = new TestClass();

JPanel contentPane = (JPanel) getContentPane();
contentPane.add(test);
contentPane.addAncestorListener(new RequestFocusListener());
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}

}

class RequestFocusListener implements AncestorListener {
public void ancestorRemoved(AncestorEvent arg0) {}
public void ancestorMoved(AncestorEvent arg0) {}

@Override
public void ancestorAdded(AncestorEvent aEvt) {
Component comp = (Component) aEvt.getSource();
comp.requestFocusInWindow();
}

}

@SuppressWarnings("serial")
class TestClass extends JPanel {
public TestClass() {
setLayout(new BorderLayout());
add(new JLabel("TestClass", SwingUtilities.CENTER));

int condition = WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
ActionMap actionMap = getActionMap();

for (KeyInfo keyInfo : KeyInfo.values()) {
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyInfo.getKeyCode(), 0);
inputMap.put(keyStroke, keyInfo.toString());
actionMap.put(keyInfo.toString(), new AbstractAction() {

@Override
public void actionPerformed(ActionEvent evt) {
System.out.println("key press: " + evt.getActionCommand());
}
});
}
}
}

enum KeyInfo {
UP(KeyEvent.VK_W), DOWN(KeyEvent.VK_S), LEFT(KeyEvent.VK_A), RIGHT(
KeyEvent.VK_D);
private int keyCode;

private KeyInfo(int keyCode) {
this.keyCode = keyCode;
}

public int getKeyCode() {
return keyCode;
}

}

关于java - 尽管可见,启用为 true,但子 JComponent 不会获得焦点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13661151/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com