简体   繁体   中英

Where to put action listeners?

I'm a little confused about where the best class is for ActionListener instances in a small Swing application.

If I have a Controller , a MainFrame for the main JFrame and various JPanel containers such as LeftPanel , RightPanel etc, each with buttons, a list etc.

Where's the best place to put the action listeners? Should I have them in the same class as the components (as an inner class or class implementing action listener), in the MainFrame as this is the 'parent' of all the panels, or in the Controller , which really only has the main() method and a few other Swing details?

Each approach seems to have its pros and cons. I am trying to un-couple features from functionality but I'm finding it hard to work this out.

Or have I missed another (better) way?

One possible for the panels to communicate with each other is through the main frame. Each panel would have a reference to the main frame and the main frame provides all the operations such as reading data from the form, updating data to the form. Below is an example:

class UserForm extends JPanel {
    private final MyApp app;
    private final JTextField userNameField = new JTextField(20);
    public UserForm(MyApp app){
        this.app = app;
        this.add(userNameField);
    }
    public String getUserName(){
        return userNameField.getText();
    }
    public void setUserName(String name){
        userNameField.setText(name);
    }
}
class FormControl extends JPanel {
    private final MyApp app;
    private final JButton randNameButton = new JButton("Random");
    private final JButton saveButton = new JButton("Save");
    private final String[] names = {"john", "mike", "bill", "joe"};
    private final Random r = new Random();
    public FormControl(MyApp app){
        this.app = app;
        this.setLayout(new FlowLayout());
        this.add(randNameButton);
        this.add(saveButton);
        randNameButton.addActionListener(e->app.setUserName(names[r.nextInt(4)]));
        saveButton.addActionListener(e->app.save());
    }
}
public class MyApp extends JFrame{
    private final UserForm form = new UserForm(this);
    private final FormControl control = new FormControl(this);
    public MyApp(){
        this.setTitle("Demo");
        this.setSize(200, 100);
        JPanel pane = new JPanel();
        pane.setSize(200,100);
        pane.setLayout(new BorderLayout());
        pane.add(form, BorderLayout.NORTH);
        pane.add(control, BorderLayout.SOUTH);
        this.setContentPane(pane);
    }
    
    // all the operations are here.
    public String getUserName(){
        return form.getUserName();
    }
    public void setUserName(String userName){
        form.setUserName(userName);
    }
    public void save(){
        System.out.println("Saving");
        System.out.println(getUserName());
        System.out.println("Done saving.");
    }
    public static void main(String[] args) {
        new MyApp().setVisible(true);
    }
}

I would use lambda for action listener. See example below:

public class JavaApplication7 extends JFrame{
    public JavaApplication7(){
        this.setTitle("Demo");
        this.setSize(100, 100);
        JButton b = new JButton("Click");
        b.addActionListener(e->{
            System.out.println("hello");
            System.out.println("from " + this.getTitle());
        });
        this.setContentPane(b);
    }

    public static void main(String[] args) {
        new JavaApplication7().setVisible(true);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM