太難兩個JFrames之間的管理重點,更好地將只創建一個JFrame等Top-level Containers將JDialogs,創建一/二JDialog(s)和重用,通過消除所有JComponent上
basicaly這將是:
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
someComponent.grabFocus();
someComponent.requestFocus();//or inWindow depends if Swing or Awt
}
});
而是兩個JFrames之間的事情有點複雜,只是基本的和未完成的例子(基於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
有由camickr Dialog Focus但AncestorListener外觀極好Woodoo不是我的Java杯和太多的抽象,我
你爲什麼要這樣做?難道你不能只是讓事件監聽器(或按鈕動作)執行任何操作框架B會做的事情,如果你能夠發送鍵盤事件給它呢? – gatkin
如果兩個框架在同一個應用程序中,爲什麼要將鍵盤事件發送到另一個框架?你在做某種測試自動化嗎? – Jim
是的這是用於測試自動化。我也在使用關鍵事件,因爲我試圖重用從框架繼承的功能,而不是重新發明輪子。 – drew