我正在解决一个问题,我似乎无法专注于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。
N.B有人建议这可能是一个特定于macosx的bug - 我正在使用Intellij CE11.1。虽然我无法验证这一点。
更新:我还必须创建程序应该响应mb1,2和鼠标中键的功能 - 显然,如果没有焦点,这是不可能的?
答案 0 :(得分:2)
我创建了自己的SSCCE并且在测试时,似乎无论使用什么技术,applet仍然必须请求并获得他们的工作焦点。我已经使用两个kludges中的任何一个成功地在我的Windows系统上工作,包括在xxx ms之后请求焦点的javax.swing.Timer,或者覆盖第一次请求焦点的JApplet的paint(...)
方法调用paint(以及刚刚渲染applet时)。例如,显示两个kludges(只需要一个)和一个键绑定和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;
}
}