【问题标题】:Java ActionListeners to stand-alone classesJava ActionListeners 到独立类
【发布时间】:2014-06-20 12:07:52
【问题描述】:

有没有办法将 actionListener 类移动到独立类?

我使用 Java 和 MVC 设计模式做了一个例子。我有 3 个更改背景颜色的按钮。

这是模型

public class ChangeFontColorApplicationModel {
    public ChangeFontColorApplicationModel(){}
}

查看

import java.awt.event.*;
import javax.swing.*;

public class ChangeFontColorApplicationView extends JFrame{
private JButton changeToYellowButton = new JButton("Yellow font");
private JButton changeToBlackButton = new JButton("Black font");
private JButton changeToBlueButton = new JButton("Blue font");

public ChangeFontColorApplicationView(){
    super("Change font");
    JPanel buttonPanel = new JPanel();

    buttonPanel.add(changeToYellowButton);
    buttonPanel.add(changeToBlackButton);
    buttonPanel.add(changeToBlueButton);

    this.add(buttonPanel);
}

public void addButtonActionListener(){
    changeToYellowButton.addActionListener(new yellowBackgroundHandler());
    changeToBlackButton.addActionListener(new yellowBackgroundHandler());
    changeToBlueButton.addActionListener(new yellowBackgroundHandler());
}
}

控制器

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ChangeFontColorApplicationController {
private ChangeFontColorApplicationView changeFontColorApplicationViewObject;
backgroundHandler yellowBackgroundHandlerObject = new yellowBackgroundHandler();
backgroundHandler blackBackgroundHandlerObject = new blackBackgroundHandler();
backgroundHandler blueBackgroundHandlerObject = new blueBackgroundHandler();

public ChangeFontColorApplicationController(ChangeFontColorApplicationView changeFontColorApplicationViewObject){
    this.changeFontColorApplicationViewObject = changeFontColorApplicationViewObject;

    yellowBackgroundHandlerObject.setNextHandlerInChain(blackBackgroundHandlerObject);
    blackBackgroundHandlerObject.setNextHandlerInChain(blueBackgroundHandlerObject);

    this.changeFontColorApplicationViewObject.addButtonActionListener();
}
}

现在我创建了一个处理按钮事件的接口

public interface backgroundHandler extends ActionListener{
public void setNextHandlerInChain(backgroundHandler nextInChain);
public void handleCommand(String getActionCommandString);
public void actionPerformed(ActionEvent event);
}

每个实现接口的类都处理 ActionEvent。如果不能,则传递给下一个类(作为责任链)

黄色字体处理程序

import java.awt.Color;
import java.awt.event.ActionEvent;

public class yellowBackgroundHandler implements backgroundHandler{
private backgroundHandler nextInChain;
private ChangeFontColorApplicationView ChangeFontColorApplicationViewObject = new ChangeFontColorApplicationView();

public yellowBackgroundHandler(){}

@Override
public void setNextHandlerInChain(backgroundHandler nextInChain) {
    this.nextInChain = nextInChain;
}

@Override
public void handleCommand(String getActionCommandString) {
    if(getActionCommandString.equalsIgnoreCase("Yellow font")){
        ChangeFontColorApplicationViewObject.setBackground(Color.yellow);
    }
    else {
        nextInChain.handleCommand(getActionCommandString);
    }
}

@Override
public void actionPerformed(ActionEvent event) {
    try{
        handleCommand(event.getActionCommand());
    }
    catch (Exception exeption){
        ChangeFontColorApplicationViewObject.setTitle(exeption.toString());            
    }
}
}

黑色字体处理程序

import java.awt.Color;
import java.awt.event.ActionEvent;

public class blackBackgroundHandler implements backgroundHandler{
private backgroundHandler nextInChain;
private ChangeFontColorApplicationView ChangeFontColorApplicationViewObject = new ChangeFontColorApplicationView();

public blackBackgroundHandler(){}

@Override
public void setNextHandlerInChain(backgroundHandler nextInChain) {
    this.nextInChain = nextInChain;
}

@Override
public void handleCommand(String getActionCommandString) {
    if(getActionCommandString.equalsIgnoreCase("Black font")){
        ChangeFontColorApplicationViewObject.setBackground(Color.BLACK);
    }
    else {
        nextInChain.handleCommand(getActionCommandString);
    }
}

@Override
public void actionPerformed(ActionEvent event) {
    try{
        handleCommand(event.getActionCommand());
    }
    catch (Exception exeption){
        ChangeFontColorApplicationViewObject.setTitle(exeption.toString());            
    }
}
}

蓝色字体处理程序

import java.awt.Color;
import java.awt.event.ActionEvent;

public class blueBackgroundHandler implements backgroundHandler{
private backgroundHandler nextInChain;
private ChangeFontColorApplicationView ChangeFontColorApplicationViewObject = new ChangeFontColorApplicationView();

public blueBackgroundHandler(){}

@Override
public void setNextHandlerInChain(backgroundHandler nextInChain) {
    this.nextInChain = nextInChain;
}

@Override
public void handleCommand(String getActionCommandString) {
    if(getActionCommandString.equalsIgnoreCase("Μπλε φόντο")){
        ChangeFontColorApplicationViewObject.setBackground(Color.BLUE);
    }
    else {
        ChangeFontColorApplicationViewObject.setTitle("This is the back end of COR");
    }
}

@Override
public void actionPerformed(ActionEvent event) {
    try{
        handleCommand(event.getActionCommand());
    }
    catch (Exception exeption){
        ChangeFontColorApplicationViewObject.setTitle(exeption.toString());            
    }
}
}

最后我用main方法创建了类

public class ChangeFontColorApp {
public static void main(String[] args){
    ChangeFontColorApplicationView changeFontColorApplicationViewObject = new ChangeFontColorApplicationView();
    ChangeFontColorApplicationController changeFontColorApplicationControllerObject = new ChangeFontColorApplicationController(changeFontColorApplicationViewObject);

    changeFontColorApplicationViewObject.setVisible(true);
    changeFontColorApplicationViewObject.setSize(600, 600);
       changeFontColorApplicationViewObject.setDefaultCloseOperation(ChangeFontColorApplicationView.EXIT_ON_CLOSE);
}
}

有什么办法可以做到这一点吗?我不想有一个用于事件处理的内部类,其中包含多个 if blick。任何建议将不胜感激。

【问题讨论】:

  • 请阅读How to create a Minimal, Complete, and Verifiable example。代码墙很糟糕。没有人愿意阅读所有内容。
  • 是的,你可以写一个动作控制器类。您的控制器不必是一类。它可以是多个类,每个类都响应某个动作。查看我的2048 Game in Java Swing 文章,了解使用 MVC 创建 Java Swing 应用程序的一种方法。
  • 好吧,伙计们,我会读两个。感谢您的建议

标签: java swing design-patterns observer-pattern chain-of-responsibility


【解决方案1】:

那是行不通的。但是,问题不是因为你有独立的类(使用独立的类很好)。相反,问题是:

在视图类中,您有:

public void addButtonActionListener(){
    changeToYellowButton.addActionListener(new yellowBackgroundHandler());
    changeToBlackButton.addActionListener(new yellowBackgroundHandler());
    changeToBlueButton.addActionListener(new yellowBackgroundHandler());
}

这意味着所有按钮的点击都由 YellowBackgroundHandler 处理。但是,yellowBackgroundHandler 只接受来自 changeToYellowButton 的点击。除此之外,yellowBackgroundHandler 没有配置下一个处理程序。

要解决此问题,请在视图类中更改:

public void addButtonActionListener(){
    changeToYellowButton.addActionListener(new yellowBackgroundHandler());
    changeToBlackButton.addActionListener(new yellowBackgroundHandler());
    changeToBlueButton.addActionListener(new yellowBackgroundHandler());
}

public void addButtonActionListener(backgroundHandler handler){
    changeToYellowButton.addActionListener(handler);
    changeToBlackButton.addActionListener(handler);
    changeToBlueButton.addActionListener(handler);
}

在控制器类中,改变这个:

this.changeFontColorApplicationViewObject.addButtonActionListener();

this.changeFontColorApplicationViewObject.addButtonActionListener(yellowBackgroundHandlerObject);

我看到的另一个问题是,yellowBackgroundHandler、blackBackgroundHandler 和 blueBackgroundHandler 有私有变量 ChangeFontColorApplicationViewObject,它指向自己的 ChangeFontColorApplicationView 实例。我们需要这个变量指向在 main 方法中创建的实例。为此,请更改:

private ChangeFontColorApplicationView ChangeFontColorApplicationViewObject = new ChangeFontColorApplicationView();
public blueBackgroundHandler(){}

到:

private ChangeFontColorApplicationView ChangeFontColorApplicationViewObject;
public blueBackgroundHandler(ChangeFontColorApplicationView ChangeFontColorApplicationViewObject){
  this.ChangeFontColorApplicationViewObject = ChangeFontColorApplicationViewObject;
}

并改变这个:

private ChangeFontColorApplicationView ChangeFontColorApplicationViewObject = new ChangeFontColorApplicationView();
public blackBackgroundHandler(){}

到:

private ChangeFontColorApplicationView ChangeFontColorApplicationViewObject;
public blackBackgroundHandler(ChangeFontColorApplicationView ChangeFontColorApplicationViewObject){
  this.ChangeFontColorApplicationViewObject = ChangeFontColorApplicationViewObject;
}

并改变这个:

private ChangeFontColorApplicationView ChangeFontColorApplicationViewObject = new ChangeFontColorApplicationView();
public blueBackgroundHandler(){}

到:

private ChangeFontColorApplicationView ChangeFontColorApplicationViewObject;
public blueBackgroundHandler(ChangeFontColorApplicationView ChangeFontColorApplicationViewObject){
  this.ChangeFontColorApplicationViewObject = ChangeFontColorApplicationViewObject;
}

最后,改变这个:

backgroundHandler yellowBackgroundHandlerObject = new yellowBackgroundHandler();
backgroundHandler blackBackgroundHandlerObject = new blackBackgroundHandler();
backgroundHandler blueBackgroundHandlerObject = new blueBackgroundHandler();

public ChangeFontColorApplicationController(ChangeFontColorApplicationView changeFontColorApplicationViewObject){
    this.changeFontColorApplicationViewObject = changeFontColorApplicationViewObject;

    yellowBackgroundHandlerObject.setNextHandlerInChain(blackBackgroundHandlerObject);
    blackBackgroundHandlerObject.setNextHandlerInChain(blueBackgroundHandlerObject);

    this.changeFontColorApplicationViewObject.addButtonActionListener();
}

backgroundHandler yellowBackgroundHandlerObject = new yellowBackgroundHandler();
backgroundHandler blackBackgroundHandlerObject = new blackBackgroundHandler();
backgroundHandler blueBackgroundHandlerObject = new blueBackgroundHandler();

public ChangeFontColorApplicationController(ChangeFontColorApplicationView changeFontColorApplicationViewObject){
    this.changeFontColorApplicationViewObject = changeFontColorApplicationViewObject;
    this.yellowBackgroundHandlerObject = new yellowBackgroundHandler(this.changeFontColorApplicationViewObject);
    this.blackBackgroundHandlerObject = new blackBackgroundHandler(this.changeFontColorApplicationViewObject);
    this.blueBackgroundHandlerObject = new blueBackgroundHandler(this.changeFontColorApplicationViewObject);

    yellowBackgroundHandlerObject.setNextHandlerInChain(blackBackgroundHandlerObject);
    blackBackgroundHandlerObject.setNextHandlerInChain(blueBackgroundHandlerObject);

    this.changeFontColorApplicationViewObject.addButtonActionListener(this.changeFontColorApplicationViewObject);
}

【讨论】:

  • 恐怕这也不起作用...会不会是因为在将按钮添加到 buttonPanel 之前,在控制器中而不是视图中添加了 actionListeners?
  • 也许您可以详细说明“也没有工作”?黄色按钮有用吗?
  • 不,它没有...更具体地说,我发现事件卡在 EventDispatchThread.java,pumpEventsForFilter 方法中的 while 循环中。进入循环后,调试就停留在那里。我不能再跨过去了。这就像它无法摆脱while循环并停止调试。那可能是什么?每个按钮都是一样的。
  • 我发现了另一个问题。我刚刚更新了答案。告诉我进展如何。
  • 在最后一个表达式this.changeFontColorApplicationViewObject.addButtonActionListener(this.changeFontColorApplicationViewObject); addButtonActionListener() 方法接受一个 backgroundHandler 参数。我该怎么投呢?还有别的东西:backgroundHandler yellowBackgroundHandlerObject = new yellowBackgroundHandler(); backgroundHandler blackBackgroundHandlerObject = new blackBackgroundHandler(); backgroundHandler blueBackgroundHandlerObject = new blueBackgroundHandler(); 的声明不应该有所不同吗?他们的构造函数现在接受一个论点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-09
相关资源
最近更新 更多