简体   繁体   中英

JFrame subclass and ActionListener interface implementation

为什么extends JFrame implements ActionListener一个糟糕的设计决策?

A couple points:

  • Extending a JFrame is probably a wrong approach
  • Implementing an ActionListener on an JFrame probably will lead to non-OOP code.

Wrong Approach?

If the idea is that an GUI application is being made, then, one is not making an extension of a JFrame , but actually writing an application.

Therefore, the JFrame would be part of an application, not the application itself. Hence, the JFrame should be an object in the class.

Implementing an ActionListener on an JFrame probably will lead to non-OOP code

Consider the following case -- as the GUI application is starting to get large, and we're starting to add lots of buttons and menus which give rise to ActionEvent s.

If the JFrame itself were to get the events, then what would the actionPerformed method look like?

Probably something like this:

public void actionPerformed(ActionEvent e) {
  Object source = e.getSource();

  // Find out which component fired the event
  if (source == masterButton) {
    // ... do something
  } else if (source == anotherButton) {
    // ... do something else
  } else if (...)
    // ... and so on ...
  } else if (...)
    // ... and so on ...
  }
}

Yikes.

We're going to start getting code that's tightly coupled to all the components in the application, and maintainability will be out the window in no time.


If, for example, the GUI application had instances of ActionLister s which responded to each component, then we'd be able to break up the actions and the coupling of the actionPerformed method with all the components in the GUI.

For example:

JButton masterButton = new JButton();
masterButton.addActionListener(new MasterButtonActionListener());

JButton anotherButton = new JButton();
anotherButton.addActionListener(new AnotherButtonActionListener());

This way, there will be ActionListeners for each button which presumably have different functionality. The responsibility of the MasterButtonActionListener would be to handle events from the masterButton -- it doesn't have to know about other buttons in the application.

Also, this would promote reusability of the components in other applications or other part of the application without having to copy-and=paste parts of the monolithic if-else statement in the actionPerformed method.

If you read Effective Java, item 16 states:

" Favor composition over inheritence "

. Read the explanation given here

我相信这是一个糟糕的设计..因为,你将控制器代码与视图混合..如果你想跟随mvc模式,你不应该混合它们..

Additionally, A JFrame generally doesn't receive actions. Its child objects would be the benefactors of an ActionEvent .

A better and more OO approach would be to have separate Action objects. This allows you to separate functionality and state from a component. It makes your code reusable because you can use the same action on a button as well as menu item, for instance.

Example:

class ExitAction extends AbstractAction{    
    public ExitAction(){
        super("Exit");
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Exiting");
    }
}

JButton exitButton = new JButton(new ExitAction());

Take a look at How to Use Actions in the Java Tutorial:

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