我正在使用Java来创建内部工具。两者由两个JPanels
组成,预计将在两个不同的屏幕上运行。我希望能够点击JButton
的{{1}},JFrame A
会将键盘操作发送到JFrame B
。
不幸的是我似乎无法做到这一点,因为JFrame B
没有焦点而且我无法使用任何请求Focus
方法,因为JFrame B
不是孩子Focus Window
(JFrame A
是)。
那么我怎样才能提供JFrame B
焦点,尽管它不是Focus Window
的孩子,或者发送Keyboard Event
到J Frame B
它会响应而没有聚焦?
答案 0 :(得分:3)
很难管理两个JFrames之间的焦点,最好只创建一个JFrame而其他Top-level Containers将是JDialogs,创建一个/两个{{3}通过删除所有JComponents来重用它
基本上是:
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
someComponent.grabFocus();
someComponent.requestFocus();//or inWindow depends if Swing or Awt
}
});
但两个JFrame之间的事情有点复杂,只是基本和未完成的例子(基于old.good.sun.forums.com的代码)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PMDialog extends JDialog {
private static final long serialVersionUID = 1L;
private boolean modal = false;
private WindowAdapter parentWindowListener;
private Window owner;
private JFrame blockedFrame = new JFrame("Blocked Frame");
private JFrame noBlockedFrame = new JFrame("No Blocked Frame");
public PMDialog() {
noBlockedFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
noBlockedFrame.getContentPane().add(new JButton(new AbstractAction("Test button") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent evt) {
System.out.println("Non blocked button pushed");
/*if (blockedFrame.isVisible()) {
noBlockedFrame.setVisible(false);
} else {
blockedFrame.setVisible(true);
}*/
noBlockedFrame.setVisible(true);
blockedFrame.setVisible(true);
}
}));
noBlockedFrame.setSize(200, 200);
noBlockedFrame.setVisible(true);
blockedFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
blockedFrame.getContentPane().add(new JButton(new AbstractAction("Test Button") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent evt) {
final PMDialog pmd = new PMDialog(blockedFrame, "Partial Modal Dialog", true);
pmd.setSize(200, 100);
pmd.setLocationRelativeTo(blockedFrame);
pmd.getContentPane().add(new JButton(new AbstractAction("Test button") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent evt) {
System.out.println("Blocked button pushed");
pmd.setVisible(false);
blockedFrame.setVisible(false);
noBlockedFrame.setVisible(true);
}
}));
pmd.setDefaultCloseOperation(PMDialog.DISPOSE_ON_CLOSE);
pmd.setVisible(true);
System.out.println("Returned from Dialog");
}
}));
blockedFrame.setSize(200, 200);
blockedFrame.setLocation(300, 0);
blockedFrame.setVisible(false);
}
public PMDialog(JDialog parent, String title, boolean isModal) {
super(parent, title, false);
initDialog(parent, title, isModal);
}
public PMDialog(JFrame parent, String title, boolean isModal) {
super(parent, title, false);
initDialog(parent, title, isModal);
}
private void initDialog(Window parent, String title, boolean isModal) {
owner = parent;
modal = isModal;
parentWindowListener = new WindowAdapter() {
@Override
public void windowActivated(WindowEvent e) {
if (isVisible()) {
System.out.println("Dialog.getFocusBack()");
getFocusBack();
}
}
};
}
private void getFocusBack() {
Toolkit.getDefaultToolkit().beep();
super.setVisible(false);
super.pack();
super.setLocationRelativeTo(owner);
super.setVisible(true);
super.toFront();
}
@Override
public void dispose() {
owner.setEnabled(true);
owner.setFocusableWindowState(true);
super.dispose();
}
@Override
@SuppressWarnings("deprecation")
public void hide() {
owner.setEnabled(true);
owner.setFocusableWindowState(true);
super.hide();
}
@Override
public void setVisible(boolean visible) {
boolean blockParent = (visible && modal);
owner.setEnabled(!blockParent);
owner.setFocusableWindowState(!blockParent);
super.setVisible(visible);
if (blockParent) {
System.out.println("Adding listener to parent ...");
owner.addWindowListener(parentWindowListener);
try {
if (SwingUtilities.isEventDispatchThread()) {
System.out.println("EventDispatchThread");
EventQueue theQueue = getToolkit().getSystemEventQueue();
while (isVisible()) {
AWTEvent event = theQueue.getNextEvent();
Object src = event.getSource();
if (event instanceof ActiveEvent) {
((ActiveEvent) event).dispatch();
} else if (src instanceof Component) {
((Component) src).dispatchEvent(event);
}
}
} else {
System.out.println("OUTSIDE EventDispatchThread");
synchronized (getTreeLock()) {
while (isVisible()) {
try {
getTreeLock().wait();
} catch (InterruptedException e) {
break;
}
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Error from EDT ... : " + ex);
}
} else {
System.out.println("Removing listener from parent ...");
owner.removeWindowListener(parentWindowListener);
owner.setEnabled(true);
owner.setFocusableWindowState(true);
}
}
@Override
public void setModal(boolean modal) {
this.modal = modal;
}
public static void main(String args[]) {
PMDialog pMDialog = new PMDialog();
}
}
编辑:对于如何将焦点添加到JDialog
是不是有一个很棒的Woodoo by camickr JDialog(s)但是Dialog Focus不是我的Java杯,而且对我来说太抽象了
答案 1 :(得分:2)
这是一个Swing GUI(你没有提到或添加一个标签到gui库)?如果是这样,请考虑使用Key Bindings,与KeyListeners相比,它可以更灵活地重点关注。
答案 2 :(得分:2)