如何从另一个类更改帧的大小

时间:2018-12-30 19:31:51

标签: java swing jframe

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

我尝试在主目录中创建一个JFrame,然后使用它来更改大小,我尝试将其公开,然后从按钮中进行更改。

Frame()类

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);
    }

VariableDetails()类

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捕获迷宫的高度和宽度的用户输入。

2 个答案:

答案 0 :(得分:1)

bug,或更简单的层次,Model-View-ControllerPassing Information to a Method or a Constructor是您要学习和理解的概念。

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

为了在您的上下文中实现此目的,您需要在两个视图之间共享模型,并传递对每个视图的引用。 “渲染器”视图还将“观察”模型是否存在任何可能的变化

首先定义模型...

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);
        }
    }
}

就个人而言,我宁愿以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包裹在JScrollPane中,这将使它可以将大小更改为任何大小,并且帧可以保持相对静态大小。

有关更多详细信息,请参见observer pattern

作为用户,如果我自己设置窗口的大小,而您又来更改它,那将使我无休止地

答案 1 :(得分:0)

如果正确理解您要执行的操作,则是从面板更改框架的大小。为此,需要在Panel类中调整对象Frame的大小。您可以使用单例模式来实现。您也可以将setSize2方法设为静态,并像这样def flatten_obj(obj, FLAT_OBJ=None): if FLAT_OBJ is None: FLAT_OBJ = OrderedDict() if isinstance(obj, list): return [flatten_obj(l, FLAT_OBJ=FLAT_OBJ) for l in obj] elif not isinstance(obj, dict): return obj else: for key in list(obj.keys()): val = get_sub_object_from_path(obj, key) if isinstance(val, dict): FLAT_OBJ[key] = [{'_Key': subkey, 'Value': flatten_obj(subval)} for subkey, subval in val.items()] elif isinstance(val, list): FLAT_OBJ[key] = flatten_obj(val, FLAT_OBJ=FLAT_OBJ) else: FLAT_OBJ[key] = val return FLAT_OBJ

进行调用

我已使用单例模式重写了您的代码。希望对您有所帮助。

Frame.setSize(UserInputWidth,UserInputHeight)