2016-01-16 5 views
1

Итак, у меня есть три класса. 1.) Программный драйвер - основной класс 2.) TopPanel 3.) Frame My Action Listener для выхода из системы работает нормально, но я просто подумал, может быть, есть лучший способ разделить блоки для прослушивателей действий. Пожалуйста, несите меня, поскольку я новичок в этом. Каков наилучший способ отделить блок «Слушатели»? Нужно ли мне каждый раз внедрять Action Listener в класс или я могу сделать то же самое, что и здесь?Что такое подходящее место, чтобы включить блок списка действий

Вот мой код. TopPanel класс

public class TopPanel extends JPanel{ 
//DECLARATION 

JButton logOutButton = new JButton("Logout"); 
TopTabbedPane topTabbedPane = new TopTabbedPane(); 
private final Border myLineBorder = BorderFactory.createLineBorder(Color.BLACK, 2); 

//CONSTRUCTOR  
public TopPanel(){ 
    setPanelInitialProperties(); 
    addComponents(); 

} 

//METHODS 
private void setPanelInitialProperties(){ 
    setLayout(new GridBagLayout()); 
    setBorder(myLineBorder); //sets a Line Border for this panel 
    //setBackground(Color.red); 
} 

private void addComponents(){ 
    GridBagConstraints topTabbedPaneGBC = new GridBagConstraints(); 
    GridBagConstraints logOutButtonGBC = new GridBagConstraints(); 

    topTabbedPaneGBC.gridx = 0; 
    topTabbedPaneGBC.gridy = 1; 
    topTabbedPaneGBC.anchor = GridBagConstraints.CENTER; 
    this.add(topTabbedPane,topTabbedPaneGBC); //adds TabbedPane holding Home, Administration... to this Top Panel 

    logOutButton.addActionListener(new ActionListener(){ 
     @Override 
     public void actionPerformed(ActionEvent e){ 
      int logOutChoice = JOptionPane.showConfirmDialog(null, "Do you want to logout?"); 
      if(logOutChoice == 0){ 
       System.exit(0); 
      } 
     } 
    }); 

    logOutButtonGBC.gridx = 0; 
    logOutButtonGBC.gridy = 0; 
    logOutButtonGBC.anchor = GridBagConstraints.FIRST_LINE_END; 
    this.add(logOutButton,logOutButtonGBC); 
} 


} 

А вот для класса кадра

public class TopFrame extends JFrame { 
//DECLARATION 
TopPanel topPanel = new TopPanel(); //create an object 

//CONSTRUCTOR 1: 
public TopFrame(){ 
    setFrameInitialProperties(); 
    addComponentsToPane(); 
} 

//METHOD 1: 
private void setFrameInitialProperties(){ 
    this.setLayout(new BorderLayout()); 
    this.setResizable(true); 
    this.setPreferredSize(new Dimension(1300,700)); //set it's dimensions or it's size 
    this.setVisible(true); //sets it's initial visibility to true so it shows on the screen when objects are created from this class 
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    this.setTitle("Enrollment System"); 

    //always put pack() first before setLocationRelativeTo(null) 
    this.pack(); 
    this.setLocationRelativeTo(null); 
} 
//METHOD 2: 
private void addComponentsToPane(){ 
    Container myContainer = this.getContentPane(); //stores the Frame to a Container we named myContainer 
     myContainer.add(topPanel); //adds one panel which we named topPanel 
} 
} 

Я бы признателен за любые пояснения или примеры.

Спасибо.

ответ

1

Много подходит для контекста.

С включением внутренних и анонимных классов создание ActionListener s стало проще, выражение лямбда также может уменьшить массу беспорядка (но IMHO может затруднить чтение и выяснение контрактов API).

В вашем случае, когда содержимое ActionListener занимает всего несколько строк, поэтому анонимный класс, как и у вас, более чем подходит, он изолирован и контекстуаль (теперь представьте, что вам пришлось выкапывать отдельный класс просто чтобы увидеть эти несколько строк: P)

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

Единственный раз, когда я могу использовать внешний класс, является функциональность ActionListener в некотором роде, но тогда я бы использовал Actions API, которые являются автономными единицами работы. Проблема здесь заключается в том, что вам необходимо предоставить им контекст, передав ссылку объекта, который содержит методы/поля, с которыми вам нужно работать, на этом этапе вам необходимо принять тщательные решения о вашем дизайне, и именно здесь interfaces может действительно помочь

Таким образом, на основе текущей функциональности, вы можете создать «общий», «Выход» действия, к примеру ...

public class LogoutAction extends AbstractAction { 

    private LogoutAction parent; 

    public CloseAction(String name, Component parent) { 
     super(name); 
     this.parent = parent; 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     int logOutChoice = JOptionPane.showConfirmDialog(parent, "Do you want to logout?"); 
     if (logOutChoice == JOptionPane.OK_OPTION) { 
      SwingUtilities.windowForComponent(parent).dispose(); 
     } 
    } 

} 

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

public class TopPanel extends JPanel{ 

    private JButton logOutButton; 

    //... 
    private void addComponents() { 
     //... 
     logOutButton = new JButton(new LogoutAction(this, "Logout")); 
     //... 

И это было бы , когда кнопка будет нажата, появится вопрос, и если пользователь выберет Ok, соответствующее окно будет закрыто (и если это последнее окно, то оно сконфигурировано для закрытия при выходе, JVM выйдет)

Смежные вопросы