2017-02-11 32 views
0

Привет Я новичок в Java Swing.Java Swing-Call-actionlisner от внешнего класса

Иметь класс Свинг следующим образом-

Class A extends JDialog 
{ 

JButton button=new JButton(" test"); 
button.addActionListener(new TestAction()); 

//Inner class 
private class TestAction extends AbstractAction { 

     public void actionPerformed(final ActionEvent e) { 
      dispose(); 
     } 
    } 
} 

Приведенный выше код работает хорошо. Необходимо переместить внутренний класс TestAction как обычный java-файл, чтобы его можно было повторно использовать.

public class TestActionNew extends AbstractAction { 

    JFrame frame; 

    TestActionNew() { 
     this.frame = new JFrame(); 

    } 

    public void actionPerformed(final ActionEvent e) { 
     frame.dispose(); 
    } 
} 

Добавлен новый слушатель на кнопку button.addActionListener (новый TestActionNew())

Но действие отчуждать не работает. Может кто-нибудь помочь, что я делаю неправильно здесь. Благодаря

ответ

2

Вы уход за созданием другого кадра и вызов dispose на том, что, в то время как вложенный класс, dispose вызываются вмещающим экземпляр.

Если вы хотите, чтобы сделать его многоразовым, вы должны передать вещь, на которую назвать dispose в конструктор:

public class TestActionNew extends AbstractAction { 

    JFrame frame; 

    TestActionNew (JFrame frame) { 
     this.frame = frame; 

    } 

    public void actionPerformed(final ActionEvent e) { 
     frame.dispose(); 
    } 
} 

Затем в другое использование кода:

JButton button = new JButton(" test"); 
button.addActionListener(new TestAction(this)); 
+0

Почему бы не настроить 'Action', чтобы быть автономным, задать имя и другие свойства, то вам просто нужно вызвать 'new JButton (новый MySuperAwesomeAction()) ... это также позволит вам использовать его с привязками клавиш и элементами меню, похоже, много перехитрит в противном случае – MadProgrammer

2

Вы могли бы ...

Предоставить ActionListener подпорку напрямую ...

class A extends JDialog { 

    JButton button = new JButton(" test"); 

    public A() { 
    } 

    public void addActionListener(ActionListener listener) { 
     button.addActionListener(listener); 
    } 

    public void removeActionListener(ActionListener listener) { 
     button.removeActionListener(listener); 
    } 

} 

Это, как правило, подвергать элементы (т.е. кнопки) для других классов и предполагает, что они знают о внутренней реализации (т.е. actionCommand) диалогового

Вы могли бы ...

обеспечивают возможность поставлять на заказ Action s

class A extends JDialog { 
    //... 
    public void addAction(Action action) { 
     JButton btn = new JButton(action); 
     buttonPanel.add(btn); 
    } 
} 

Это означает, что диалог не нужно заботиться «что такое» Action делает, он просто обеспечивает средства для выполнения его, Action обеспечить са самодостаточной единицы работы, которые необходимо сделать, чтобы получить

Например, дано Action как ...

public class CancelAction extends AbstractAction { 

    public CancelAction() { 
     putValue(NAME, "Cancel"); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     // What ever needs to be done here... 
    } 

} 

Вы бы использовать что-то вроде ...

A dialog = A(); 
dialog.addAction(new CancelAction()); 

Теперь, очевидно, вы могли бы настроить действие на свои нужды, передавая любую информацию, необходимую для работы Action, но диалог не волнует

Вы co uld ...

Создайте предопределенный интерфейс, который определяет действия, которые диалог готов выполнить ...

public interface AListener { 
    public void wasCancelled(A dialog); 
    public void wasAccepted(A dialog); 
} 

Вы бы затем прикрепить этот приемник к экземпляру A и принять соответствующие меры, если он выполняется

class A extends JDialog { 
    //...  
    private Set<AListener> listeners = new HashSet<>(); 

    public void addAListener(AListener listener){ 
     listeners.add(listener); 
    } 

    public void removeAListener(AListener listener){ 
     listeners.add(listener); 
    } 

    protected void fireWasCancelled() { 
     for (AListener listener : listeners) { 
      listener.wasCancelled(this); 
     } 
    } 

    protected void fireWasAcceppted() { 
     for (AListener listener : listeners) { 
      listener.wasAccepted(this); 
     } 
    } 
} 

Так что, когда некоторые «действие» происходит в диалоговом окне (например, кнопка была нажата) , вы могли бы назвать соответствующий fireXxx метод сообщать о любых зарегистрированных слушателей

A aDialog = new A(); 
aDialog.addAListener(new AListener() { 
    @Override 
    public void wasCancelled(A dialog) { 
     // Do stuf 
    } 

    @Override 
    public void wasAccepted(A dialog) { 
     // Do stuff 
    } 
}); 

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

Вы могли бы ...

Просто используйте JOptionPane, которая обеспечивает автономный API для отображения информации для пользователя и предоставить вам с обратной связью по тому, что пользователь сделал

Что вы должны использовать .. .?

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

Лично я предпочитаю использовать Action, так как это автономный многоразовый блок работы, который можно использовать с кнопками, привязками клавиш и пунктами меню, делая их очень гибкими, но если вы просто имеете диалоговое окно, которое имеет Кнопка «ok»/«cancel» может быть чуть более убита.

Вы можете взять вторую идею и просто обеспечивают функциональность, которая позволяет настраивать «ОК» и «отменить» действия напрямую, а не гибкость, чтобы поставить то, что когда-либо действия, которые вы хотите, в качестве примера

I 'd также рекомендуем вам взглянуть на How to Use Actions, так как вы, похоже, не полностью поняли силу этого API еще