2013-07-11 4 views
1

Итак, как правило, я программист на C, C++ и C#, причем большинство моих графических интерфейсов в C# WPF. Я был помещен в проект, который использует Java, и я нахожу свой словарь для C#, который не хорошо сочетается с Java.Действия Java Clarification

Одна проблема, с которой я столкнулся, касается JButtons и, предположительно, всего, что называется «делегатами» на C#. Из этого example есть этот кусок кода:

jbnButton1.addActionListener(new ActionListener() 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
     jtfInput.setText("Button 1!"); 
    } 
}); 

Просто, что это называется, где функция определена в качестве параметра (или передается в качестве параметра)? Кроме того, это лучшая практика? В проекте, в котором я включен, функция Initialize() заполнена такими функциями, как кнопки, флажки и т. Д., Что делает ее довольно неудобной. Я бы предпочел иметь определение на уровне класса, а не в Initialize().

Что приводит меня к другому example (пример верхнего кода). С помощью этих строк коды:

b1.addActionListener(this); 
    b3.addActionListener(this); 
... 
} 

public void actionPerformed(ActionEvent e) { 
    if ("disable".equals(e.getActionCommand())) { 
     b2.setEnabled(false); 
     b1.setEnabled(false); 
     b3.setEnabled(true); 
    } else { 
     b2.setEnabled(true); 
     b1.setEnabled(true); 
     b3.setEnabled(false); 
    } 
} 

По сути, код присваивает действие для одной кнопки, b1, и кнопки три, b3 в тот же обработчик событий, который определен в объеме, я предпочитаю (за пределами того, где кнопки инициализируются). Есть ли способ заставить их указывать на разные функции? Кроме того, по телефону

.addActionListener(this); 

Как фигура компилятор, чтобы использовать actionPerformed (ActionEvent е) в этом? Является ли что-то предопределенным, которое говорит, что действия решат «actionPerformed (ActionEvent e)»?

+0

для вашего второго вопроса: это текущий класс, который должен реализовывать интерфейс ActionListener. Компилятор не «вычисляет», чтобы использовать actionPerformed. Вместо этого addActionListener требует, чтобы этот параметр реализовал интерфейс ActionListener, который включает метод actionPerformed(). Используйте ActionEvent.getSource(), чтобы определить, было ли нажато b1 или b3, затем вызовите соответствующий метод из метода actionPerformed. – DwB

ответ

1

Ваш первый пример называется Анонимный класс. Он часто используется для прослушивателей (например, ActionListener s), но его следует использовать только в том случае, если вам никогда не нужно удалять слушателя, так как нет ссылки.

Для второй части вопроса компилятор не выясняет, когда позвонить actionPerformed.Он объявлен в ActionListenerdocumentation:

Когда событие происходит действие, метод actionPerformed этого объекта вызывается.

Таким образом, он несет ответственность за JButton «s вызвать actionPerformed на всех ActionListener с, которые были добавлены к нему всякий раз, когда происходит действие.

Невозможно сделать b1 и b3 указать разные способы. Это хороший пример того, где анонимный класс будет делать для лучшего дизайна:

b1.addActionListener(new ActionListener() 
{ 
    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     b2.setEnabled(false); 
     b1.setEnabled(false); 
     b3.setEnabled(true); 
    } 
}); 

b3.addActionListener(new ActionListener() 
{ 
    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     b2.setEnabled(true); 
     b1.setEnabled(true); 
     b3.setEnabled(false); 
    } 
}); 

Предполагая, что b1 имеет этикетку «отключить». Затем this больше не нужно будет реализовывать ActionListener.

1

Первый пример, который вы даете, называется «анонимным внутренним классом». Вы определяете анонимный подкласс класса ActionListener, переопределяя его метод actionPerformed, создавая его экземпляр (создавая экземпляр этого подкласса), а затем передавая ссылку на этот экземпляр методу jbnButton1.addActionListener. Это ближайшая Java на сегодняшний день имеет «закрытие» (по крайней мере до Java 8).

Это идиоматическое, когда слушатель действия прост, но вы можете перекодировать это как

class MyListener extends ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
     jtfInput.setText("Button 1!"); 
    } 
} 
... 
jbnButton1.addActionListener(new MyListener()); 

, но тогда вы, возможно, придется организовать конструктор MyListener принять и сохранить jtfInput ссылку. Встроенное определение упрощает это. Но для более сложной ситуации вы можете захотеть определить класс вне линии.

Что касается второго вопроса:

.addActionListener(this); 

Класс, в котором это, кажется, должен реализовать интерфейс ActionListener, поэтому он должен иметь actionPerformed() метод. Это то, что позволяет фреймворку «знать», что вызывать.

1

Для вашего второго кода, например:

Он знает, использовать это actionperformed(), потому что класс используется для добавления actionlistener -s к кнопкам, реализующего интерфейс ActionListener

и если вы передаете addActionListener метод ваш собственный класс (это), где вы должны реализовать actionPerformed метод, он работает так же, как anonymous classes, потому что это ActionListener

метод addActionListener знает s он имеет метод actionPerformed (он должен быть один), поэтому он будет автоматически называть это