当前位置: 首页 > 知识库问答 >
问题:

使用GridBagLayout调整Java Swing组件大小

商泽宇
2023-03-14

我的Java Swing GUI有问题。首先,我创建了一个带有GridBagLayout的面板,并将所有标签添加到其中。然而,我还在另一个JPanel的右侧创建了一个面板,其中添加了一个按钮和两个滑块,它们应该与标签匹配。

问题是JLabels比另一个面板右侧的组件小,这使得它看起来像这样......

例如,水选项——JSLIDER(JSLIDER看起来要大得多)

我试图通过将ipadx添加到更大的值来使组件更大,并且我尝试将标签面板的网格宽度设置得更大,但似乎没有任何效果。它就是没有响应。

代码如下:

package gui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;

public class Options extends JFrame{
        //water option (button changes text on or off)
        //make a button listener
        JSlider renderDistance;
        JSlider grassDensity;
        JButton waterToggleButton;

        JLabel rdTitle;
        JLabel gdTitle;
        JLabel wtTitle;
        JButton buttonClose;

        static final int RD_MIN_VALUE = 0;
        static final int RD_MAX_VALUE = 1000;
        static final int RD_INIT_VALUE = 500;


        static final int GD_MIN_VALUE = 0;
        static final int GD_MAX_VALUE = 1000;
        static final int GD_INIT_VALUE = 500;

        public Options() {
                this.setTitle("Settings");
                this.setSize(getMaximumSize());
                this.setLocationRelativeTo(null);
                createView();

                this.setVisible(true);

        }

        private void createView() {
                //Making panels and adding them to window*
                JPanel pOptions = new JPanel();
                this.add(pOptions);

                //These are for the labels that I added so people know which option they are using
                JPanel pOptionLabels = new JPanel(new GridBagLayout());
                pOptions.add(pOptionLabels);

                //These are for the middle columns, the objects like button and slider
                JPanel pOptionObjects = new JPanel(new GridBagLayout());
                pOptions.add(pOptionObjects);

                //Making panels and adding them to window*

                //Initializing Objects*

                GridBagConstraints gbcLabels = new GridBagConstraints();
                GridBagConstraints gbcObjects = new GridBagConstraints();

                renderDistance = new JSlider(RD_MIN_VALUE, RD_MAX_VALUE, RD_INIT_VALUE);
                grassDensity = new JSlider(GD_MIN_VALUE, GD_MAX_VALUE, GD_INIT_VALUE);
                waterToggleButton = new JButton("On");

                rdTitle = new JLabel("Render Distance");
                gdTitle = new JLabel("Grass Density");
                wtTitle = new JLabel("Water Terrain Visibility");

                //Initializing Objects*

                //Giving objects some attributes using methods*

                renderDistance.setMinorTickSpacing(100);
                renderDistance.setMajorTickSpacing(500);
                renderDistance.setPaintTicks(true);
                renderDistance.setPaintLabels(true);

                grassDensity.setMinorTickSpacing(100);
                grassDensity.setMajorTickSpacing(500);
                grassDensity.setPaintTicks(true);
                grassDensity.setPaintLabels(true);

                gbcLabels.gridx = 0;
                gbcLabels.gridy = 0;
                gbcLabels.anchor = GridBagConstraints.LINE_START;

                gbcObjects.gridx = 0;
                gbcObjects.gridy = 0;

                waterToggleButton.addActionListener(new ActionListener() {

                           public void actionPerformed(ActionEvent e) {

                                  if(waterToggleButton.getText().equals("Off")) {
                                          waterToggleButton.setText("On");
                                  }else {
                                          waterToggleButton.setText("Off");


                                  }
                                }
                          });



                //Giving objects some attributes using methods*

                //Add things to panel ex. p.add();
                pOptionLabels.add(rdTitle, gbcLabels);
                gbcLabels.gridy++;
                pOptionLabels.add(gdTitle, gbcLabels);
                gbcLabels.gridy++;
                pOptionLabels.add(wtTitle, gbcLabels);

                gbcObjects.gridx++;
                pOptionObjects.add(renderDistance, gbcObjects);
                gbcObjects.gridy++;
                pOptionObjects.add(grassDensity, gbcObjects);
                gbcObjects.gridy++;
                pOptionObjects.add(waterToggleButton, gbcObjects);





        }

        public static void main(String[] args) {
                new Options();

        }




                }

共有2个答案

秦时铭
2023-03-14

您所经历的技术上是正确的,因为您有两个JPanel,其中有两个GridBagLayout管理器的独立实例,因此一个布局管理器中的行(和列)没有关于另一个布局管理器中的行的信息。

如果您计划在其中使用JComponents并创建类似于表的外观,那么可以使用单个GridBagLayout。以后可以添加其他JPanel(使用不同的布局管理器或更多的GridBagLayouts!)但在主GridBagLayout JPanel中。

GridBagLayout是一个非常强大的布局,我建议坚持使用is并掌握它,因为从长远来看,它将帮助您很好(且快速)地布局。

这是了解GridBagLayout的重要资源:

https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html

一条小评论:在我看来,GridBagLayout并不是用作“根”布局容器的最佳布局管理器。相反,我建议创建一个带有BorderLayout()的“根”JPanel,并将您的GridBagLayout JPanel添加到BorderLayout面板add(您的GridPanel,BorderLayout.center)的中心,因为BorderLayout通常免费提供水平/垂直填充的功能,并可以让您在中心很好地打包窗口(之后可能会在北面/南面/东面/西面添加更多内容)。

祝你好运

孔鸿哲
2023-03-14

改变你的思维方式。与其试图将所有标签和所有“其他”组件布局在单独的容器中,不如考虑将它们都放在同一个容器中。

这样,当布局它们时,布局计算是在单个上下文中相对于所有组件进行的。

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;

public class Options extends JFrame {
                //water option (button changes text on or off)
    //make a button listener

    JSlider renderDistance;
    JSlider grassDensity;
    JButton waterToggleButton;

    JLabel rdTitle;
    JLabel gdTitle;
    JLabel wtTitle;
    JButton buttonClose;

    static final int RD_MIN_VALUE = 0;
    static final int RD_MAX_VALUE = 1000;
    static final int RD_INIT_VALUE = 500;

    static final int GD_MIN_VALUE = 0;
    static final int GD_MAX_VALUE = 1000;
    static final int GD_INIT_VALUE = 500;

    public Options() {
        this.setTitle("Settings");

        createView();

        pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);

    }

    private void createView() {
        //Making panels and adding them to window*
        JPanel pOptions = new JPanel();
        this.add(pOptions);

        //These are for the labels that I added so people know which option they are using
        JPanel pOptionLabels = new JPanel(new GridBagLayout());
        pOptions.add(pOptionLabels);

        GridBagConstraints gbc = new GridBagConstraints();

        renderDistance = new JSlider(RD_MIN_VALUE, RD_MAX_VALUE, RD_INIT_VALUE);
        grassDensity = new JSlider(GD_MIN_VALUE, GD_MAX_VALUE, GD_INIT_VALUE);
        waterToggleButton = new JButton("On");

        rdTitle = new JLabel("Render Distance");
        gdTitle = new JLabel("Grass Density");
        wtTitle = new JLabel("Water Terrain Visibility");

                                //Initializing Objects*
                                //Giving objects some attributes using methods*
        renderDistance.setMinorTickSpacing(100);
        renderDistance.setMajorTickSpacing(500);
        renderDistance.setPaintTicks(true);
        renderDistance.setPaintLabels(true);

        grassDensity.setMinorTickSpacing(100);
        grassDensity.setMajorTickSpacing(500);
        grassDensity.setPaintTicks(true);
        grassDensity.setPaintLabels(true);

        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.LINE_START;
        gbc.insets = new Insets(2, 2, 2, 2);

        waterToggleButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                if (waterToggleButton.getText().equals("Off")) {
                    waterToggleButton.setText("On");
                } else {
                    waterToggleButton.setText("Off");

                }
            }
        });

                                //Giving objects some attributes using methods*
        //Add things to panel ex. p.add();
        pOptionLabels.add(rdTitle, gbc);
        gbc.gridy++;
        pOptionLabels.add(gdTitle, gbc);
        gbc.gridy++;
        pOptionLabels.add(wtTitle, gbc);

        gbc.gridx++;
        gbc.gridy = 0;
        pOptionLabels.add(renderDistance, gbc);
        gbc.gridy++;
        pOptionLabels.add(grassDensity, gbc);
        gbc.gridy++;
        pOptionLabels.add(waterToggleButton, gbc);

    }

    public static void main(String[] args) {
        new Options();

    }

}
 类似资料:
  • 问题内容: 我正在使用一些动态生成的数据输入形式来管理组件。布局大致如下: 我将2个平行组用于水平布局,并将一个顺序组用于垂直布局。在大多数情况下,一切都很好。 我想将标签的最大宽度(只是的实例)限制为父级宽度的。如果将JFrame其设置为固定大小,这将是微不足道的,但是我必须处理它的调整大小。 我正在从接收事件,JFrame但是一旦收到这样的事件,我就该做什么了。 我试过这种方法没有任何运气:

  • 我想让JFrame上的组件随着窗口的大小调整而调整大小。 这怎么能做到。 当前,当我使JFrame变小时,组件会保留在相同的位置,然后随着框架变小而消失。 理想情况下,我希望设置一个最小的JFrame大小,它不允许表单变小,但当我将其变大时,组件应该随JFrame移动。 补充:如果我想使用绝对布局管理器,该怎么办。这是我老板比较喜欢的布局经理。 代码: 公共类TestFrame扩展JFrame{p

  • 我想减少GridBagLayout中JTextField和JScrollPane的宽度和高度,但似乎通过设置文本字段列,宽度只能减少到JList中最长内容的长度。我不确定是否需要调整组件的两个或一个尺寸以匹配宽度。 我尝试了setPreferredSize()、setSize()和在文本字段上设置列长度,但它们似乎没有任何作用。

  • 我试图创建JPanel与可拖动的交叉显示后,鼠标点击。一切都很好,但是当我调整JPanel的大小时,交叉消失了。我试图重写JPanel中的paintComponent方法,但所有交叉都在坐标(0,0)处。我该怎么修好它?

  • 我正在尝试实现一个简单的JDialog,其中上部的JPanel有一个GridBagLayout,它由5对JLabel组成:在每对JLabel中,第一个JLabel充当一个头,而第二个JLabel包含从web服务调用接收到的数据。这里有一个例子: 正如你所看到的,这个窗口太“空”了,空间太大了。首先,我不能理解为什么上面板比第二面板大得多。实际上,标题为“risultato”的JPanel也有Gri

  • 问题内容: 前一段时间,我阅读了这篇文章,该文章展示了一种在Swing中实现可调整鼠标大小的组件的方法。 作者使用null的LayoutManager以便进行绝对的组件定位。我知道不应该使用null布局,所以我的问题是: 是否有已经实现的LayoutManager允许组件的绝对定位,还是我必须自己实现它? 问题答案: 布局管理器实际上执行3件事: 设置组件的位置。由于您需要能够拖动组件,因此您不希