2011-07-05 140 views
1

我正在Java中創建一個內部工具。這兩個由兩個JPanels組成,預計可在兩個獨立的屏幕上運行。我希望能夠點擊一個JButton,它是JFrame A的一部分,它將發送一個鍵盤動作到JFrame B將焦點放在不是關注窗口的子項目的面板上?

不幸的是,我似乎無法做到這一點,因爲JFrame B沒有重點,因爲JFrame B不是Focus Window的孩子(JFrame A是)我不能使用任何要求的Focus方法。

所以,我怎麼能要麼放棄JFrame B焦點,儘管它不是在Focus Window或發送Keyboard Event s的孩子給J Frame B它將以不必焦點應對?

+0

你爲什麼要這樣做?難道你不能只是讓事件監聽器(或按鈕動作)執行任何操作框架B會做的事情,如果你能夠發送鍵盤事件給它呢? – gatkin

+0

如果兩個框架在同一個應用程序中,爲什麼要將鍵盤事件發送到另一個框架?你在做某種測試自動化嗎? – Jim

+0

是的這是用於測試自動化。我也在使用關鍵事件,因爲我試圖重用從框架繼承的功能,而不是重新發明輪子。 – drew

回答

3

太難兩個JFrames之間的管理重點,更好地將只創建一個JFrameTop-level ContainersJDialogs,創建一/二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 FocusAncestorListener外觀極好Woodoo不是我的Java杯和太多的抽象,我

2

這是一個Swing GUI(你沒有提到或添加標籤到GUI庫)?如果是這樣,請考慮使用Key Bindings,與KeyListeners相比,它可以更加靈活地關注焦點。

+0

是的,它是擺動的,我已經更新了這個問題來反映這一點。 – drew

+0

不幸的是我看不到我可以如何使用鍵綁定。我想要的鍵綁定已經存在併爲框架B開發。這個面板實際上是一個更復雜結構的一部分,它繼承了我試圖從我無法觸及的框架部分開發的功能。我的問題不是綁定鍵,而是有一個按鈕按下生成我需要的keyEvents。我知道我可以做到這一點,如果我可以給我'框架B'的焦點 – drew

2

沒有說你不能有一個Action發送消息給另一個。在此example中,Enter也需要Clear,所以它轉發ActionEvent。還要注意,每個NumberButton將兩個按鍵綁定到Click。在你的情況下,你可能不得不刪除一個現有的綁定,並可能在另一個窗口上調用toFront()。請注意支持@ mKorbel答案的警告。

+0

嗯,看起來像我喜歡你的動能...,我的懶惰不允許我寫一些最複雜的,因爲這是,我的最後一個腦細胞通過運行此代碼而死亡,+1 – mKorbel

+0

@mKorbel:謝謝!,對大腦細胞抱歉。 :-)我歡迎任何重要的見解。不幸的是,'KineticModel'充滿了邪惡,可變'org.gcs.kinetic.Vector'。 – trashgod

+0

非常好,如果我說我喜歡那個然後一些評論家嗯...原子減少5or6 ?? th點擊退回初始數字的巴爾斯,更大的原子具有相同的動力加速度作爲小人物原子,也許有人閃爍橙色脂肪邊界,但它不會打擾我 – mKorbel