#java #swing #jframe #jbutton #actionlistener
#java #swing #jframe #jbutton #actionlistener
Вопрос:
У меня простой Swing GUI с главным окном JFrame
, и его основная панель является производной от JPanel
. На панели есть несколько кнопок, которые можно нажимать и генерировать события.
Я хочу, чтобы эти события влияли на данные, хранящиеся в JFrame
, потому что это мое основное приложение — в нем есть несколько очередей для потоков, открытых потоков и так далее.
Итак, как мне заставить мою кнопку в панели вызывать обратные вызовы в ее родительском фрейме? Как лучше всего использовать это для Java / Swing?
Ответ №1:
Для вызова методов в родительском фрейме вам нужна ссылка на родительский фрейм. Итак, конструктор вашей JPanel может быть объявлен следующим образом:
public MyPanel(MyFrame frame){
super();
this.frame = frame;
//the rest of your code
}
И в JFrame вы вызываете этот конструктор следующим образом:
panel = new MyPanel(this);//this refers to your JFrame
В обработчиках событий, прикрепленных к вашим кнопкам, теперь у вас есть доступ к фрейму и вы можете вызывать различные методы по мере необходимости.
button1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
//do some stuff
frame.someMethod();//invoke method on frame
//do more stuff
}
});
Ответ №2:
Взгляните на это руководство по использованию SwingWorker.
Комментарии:
1. почему это помогает мне? Я просто хочу получить чистый доступ к JFrame из JPanel, который он содержит
2. извините, это было неясно. вы можете использовать
SwingUtilities.getWindowAncestor( JPanel )
для получения родительского окна
Ответ №3:
Используйте метод addActionListener для желаемых кнопок, указывающих класс, реализующий ActionListener.
ActionListenerClass actionListenerObject = new actionListenerClass();
JButton b = new JButton("Button");
b.addActionListener(actionListenerObject);
public class ActionListenerClass implements ActionListener(){
//or better : actionListenerClass extends AbstractAction
public void actionPerformed(ActionEvent e) {
}
}
Редактировать:
Да, я это знаю. Но прослушивателем действий я хочу быть в родительском классе JFrame — в этом проблема
затем расширяет класс JFrame, создавая новый производный класс, реализующий желаемый интерфейс.
Комментарии:
1. Да, я это знаю. Но прослушивателем действий я хочу быть в родительском классе JFrame — в этом проблема
Ответ №4:
Вы можете реализовать ActionListener
в своем классе, который имеет JFrame (или расширяет его):
class MyPanelClass {
public MyPanelClass(ActionListener al)
{
//...
JButton myButton = new JButton("Button");
myButton.addActionListener(al);
//...
}
}
class MainClass extends JFrame implements ActionListener {
public void someMethod() {
MyPanelClass mpc = new MyPanelClass(this);
}
@Override
public void ActionPerformed(ActionEvent ev) {
// your implementation
}
}
Комментарии:
1. Но тогда нужно демультиплексировать все кнопки, которые были вызваны в нем, верно? все достигают одного и того же
actionPerformed
обратного вызова?2. Это правильно. И я вижу проблему, о которой вы говорите. Возможно, передача фрейма — лучший вариант…