2017-02-11 62 views
0

嗨,我是Java Swing的新手。Java Swing-從外部類中調用一個actionlisner

有一個Swing類如下 -

Class A extends JDialog 
{ 

JButton button=new JButton(" test"); 
button.addActionListener(new TestAction()); 

//Inner class 
private class TestAction extends AbstractAction { 

     public void actionPerformed(final ActionEvent e) { 
      dispose(); 
     } 
    } 
} 

上面的代碼工作良好。 必須將內部TestAction類作爲常用java文件移動,以便可以重用它。

public class TestActionNew extends AbstractAction { 

    JFrame frame; 

    TestActionNew() { 
     this.frame = new JFrame(); 

    } 

    public void actionPerformed(final ActionEvent e) { 
     frame.dispose(); 
    } 
} 

添加了新的監聽器按鈕 button.addActionListener(新TestActionNew())

但處置行動是行不通的。 任何人都可以幫助我在這裏做錯了。 感謝

回答

2

照顧你創建另一個框架,並呼籲該dispose,而作爲一個嵌套類,dispose被稱爲在外圍實例。

如果你想讓它可重複使用,你需要通過在其上調用dispose到構造函數的東西:

public class TestActionNew extends AbstractAction { 

    JFrame frame; 

    TestActionNew (JFrame frame) { 
     this.frame = frame; 

    } 

    public void actionPerformed(final ActionEvent e) { 
     frame.dispose(); 
    } 
} 

然後在你的其他代碼使用:

JButton button = new JButton(" test"); 
button.addActionListener(new TestAction(this)); 
+0

爲什麼不配置'Action'爲自包含,設置名稱和其他屬性,那麼你只需要調用'new JButton(new MySuperAwesomeAction())'...這也可以讓你將它與鍵綁定和菜單項一起使用,否則看起來像是一種過度殺傷 – MadProgrammer

2

你可以...

直接提供ActionListener支持...

class A extends JDialog { 

    JButton button = new JButton(" test"); 

    public A() { 
    } 

    public void addActionListener(ActionListener listener) { 
     button.addActionListener(listener); 
    } 

    public void removeActionListener(ActionListener listener) { 
     button.removeActionListener(listener); 
    } 

} 

但這往往暴露元素(即按鈕)其它類,並假定他們瞭解內部實現(即actionCommand)的對話框

你可以...

提供的能力定製供應Action小號

class A extends JDialog { 
    //... 
    public void addAction(Action action) { 
     JButton btn = new JButton(action); 
     buttonPanel.add(btn); 
    } 
} 

這意味着該對話框並不需要關心「什麼」的Action呢,它只是提供了執行它的手段,在Action提供工作SA自包含單元,它需要完成的

例如,給定一個Action像...

public class CancelAction extends AbstractAction { 

    public CancelAction() { 
     putValue(NAME, "Cancel"); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     // What ever needs to be done here... 
    } 

} 

你會使用它像...

A dialog = A(); 
dialog.addAction(new CancelAction()); 

現在,很明顯,您可以根據需要定製動作,傳遞Action需要做的任何信息,但對話框不會在意

You co uld ...

創建一個預定義的接口,該接口指定對話願意執行的操作...

public interface AListener { 
    public void wasCancelled(A dialog); 
    public void wasAccepted(A dialog); 
} 

你會那麼這個監聽器附加到A一個實例,並在它的執行

class A extends JDialog { 
    //...  
    private Set<AListener> listeners = new HashSet<>(); 

    public void addAListener(AListener listener){ 
     listeners.add(listener); 
    } 

    public void removeAListener(AListener listener){ 
     listeners.add(listener); 
    } 

    protected void fireWasCancelled() { 
     for (AListener listener : listeners) { 
      listener.wasCancelled(this); 
     } 
    } 

    protected void fireWasAcceppted() { 
     for (AListener listener : listeners) { 
      listener.wasAccepted(this); 
     } 
    } 
} 

因此,採取適當的行動,當一些「動作」對話框內發生(如按鈕被點擊) ,你會調用相關的fireXxx方法所有已註冊偵聽

A aDialog = new A(); 
aDialog.addAListener(new AListener() { 
    @Override 
    public void wasCancelled(A dialog) { 
     // Do stuf 
    } 

    @Override 
    public void wasAccepted(A dialog) { 
     // Do stuff 
    } 
}); 

這定義了該對話框的功能通知願意執行併爲您提供控制(和上下文)以執行其他任務,而不會過度暴露不需要了解它們的類之間的實現細節。

你可以...

只需使用一個JOptionPane,它提供了一個自包含的API,用於向用戶顯示信息和在什麼用戶做了

你應該使用哪個爲您提供反饋.. 。?

您應該使用最能滿足您需求的方法或方法的混合。我個人更喜歡使用Action,因爲它是一個自包含的,可重複使用的工作單元,它可以與按鈕,鍵綁定和菜單項一起使用,使得它非常靈活,但是如果你只是簡單地有一個對話框, 「確定」/「取消」按鈕,可能會有點過分殺死。

你可以採取的第二個想法,只是提供的功能,使您可以直接定製「確定」和「取消」的行動,而不是靈活地提供你什麼都想要的動作,作爲一個例子

我'd也鼓勵你看看How to Use Actions,因爲你似乎完全沒有完全掌握API的功能。