Как мне получить доступ к источнику ActionEvent, когда ActionListener находится в другом классе?

#java #model-view-controller #events #actionlistener

#java #модель-представление-контроллер #Мероприятия #actionlistener

Вопрос:

Я не могу разобраться с этим. Я впервые попытался придерживаться шаблона MVC и теперь испытываю трудности с доступом к источнику ActionEvent, потому что ActionListener находится в другом классе. Но пусть говорит код…

В «представлении»:

 // ControlForms.java

...

private JPanel createSearchPanel() throws SQLException {

...

comboBoxCode = new JComboBox(); // Field comboBoxCode -> JComboBox()
    SwingUtilities.invokeLater(new Runnable() {  
        public void run() {  
            AutoCompleteSupport<Object> support = AutoCompleteSupport.install(
comboBoxCode, GlazedLists.eventListOf(jnlCodeArray));
        }  
    });  // Auto-Complete comboBox from GlazedLists

...

public void setComboListener(ComboListener comboListener) {
    comboBoxCode.addActionListener(comboListener);
}

...

}
  

Тогда в том, что я называю контроллером, у меня есть два разных класса:

 // Controller.java

    public MyController() throws SQLException {
...
    addListeners();
}

...

    private void addListeners(){
    View view = getView();
    getView().getControlForm().setComboListener(new ComboListener());

}
  

и

 public class ComboListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
    System.out.println("ComboBox listened to! e = "   e.toString());
}
}
  

Теперь, e очевидно, не указывает имя переменной (чего на данный момент я бы хотел), поэтому я не могу if проверить e.getSource() .

Мой вопрос заключается в следующем: есть ли либо а) способ запросить (через if , например) источник e, либо б) менее сложный способ получить имя переменной?

Большое, большое спасибо заранее за ваши идеи и советы!

Ответ №1:

Зачем вам нужно имя переменной? Почему вы не можете выполнить обработку события следующим образом

 public class ComboListener implements ActionListener 
{
    public void actionPerformed(ActionEvent e) 
    {
        JComboBox source = (JComboBox)e.getSource();

        //do processing here
    }
}
  

Я бы подумал, что если вам нужно выполнить обработку в соответствии с именем переменной, очевидно, вам нужны разные прослушиватели для разных полей со списком.

Комментарии:

1. Спасибо. Я новичок в MVC, поэтому я пытался делать все «старомодным» способом, я полагаю. Конечно, вы правы в том, что мне понадобится по одному слушателю на JComboBox . Ли это хорошая практика кодирования , чтобы иметь одного слушателя на, скажем, элемент формы?

2. Вообще говоря, вам лучше отделить каждое поведение при обработке событий в отдельном [хотя и внутреннем] классе. Следовательно, если способ обработки событий в двух разных JComboBoxes отличается, то поместите их в разные классы. С другой стороны, если у вас есть два поля со списком, которые выполняют аналогичное автозаполнение, попробуйте выполнить обработку в том же классе.

Ответ №2:

Как правило, есть только две ситуации, в которых вам следует использовать подобный прослушиватель: а) вы собираетесь обрабатывать определенное событие таким же образом для группы объектов, или б) вы собираетесь использовать прослушиватель только для одного объекта. В последнем случае я бы предпочел обрабатывать событие локально в любом случае.

Тем не менее, прямой ответ на ваш вопрос таков: вам не нужно проверять внутри вашей ActionListener реализации, является ли соответствующий объект источником события; вы должны просто добавить ActionListener только к этому одному объекту.

Последнее замечание: без знания особенностей вашей архитектуры … как правило, MVC будет обрабатывать всю обработку событий как часть представления (это уменьшает связь), и представление будет передавать команды или вызовы методов или ваши собственные события (т. Е. не Swing) контроллеру.

Комментарии:

1. Вкратце добавлю к этому: с точки зрения ООП, if утверждения обычно указывают на то, что ваш дизайн мог бы быть лучше.