Практическая проблема, похоже, была решена (см. Марк Петерс и jjnguy's ответы). И метод fireActionPerformed
также уже упоминался (см. OscarRyz 'answer ), чтобы избежать потенциальных проблем параллелизма.
Я хотел добавить, что вы можете вызывать все закрытые и защищенные методы (включая fireActionPerformed
) без необходимости создавать подклассы для каких-либо классов, используя отражение. Во-первых, вы получаете объект отражения Method
частного или защищенного метода с method = clazz.getDeclaredMethod()
(clazz
должен быть объектом Class
класса, который объявляет метод, а не одним из его подклассов (то есть AbstractButton.class
для метода fireActionPerformed
, не JButton.class
)). Затем вы вызываете method.setAccessible(true)
для подавления IllegalAccessException
s, которые в противном случае возникнут при попытке доступа к закрытым или защищенным методам / полям. Наконец, вы звоните method.invoke()
.
Однако я недостаточно знаю об отражении, чтобы иметь возможность перечислить недостатки использования отражения. Однако они существуют в соответствии с API-интерфейсом Reflection *1028* (см. Раздел «Недостатки отражения»).
Вот рабочий код:
// 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);
}
}