プログラムでActionEvent
(ボタンが押された/ ACTION_PERFORMEDなど)をJButton
に送信するにはどうすればよいですか?
私は知っています:
button.doClick(0);
そして
button.getModel().setArmed(true);
button.getModel().setPressed(true);
button.getModel().setPressed(false);
button.getModel().setArmed(false);
しかし、直接ActionEvent
を送信することはできませんか?
編集:これは製品コードではなく、ほんの少しの個人的な実験です。
ボタンのActionListener
sを取得してから、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);
}
できたとしても、なぜしたいのですか?通常、人々がこのようなことをしたいとき、それは彼らが適切に懸念を分離してビジネスロジックから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();
}
保護されている 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
なぜあなたはそれをしたいのですか?わかりませんが、従うことをお勧めします マークのアドバイス
ボタンで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)
を呼び出して、プライベートまたは保護されたメソッド/フィールドにアクセスしようとしたときに発生するIllegalAccessException
sを抑制します。最後に、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);
}
}
_