首页 > 解决方案 > 如何从另一个类更改框架的大小

问题描述

我正在创建一个迷宫生成器,它会根据用户想要的行数/列数随机生成一个迷宫。我只能通过在JFrame每次生成迷宫时创建一个新的而不是更改现有框架来完成这项工作。

我尝试JFrame主要创建一个然后使用它来更改大小,我尝试将其公开并从按钮内更改它。

框架()类

public class Frame extends JFrame {
    private VariableDetails vDetails;
    private MazeArea mArea;

    private int width;
    private int height;

    public Frame(String title) {
        super(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        width = 500;
        height = 500;
        setSize(width,height);

        setLayout(new BorderLayout());

        mArea = new MazeArea();
        vDetails = new VariableDetails();

        Container c = getContentPane();

        c.add(mArea, BorderLayout.CENTER);
        c.add(vDetails, BorderLayout.EAST);
    }

    public void setSize2(int width, int height) {
        setSize(width,height);
    }

变量详细信息()类

public class VariableDetails extends JPanel {
    public VariableDetails() {
        JButton genBtn = new JButton("Generate");
        genBtn.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {
            setSize2(UserInputWidth,UserInputHeight);
        }
});
}

VariableDetails()我有 2 个JTextFields捕获用户输入的迷宫高度和宽度。

标签: javaswingjframe

解决方案


模型-视图-控制器,或者更简单的级别,将信息传递给方法或构造函数观察者模式是您想要学习和理解的概念。

本质上,您的“视图”是您的“模型”的视觉表示。“视图”“观察”“模型”以进行更改并相应地更新自身。

为了在您的上下文中实现这一点,您需要在两个视图之间共享模型,并传递对每个视图的引用。“渲染器”视图还将“观察”模型以进行任何可能的更改

首先定义模型...

public class MazeModel {

    private List<ChangeListener> listeners = new ArrayList<>(25);

    private int rows;
    private int cols;

    public void setSize(int cols, int rows) {
        this.cols = cols;
        this.rows = rows;

        fireStateChanged();
    }

    public int getRows() {
        return rows;
    }

    public int getCols() {
        return cols;
    }

    public void addChangeListener(ChangeListener listener) {
        listeners.add(listener);
    }

    public void removeChangeListener(ChangeListener listener) {
        listeners.remove(listener);
    }

    protected void fireStateChanged() {
        ChangeEvent evt = new ChangeEvent(this);
        for (ChangeListener listener : listeners) {
            listener.stateChanged(evt);
        }
    }
}

就个人而言,我更喜欢从 a 开始interface定义合同,但为了简洁起见。该模型应包含管理迷宫所需的数据和逻辑。

接下来,更新您的类,以便MazeModel可以传入的实例...

public class Frame extends JFrame {

    private VariableDetails vDetails;
    private MazeArea mArea;

    private int width;
    private int height;

    private MazeModel model;

    public Frame(String title, MazeModel model) {
        super(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.model = model;
        this.model.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                // Update the state as required...
            }
        });

        width = 500;
        height = 500;
        // Prefer pack :/
        setSize(width, height);

        setLayout(new BorderLayout());

        // I'm guessing that model should be passed to this
        // and it should modify it's state accoridingly....
        mArea = new MazeArea();
        vDetails = new VariableDetails(model);

        Container c = getContentPane();

        c.add(mArea, BorderLayout.CENTER);
        c.add(vDetails, BorderLayout.EAST);
        setVisible(true);
    }

    public class VariableDetails extends JPanel {

        private MazeModel model;

        public VariableDetails(MazeModel model) {
            this.model = model;
            JButton genBtn = new JButton("Generate");
            genBtn.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    model.setSize(cols, rows);
                }
            });
        }
    }
}

现在,这允许类通过 建立一个独立的通信通道,ChangeListener从而确保它们保持解耦。

关于调整窗口大小的说明

我不会。相反,我会将模型传递给实例MazeArea,因此它可以观察模型的变化并相应地更新自身。然后我将它包装MazeArea在 a 中JScrollPane,这将允许它将大小更改为任何内容,并且框架可以保持相对静态大小。

有关详细信息,请参阅如何使用滚动窗格

作为一个用户,如果我自己设置窗口的大小而你来改变它,我会很恼火


推荐阅读