2015-06-08 59 views
0

好的,所以我一直在改變這個練習程序,而且我仍然堅持同一個問題。希望得到一些幫助。Java:需要按下輸入來觸發動作和動作偵聽器

注意:我正在盡我所能簡單地使用基本代碼段和簡單縮寫來描述我的程序的各個元素。基本描述將首先出現,代碼段將根據需要顯示。

問題。在我的GUI中,我有三個主要類。我的窗口,面板A和麪板B.在面板B中,我有一個搜索字段,根據是否需要顯示或消失。有三個按鈕:查找(顯示搜索字段),搜索(運行搜索,隱藏字段)和取消(只是再次隱藏字段)。另外,我使用輸入/動作映射鍵綁定,以便按下ENTER鍵時我的搜索文本字段將複製搜索按鈕行爲,並且在ESCAPE上將複製取消按鈕行爲。

總之,這些組件執行兩個關鍵的行爲:

1)顯示或隱藏搜索欄

2)啓動它運行在後臺的搜索和它完成時更新GUI中的SwingWorker。

最初,我有一個行動旨在做到這一切,它的工作非常好。但是,當我走時,我意識到在運行搜索之後,偶爾會出現一些情況,我希望Panel A中顯示的數據能夠更新以匹配正在加載顯示的內容。這不會經常發生,但偶爾會造成我想要阻止的不協調。

我的行動,在當時,在面板B.內部類然而,對於SwingWorker的影響這兩個組A & B,我需要通過傳遞他們兩個作爲參數傳遞給SwingWorker類的構造函數,像這樣:

public SampleSwingWorker(String text, JPanel panelA, JPanel panelB){ 
     this.text = text; 
     this.panelA = panelA; 
     this.panelB = panelB; 
    } 

作爲面板B中的內部類,我無法將面板A作爲參數。

然後我嘗試了很多新的配置來設置這些動作。最終我開始意識到唯一的問題是SwingWorker。它是需要訪問Panel A & Panel B的代碼的唯一部分。

所以我重構了整個設置。以上,我列出了兩種行爲。我的行爲現在隻影響行爲1),不管搜索字段是顯示還是隱藏。同時,我在我的Window類中創建了一個ActionListener,並通過它的構造函數將它傳遞給了Panel B。結果是看起來像這樣的代碼。 ActionListener處理行爲2)。生成的代碼看起來是這樣的:

public class SampleWindow { 

    private PanelA panelA; 
    private PanelB panelB; 

    private JPanel createContentPane(){ 
     JPanel contentPane = new JPanel(new MigLayout()); 

     panelA = new PanelA(); 
     contentPane.add(panelA, "dock left"); 

     panelB = new PanelB(new SampleActionListener()); 
     contentPane.add(panelB, "dock center"); 

     return contentPane; 
    } 

    private class SampleActionListener implements ActionListener{ 

     public void actionPerformed(ActionEvent ae){ 
      SampleSwingWorker ssw = new SampleSwingWorker("text", panelA, panelB); 
      ssw.execute(); 
     } 
    } 

} 

public class PanelB { 

    private ActionListener al; 

    public PanelB(ActionListener al){ 
     this.al = al; 
     addComponents(); 
    } 

    private void addComponents(){ 
     JTextField searchField = new JTextField(); 
     addActionMap(searchField); 
     searchField.addActionListener(al); 
     //...add other components and buttons, etc, then add the listener to them too 
    } 

    private void addActionMap(JComponent component){ 
     InputMap im = component.getInputMap(); 
     ActionMap am = component.getActionMap(); 
     im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "HideAction"); 
     im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "HideAction"); 
     am.put("HideAction", new SampleAction(SampleAction.HIDE_FIELD)); 
    } 

    private class SampleAction extends AbstractAction{ 

     public static final int SHOW_FIELD = 1; 
     public static final int HIDE_FIELD = 2; 

     private int actionType; 

     public SampleAction(Object param1, Object param2, int actionType){ 
      this.actionType = actionType; 

      //...params are for JButtons, which require name, icon, etc 
      //to be passed to Action if using an Action 
     } 

     public void actionPerformed(ActionEvent ae){ 
      if(actionType == SHOW_FIELD){ 
       //...show the field 
      }else{ 
       //...hide the field 
      } 
     } 
    } 
} 

現在幾乎所有的作品,有一個問題,剩下的,那使我對我的帖子的核心。從我的代碼段可以看到,我使用輸入/動作映射將Action分配給我的搜索字段,因此按ENTER/ESCAPE將隱藏該字段。但是,當我在搜索字段中按Enter鍵時,它現在只觸發動作,而不是動作偵聽器來運行SwingWorker。

所以我想弄清楚如何讓兩者都發生。如何進行按下操作,觸發Action和ActionListener。

此外,我在這裏解釋了整個過程,如果我只是做這一切都錯了,有人可以指出我的邏輯在哪裏我失去了哈哈。

回答

1

你的代碼看起來有點糾結於我,這是一個嵌套問題。

使用ActionMapInputMap是一個不錯的主意,但我期望這些操作調用查找面板(面板B)的find()hide()等方法。

,然後逃逸KeyEvent可以調用hide()和ENTER KeyEvent可以調用find()hide()先後。您也可以將按鈕操作指向這些方法。