【问题标题】:How do I dynamically resize a JFrame based on its components (a JPanel)如何根据 JFrame 的组件(JPanel)动态调整 JFrame 的大小
【发布时间】:2022-11-10 03:35:14
【问题描述】:

所以基本上我的gui是这样的:

包含名为 JPanel 的免费设计布局的框架主面板

mainPanel 内部还有另外两个面板:

一个)工具面板布局 BoxLayout

二)游戏面板布局 GridLayout

这是代码的重要位:

public Normalv3() {
        initComponents();
        importBombs();
    }
    
    public void importBombs(){
        
        rows = Minesweeper.rows;
        columns = Minesweeper.columns;
        total = rows*columns;
        bombsIndexes = new ArrayList<Integer>(Minesweeper.totalBombs);
        gamePanel.setLayout(new java.awt.GridLayout(rows,columns)); //Creating a new grid layout and putting it inside the old layout
        
        
        ////
        Random ran = new Random();
        int low=1;
        int high=rows*columns;
        int ranValue;
        for (int i = 0 ; i< Minesweeper.totalBombs;i++){
            ranValue = ran.nextInt(high - low)+low;
        
            if(bombsIndexes.contains(ranValue)){
                i--;
                continue;
            }
        
        bombsIndexes.add(ranValue);
        }
        ////
        
        for (int i = 1; i <= total ; i++){
            btnMines b = new btnMines(i);
            if(bombsIndexes.contains(i)){     
                b.isBomb = true;
                b.setIcon(new javax.swing.ImageIcon(getClass().getResource("/minesweeper/resources/bomb.png")));
            }
            b.setPreferredSize(new Dimension(20,20));
            
            gamePanel.add(b);
        }
        this.setResizable(false);
        this.setTitle("Minesweeper");
        this.pack();//sizes frame so that all components are at their preferred sizes
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.validate(); //recalculate layout
        this.setVisible(true);
    }

问题是当我增加列数时,游戏面板或者主面板增加,但框架的宽度不增加。

例子:

如何更改框架的大小以根据面板大小调整自身大小?

笔记:btnMines 基本上只是一个附加了一些变量的 JButton。

额外的问题:我将如何将每个按钮变成正方形?如您所见,我尝试通过编写 b.setPreferredSize(new Dimension(20,20));但每个生成的按钮仍然是矩形!

请帮忙!

另外,我知道代码很乱。我曾经将该函数分离为单独的函数,但现在我决定将其全部放入 1 个函数中,以便正确测试它。

谢谢!

我尝试添加:

this.setResizable(false);
        this.setTitle("Minesweeper");
        this.pack();//sizes frame so that all components are at their preferred sizes
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.validate(); //recalculate layout
        this.setVisible(true);

但它没有工作,因为框架没有调整大小!

【问题讨论】:

  • 包含自由设计布局 JPanel 的框架- 没有必要。可能使用无效的空布局。默认情况下,框架使用 BorderLayout。因此,您只需使用 BorderLayout.PAGE_START 将“toolPanel”添加到框架,使用 BorderLayout.CENTER 将“gamePanel”添加到框架中。然后在使其可见之前pack() 框架。您是否解决了您的其他问题:stackoverflow.com/q/74246638/131872?看起来像,因为我看到了炸弹的图像。那么,为什么您没有对表明问题已解决的问题发表评论呢?
  • 我首先关心的是initComponents 在做什么。您应该避免直接从像JFrame 这样的顶级容器扩展,这可能会导致“其他”问题
  • 你为什么删除你的最后一个问题?您仍然没有回复说明这些建议是否有帮助。见:What should I do when someone answers my question

标签: java swing jframe jpanel awt


【解决方案1】:

包含名为 mainPanel 的免费设计布局 JPanel 的框架

这似乎表明mainPanel 可能正在使用null 布局,这会导致您出现问题,但这只是一个猜测。

JFrame#pack 应该根据通过后续布局管理器提供的内容“首选大小”提示将框架包裹在内容周围,这让我质疑您的设计中涉及哪些布局管理器(如果有的话)。

例如...

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new Normalv3(10, 10));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class Normalv3 extends JPanel {

        public Normalv3(int cols, int rows) {
            setLayout(new BorderLayout());
            add(makeControlsPane(), BorderLayout.NORTH);
            add(makeGamePane(cols, rows));
        }

        protected JPanel makeControlsPane() {
            JPanel pane = new JPanel(new FlowLayout(FlowLayout.LEADING));
            pane.add(new JButton("Back to Menu"));
            pane.add(new JButton("Reset"));
            return pane;
        }

        protected JPanel makeGamePane(int cols, int rows) {
            JPanel pane = new JPanel(new GridLayout(rows, cols));
            for (int index = 0; index < (cols * rows); index++) {
                JButton btn = new SquareButton("*");
                pane.add(btn);
            }
            return pane;
        }
    }

    class SquareButton extends JButton {

        SquareButton(String s) {
            super(s);
        }

        @Override
        public Dimension getPreferredSize() {
            Dimension d = super.getPreferredSize();
            int s = (int) (d.getWidth() < d.getHeight() ? d.getHeight() : d.getWidth());
            return new Dimension(s, s);
        }
    }
}

方形按钮设计取自Creating Square Buttons in Swing

作为旁注 - 我鼓励您不要使用表单设计器,它们往往会很快变得混乱并且难以诊断和维护(恕我直言)

【讨论】:

  • 回覆“笔记”: 你的意思是“不是”?
猜你喜欢
  • 1970-01-01
  • 2011-10-03
  • 1970-01-01
  • 2012-05-16
  • 2012-09-01
  • 1970-01-01
  • 2013-10-11
相关资源
最近更新 更多