Слушатель действия в другом классе - Java
Можно иметь два класса, а в одном что-то вроде
arrayButtons[i][j].addActionListener(actionListner);
и в другом
ActionListener actionListner = new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int j = 0; j < arrayButtons.length; j++) {
for (int i = 0; i < arrayButtons[j].length; i++) {
if (arrayButtons[j][i] == e.getSource()) {
if ((gameNumber == 2) && (playHand.getNumberOfCards() == 0)) {
if (player[j].getCard(i).getSuit() == Suit.HEARTS.toString() && player[j].hasSuitBesideHearts())
//second game
messageOnTable("xxx");
else{
arrayButtons[j][i].setVisible(false);
test[j].setIcon(player[j].getCard(i).getImage());
pnCardNumber[j].setText(Integer.toString(player[j].getCard(i).getNumber()));
pnCardName[j].setText(player[j].getCard(i).toString());
pnCardSuit[j].setText(player[j].getCard(i).getSuit());
playHand.addCard(player[j].getCard(i), j);
player[j].removeCard(i);
}
}
}
// и еще одна причина этого в том, что мне нужно отделить кнопку (свинг) от слушателя действия
как я могу сделать?
Спасибо
5 ответов
Не только возможно разделить эти два, но и рекомендуется (см. Шаблон MVC - речь идет о разделении элементов управления экрана, таких как кнопки, и логики вашей программы).
Самый простой способ, который приходит мне в голову - это написать именованный класс, который реализует ActionListener
интерфейс, что-то вроде этого:
public class SomeActionListener implements ActionListener{
private JTextField textField1;
private JComboBox combo1;
private JTextField textField2;
//...
public SomeActionListener(JTextField textField1, JComboBox combo1,
JTextField textField2){
this.textField1=textField1;
this.combo1=combo1;
this.textField2=textField2;
//...
}
public void actionPerformed(ActionEvent e) {
//cmd
}
}
И затем добавьте это к своим кнопкам:
ActionListener actionListener = new SomeActionListener(textField1, combo1, textField2);
someButton.addActionListener(actionListener);
Чтобы ответить: "Моя проблема в том, что слушатель действия имеет много переменных, например, таких как кнопки свинга, поэтому, когда я перехожу на другой класс, у меня возникают проблемы с этим"
Ваш класс слушателя действия может иметь конструктор, который принимает параметр типа класса представления:
public class Listener implements ActionListener {
private final MyViewClass mView;
public Listener(MyViewClass pView) {
mView = pView;
}
public void actionPerformed(ActionEvent e) {
// can use mView to get access to your components.
mView.get...().doStuff...
}
}
Тогда по вашему мнению:
Listener l = new Listener(this);
button.addActionListener(l);
Вы можете легко сделать это, используя вложенные классы, но я думаю, что лучший способ - передать родительский объект в качестве параметра для конструкции объекта и использовать его в качестве обработчика действий;
//**parent class - Calculator **//
public class Calculator extends JFrame implements ActionListener{
private DPanel dPanel;
private JTextField resultText;
public Calculator(){
// set calc layout
this.setLayout(new BorderLayout(1,1));
dPanel = new DPanel(this); // here is the trick ;)
}
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
resultText.setText(command);
// **** your code ****/
}
}
//**inner class - DPanel**//
public class DPanel extends JPanel{
private JButton digitsButton[];
private JButton dotButton,eqButton;
public DPanel(Calculator parent){
//layout
this.setLayout(new GridLayout(4,3,1,1));
// digits buttons
digitsButton = new JButton[10];
for (int i=9;i>=0;i--){
digitsButton[i] = new JButton(i+"");
digitsButton[i].addActionListener(parent); // using parent as action handler ;)
this.add(digitsButton[i]);
}
}
}
Это немного не по теме, но вы определенно не должны использовать ==
оператор для сравнения String
s, как вы, кажется, делаете в этой строке:
if (player[j].getCard(i).getSuit() == Suit.HEARTS.toString()
Это потому что String
Это указатели, а не фактические значения, и вы можете получить неожиданное поведение, используя ==
оператор. Использовать someString.equals(otherString)
метод вместо. А также
"String to compare".equals(stringVariable)
намного лучше, чем наоборот
stringVariable.equals("String to compare to")
потому что в первом примере вы избегаете получения NullPointerException, если stringVariable
нулевой. Это просто возвращает ложь.
Да, это может быть сделано. Это очень просто; в одном классе у вас есть кнопки, в другом - вам просто нужно реализовать ActionListener и просто сделать //cmd для разделения функции этой кнопки. Для этого вам нужно использовать e.getActionCommand(). Equals(buttonActionCommand). Образец кода:
public class Click implements ActionListener{
public Click(
//input params if needed
){
}
public void actionPerformed(ActionEvent e) {
if( e.getActionCommand().equals(buttonActionCommand){
//cmd
}
}
}
Чтобы добавить этого слушателя на вашу кнопку просто сделайте:
buttonTest.addActionListener(new Click());