如何将命令模式与JavaFX GUI结合使用?

时间:2017-12-02 22:12:12

标签: java oop javafx actionevent

我当前的控制器类

public class Controller {
    @FXML
public javafx.scene.image.ImageView imageView;


@FXML
private MenuItem openItem;

@FXML
public void openAction(ActionEvent event) {
    FileChooser fc = new FileChooser();
    File file = fc.showOpenDialog(null);
    try {
        BufferedImage bufferedImage = ImageIO.read(file);
        Image image = SwingFXUtils.toFXImage(bufferedImage, null);
        imageView.setImage(image);
    } catch (IOException e) {
        System.out.println("lol");
    }


}

我怎样才能将openAction函数逻辑放在自己的类中?我需要为我的UI添加大约10-20个函数及其自己的actionevent侦听器,我不希望在这个控制器类中存在所有这些函数。

1 个答案:

答案 0 :(得分:1)

目前尚不清楚您希望使用该模式的上下文,因此我展示了一个接受窗口地址的示例转换(即,将其作为对话框的所有者提交显示)。

它以描述命令的界面开始(在这种情况下,我选择返回Optional

public interface Command<R> {
    public Optional<R> execute();
}

在抽象类中实现Command接口。

public abstract class AbstractCommand<R> implements Command<R> {

    private Window window;

    public AbstractCommand(Window window) {
        this.window = window;
    }

    public Window getWindow() {
        return window;
    }
}

从现在开始,我们可以通过实现Command或扩展AbstractCommand来实现我们想要的实现。

这是load image命令的示例实现

public class LoadImageCommand extends AbstractCommand<Image> {

    public LoadImageCommand() {
        this(null);
    }

    public LoadImageCommand(Window window) {
        super(window);
    }

    @Override
    public Optional<Image> execute() {
        Image image = null;

        FileChooser fc = new FileChooser();
        File file = fc.showOpenDialog(getWindow());
        try {
            if(file != null) {
                BufferedImage bufferedImage = ImageIO.read(file);
                image = SwingFXUtils.toFXImage(bufferedImage, null);
            }
        } catch (IOException e) {
            System.out.println("lol");
        }

        return Optional.ofNullable(image);
    }
}

使用命令:

@FXML
private void openAction(ActionEvent event) {
    new LoadImageCommand().execute().ifPresent(imageView::setImage);
}

如果您想在不同的控制器中使用openAction,并且不想创建Command的单独实例,请继承Controller