Java GridBagLayout JPanels 自动调整大小问题?

标签 java swing jpanel jlabel gridbaglayout

我需要帮助调整红色 JPanel 的大小。基本上问题是我为 RED 和 BLUE JPanel 设置了相同大小的网格包约束并且它工作完美,直到我添加 JLabel,然后它只是愚蠢地开始使 RED JPanel 更大的尺寸,但它应该与以下尺寸相同BLUE JPanel,它应该保持在 0.05 大小。如果您能帮助我,我将不胜感激,在此先感谢您:)

http://s30.postimg.org/ag6fy7fg1/Screenshot_32.png

package weatherapp;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

public class WeatherApp {

    JFrame mainFrame = new JFrame("Weather App");
    Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
    GridBagConstraints gbc = new GridBagConstraints();
    JPanel topMenuBar = new JPanel();
    JPanel weatherInfoMaster = new JPanel();
    JPanel weatherGraphMaster = new JPanel();
    JPanel bottomMenuBar = new JPanel();
    JLabel currentDateLabel = new JLabel(new SimpleDateFormat("dd MMMM yyyy").format(new Date()));

    WeatherApp() {
        constructAppFrame();
        constructTopMenuBar();
    }

    public void constructAppFrame() {
        mainFrame.setSize(540, 960);
        mainFrame.setPreferredSize(new Dimension(540, 960));
        //Terminate the program when the user closes the app.
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setResizable(false);
        mainFrame.setLocation(screenDimension.width / 2 - mainFrame.getSize().width / 2, screenDimension.height / 2 - mainFrame.getSize().height / 2);
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setLayout(new GridBagLayout());

        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 1;
        gbc.weighty = 0.05;
        mainFrame.add(topMenuBar, gbc);
        gbc.gridy = 1;
        gbc.weighty = 0.6;
        mainFrame.add(weatherInfoMaster, gbc);
        gbc.gridy = 2;
        gbc.weighty = 0.5;
        mainFrame.add(weatherGraphMaster, gbc);
        gbc.gridy = 3;
        gbc.weighty = 0.05;
        mainFrame.add(bottomMenuBar, gbc);

        mainFrame.pack();
        mainFrame.setVisible(true);
    }

    public void constructTopMenuBar() {
        topMenuBar.setBackground(Color.RED);
        //topMenuBar.setBorder(new EmptyBorder(-20, 20, -20, 20));
        topMenuBar.setLayout(new BoxLayout(topMenuBar, BoxLayout.X_AXIS));
        currentDateLabel.setForeground(Color.WHITE);
        currentDateLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 20));
        currentDateLabel.setBackground(Color.BLUE);
        currentDateLabel.setOpaque(true);

        topMenuBar.add(currentDateLabel);

        weatherInfoMaster.setBackground(Color.CYAN);
        weatherGraphMaster.setBackground(Color.GREEN);
        bottomMenuBar.setBackground(Color.BLUE);
    }

    public static void main(String[] args) {
        //Create the frame on the event dispacthing thread.
        SwingUtilities.invokeLater(() -> {
            new WeatherApp();
        });
    }
}

最佳答案

//mainFrame.setLocation(screenDimension.width / 2 - mainFrame.getSize().width / 2, screenDimension.height / 2 - mainFrame.getSize().height / 2);
mainFrame.setLocationRelativeTo(null);

不需要第一个语句,因为 setLocationRelativeTo(...) 将重置位置。

constructAppFrame();
constructTopMenuBar();

不要在框架可见后向框架添加组件。两个语句的顺序应该颠倒。

it just stupidly starts making the RED JPanel Larger size, but it should of been the same size as the BLUE JPanel, 0.05 size it should of stay at.

这不傻。这是布局管理器定义明确的行为。每个布局管理器都有自己的规则要遵循。 GridBagLayout 适用于组件的“首选大小”。当没有组件添加到面板时,首选大小为 (10, 10),因为默认情况下 JPanel 使用 FlowLayout 并且组件前后的默认间隙为 5 像素。

因此,当有额外空间可用时,GridBagLayout 会根据首选大小分配空间,从而使红色获得更多空间。

作为快速破解(在遵循我上面的其他建议之后),您可以:

bottomMenuBar.setPreferredSize( topMenuBar.getPreferredSize() );
mainFrame.add(bottomMenuBar, gbc);

现在尺寸将相同,因为首选尺寸也相同。这个概念验证并不是真正好的解决方案,因为即使您更改红色面板,蓝色面板的首选尺寸也会固定。

也许更好的解决方案是使用 Relative Layout .此布局将根据框架中的可用空间而不是首选大小调整组件大小,因此如果红色/蓝色面板具有相同的相对大小,即使添加了组件,它们的大小也应该相同。

关于Java GridBagLayout JPanels 自动调整大小问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29066350/

相关文章:

java - JTable 与 JScrollpane 中的 JPanel 列表

java - 我需要将监听器添加到复选框,并且选择的更改显示在 textArea 中

java - J面板尺寸不正确

java - 在 JPanel 中实例化 JApplet 实例?

java - 调用重绘后 JButton 显示在错误的位置

java - 在 android 中更新 sqlite 数据库的首选方法

java - 在 RecyclerView 中膨胀两种类型的 .XML

java - 从jsp访问类的静态字段

java - 枚举和状态...使用监听器来计时 - Java

java - 我的单选按钮没有与我的 JButton 交互