web-dev-qa-db-ja.com

プログラムでActionEventをJButtonに送信するにはどうすればよいですか?

プログラムでActionEvent(ボタンが押された/ ACTION_PERFORMEDなど)をJButtonに送信するにはどうすればよいですか?

私は知っています:

button.doClick(0);

そして

button.getModel().setArmed(true);
button.getModel().setPressed(true);
button.getModel().setPressed(false);
button.getModel().setArmed(false);

しかし、直接ActionEventを送信することはできませんか?

編集:これは製品コードではなく、ほんの少しの個人的な実験です。

14
Anon

ボタンのActionListenersを取得してから、actionPerformedメソッドを直接呼び出すことができます。

ActionEvent event;
long when;

when  = System.currentTimeMillis();
event = new ActionEvent(button, ActionEvent.ACTION_PERFORMED, "Anything", when, 0);

for (ActionListener listener : button.getActionListeners()) {
    listener.actionPerformed(event);
}
15
jjnguy

できたとしても、なぜしたいのですか?通常、人々がこのようなことをしたいとき、それは彼らが適切に懸念を分離してビジネスロジックからUIを持っていないことを意味します。通常、アクションを実行しなくても、ActionListenerで発生するロジックを呼び出したいと考えています。

public void actionPerformed(ActionEvent ae) {
    //SomeLogic
}

//...

public void someOtherPlace() {
    //I want to invoke SomeLogic from here though!
}

しかし実際の解決策は、ActionListenerからそのロジックを抽出し、ActionListenerとその2番目の場所の両方から呼び出すことです。

public void someLogic() {
    //SomeLogic
}

public void actionPerformed(ActionEvent ae) {
    someLogic();
}

//...

public void someOtherPlace() {
    someLogic();
}
13
Mark Peters

保護されている fireActionPerformed メソッドを継承して公開する場合のみ:

class MockButton extends JButton { 
   // bunch of constructors here 
   @Override 
   public void fireActionPerformed( ActionEvent e ) { 
       super.fireActionPerformed( e );
   }
}

そうすれば可能になりますが、もちろん、次のような参照を使用する必要があります。

MockButton b = .... 

b.fireActionPerformed( new Action... etc. etc

なぜあなたはそれをしたいのですか?わかりませんが、従うことをお勧めします マークのアドバイス

3
OscarRyz

ボタンでdoClick()を呼び出したくない場合は、ボタンのアクションによって呼び出されたコードを呼び出すだけです。おそらく、actionPerformedメソッドを保持するクラスが、他のクラスが呼び出すことができるパブリックメソッドを呼び出し、単にこのメソッドを呼び出すようにしたい場合があります。

実際の問題は解決されたようです( Mark Peters ' および jjnguy's の回答を参照)。また、潜在的な同時実行の問題を回避するために、fireActionPerformedメソッドもすでに説明されています( OscarRyzの回答 を参照)。

私が追加したかったのは、クラスをサブクラス化する必要なしに、すべてのプライベートメソッドと保護されたメソッド(fireActionPerformedを含む)をできることができるということでした、リフレクションを使用します。まず、プライベートメソッドまたは保護されたメソッドのリフレクションMethodオブジェクトをmethod = clazz.getDeclaredMethod()で取得します(clazzは、宣言するクラスのClassオブジェクトである必要がありますメソッドであり、そのサブクラスの1つではありません(つまり、メソッドfireActionPerformedの場合は_AbstractButton.class_、not_JButton.class_) )。次に、method.setAccessible(true)を呼び出して、プライベートまたは保護されたメソッド/フィールドにアクセスしようとしたときに発生するIllegalAccessExceptionsを抑制します。最後に、method.invoke()を呼び出します。

しかし、私はリフレクションについて十分に知りませんが、リフレクションを使用することの欠点をリストすることができます。ただし、 Reflection API Trail (「Reflectionの欠点」のセクションを参照)によれば、これらは存在します。

ここにいくつかの実用的なコードがあります:

_// ButtonFireAction.Java
import javax.swing.AbstractButton;
import javax.swing.JButton;
import Java.awt.event.ActionEvent;
import Java.awt.event.ActionListener;
import Java.lang.reflect.Method;

public class ButtonFireAction
{
    public static void main(String[] args) throws ReflectiveOperationException
    {
      JButton button = new JButton("action command");
      Class<AbstractButton> abstractClass = AbstractButton.class;
      Method fireMethod;

      // signature: public ActionEvent(Object source, int id, String command)
      ActionEvent myActionEvent = new ActionEvent(button,
                                                  ActionEvent.ACTION_PERFORMED,
                                                  button.getActionCommand());
      button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {
          System.out.println(e.getActionCommand());
        }
      });

      // get the Method object of protected method fireActionPerformed
      fireMethod = abstractClass.getDeclaredMethod("fireActionPerformed",
                                                   ActionEvent.class);
      // set accessible, so that no IllegalAccessException is thrown when
      // calling invoke()
      fireMethod.setAccessible(true);

      // signature: invoke(Object obj, Object... args)
      fireMethod.invoke(button,myActionEvent);
    }
}
_
0
mkdrive2