(Gridbag Layout) Graphic component is clipping into another grid, 不知道为什么

(Gridbag Layout) Graphic component is clipping into another grid, not sure why

这是我的 JFrame 的预期设计:

它看起来很容易实现,有一些按钮、文本字段、标签和一个选择列表。

它还有一个位于左上角的黄色方框,称为 "graphic"。不过我不太熟悉如何使用。

为了做类似上面的东西,我想用gridbag布局。

这是我在 运行 进入问题之前能够产生的:

标签 red:、文本框和 -/+ 按钮都在第 1 列 (gridy = 1;)。

当我在第 0 行第 0 列(网格宽度 = 4)添加图形时,我希望它位于这些元素之上(因为 0 小于 1)。可悲的是,这不是我得到的,这令人沮丧,因为我不知道为什么要这样做。

我的结果:

正如我之前所说,我对 JFrames 没有太多经验。我非常感谢某人的经验并帮助解决此问题并解释原因。

这是我的源代码:

(1/2):

package colorSamplerApp;

import java.awt.*;
import javax.swing.*;



public class WindowApplication extends JFrame {
    final static boolean shouldFill = true;
    final static boolean shouldWeightX = true;
    final static boolean RIGHT_TO_LEFT = false;

    protected static JLabel redLabel;
    protected static JLabel greenLabel;
    protected static JLabel blueLabel;

    protected static JTextField redTextField;
    protected static JTextField greenTextField;
    protected static JTextField blueTextField;

    protected static JButton redButtonM;
    protected static JButton greenButtonM;
    protected static JButton blueButtonM;

    protected static JButton redButtonP;
    protected static JButton greenButtonP;
    protected static JButton blueButtonP;

    protected static JButton saveButton;
    protected static JButton resetButton;

    protected static JList listColors;

    protected static DrawingTester drawTest;



    public static void addComponentsToPane(Container pane) 
    {
        if (RIGHT_TO_LEFT) {
            pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        }


        pane.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        if (shouldFill) {
        //natural height, maximum width
        c.fill = GridBagConstraints.HORIZONTAL;
        }


        /**
         * Setup the RGB Labels
         * 
         * R <0,1>
         * G <0,2>
         * B <0,3>
         * 
         */

        c.insets = new Insets(0,10,0,5);

        c.gridwidth = 1;
        redLabel = new JLabel("Red:");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 1;
        pane.add(redLabel, c);

        greenLabel = new JLabel("Green:");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 2;
        pane.add(greenLabel, c);

        blueLabel = new JLabel("Blue:");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 3;
        pane.add(blueLabel, c);

        /**
         * Setup the RGB Text Fields
         * 
         * R<1,1>
         * G<1,2>
         * B<1,3>
         * 
         */


        c.insets.set(0, 0, 0, 5);

        redTextField = new JTextField("255");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 1;
        pane.add(redTextField, c);

        greenTextField = new JTextField("0");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 2;
        pane.add(greenTextField, c);

        blueTextField = new JTextField("0");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 3;
        pane.add(blueTextField, c);

        /**
         * Setup the RGB (-) Button Fields
         * 
         * R<2,1>
         * G<2,2>
         * B<2,3>
         * 
         */

        c.insets.set(5,5,0,10);

        redButtonM = new JButton("-");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 2;
        c.gridy = 1;
        pane.add(redButtonM, c);

        greenButtonM = new JButton("-");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 2;
        c.gridy = 2;
        pane.add(greenButtonM, c);

        blueButtonM = new JButton("-");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 2;
        c.gridy = 3;
        pane.add(blueButtonM, c);

        /**
         * Setup the RGB (+) Button Fields
         * 
         * R<3,1>
         * G<3,2>
         * B<3,3>
         * 
         */

        c.insets.set(5,0,0,10);

        redButtonP = new JButton("+");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 3;
        c.gridy = 1;
        pane.add(redButtonP, c);

        greenButtonP = new JButton("+");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 3;
        c.gridy = 2;
        pane.add(greenButtonP, c);

        blueButtonP = new JButton("+");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 3;
        c.gridy = 3;
        pane.add(blueButtonP, c);

        /**
         * Setup the Save/Reset Buttons
         * 
         * save <0,4>
         * reset<1,4>
         * 
         */

        c.insets.set(10,10,10,5);

        saveButton = new JButton("Save");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.ipady = 10;      //make this component tall
        c.ipadx = 10;
        //c.weightx = 0.0;
        c.gridwidth = 2;
        c.gridx = 0;
        c.gridy = 4;
        pane.add(saveButton, c);


        c.insets.set(10,5,10,10);

        resetButton = new JButton("Reset");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.ipady = 10;      
        c.ipadx = 10;
        //c.weighty = 1.0;   //request any extra vertical space
        //c.anchor = GridBagConstraints.PAGE_END; //bottom of space
        c.gridx = 2;       //aligned with button 2
        c.gridwidth = 2;   //2 columns wide
        c.gridy = 4;       //third row
        pane.add(resetButton, c);

        /**
         * Setup the Color Selection List
         * 
         * <4,0>
         * 
         */

        c.insets.set(10,0,10,10);

        listColors = new JList();
        /**
            File reading shenanigans to fill up the list
        */
        c.fill = GridBagConstraints.HORIZONTAL;
        c.ipady = 150;       
        c.ipadx = 100;
        //c.weighty = 1.0;   //request any extra vertical space
        //c.anchor = GridBagConstraints.PAGE_END; //bottom of space
        c.gridx = 4;       //aligned with button 2
        c.gridheight = 5;   //2 columns wide
        c.gridy = 1;       //third row
        pane.add(listColors, c);

        /**
         * Setup the Graphics
         * 
         * <0,0>
         * 
         */

        drawTest = new DrawingTester();
        c.insets.set(0,0,0,0);
        c.gridx = 0;       //top leftw
        c.gridy = 0;       //bottom
        c.gridwidth = 0 ;
        pane.add(drawTest,c);
    }


    public static void main (String argv[])
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI("Color Sampler");
            }
        });
    }

    public static void createAndShowGUI(String title)
    {
        // Create and setup the window
        JFrame frame = new JFrame (title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Setup the content pane
        addComponentsToPane(frame.getContentPane());

        // Display the window
        frame.pack();
        frame.setVisible(true);

    }


}

(2/2)

package colorSamplerApp;

import java.awt.*;
import javax.swing.*;

import javax.swing.JComponent;

public class DrawingTester extends JComponent {

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.setColor(Color.red);
        g.fillRect(0,0, 170, 70);   
    }
}

您遇到的问题与重复使用相同的 GridBagConstraints 对象有关。很常见的一个,也是处理这种布局的痛苦之一。

首先,我已经注释掉了所有改变 insets 的调用。

然后,我确定 gridxgridy 设置正确。另外,将 gridheightgridwidth 视为组件将要占用的网格中的单元格数量,不要根据实际的 widthheight 来考虑您要放置在单元格中的内部组件。

DrawingTester 中,我还确保我们绘制了整个东西。

查看代码和结果:

import java.awt.*;
import javax.swing.*;

public class WindowApplication extends JFrame {
    final static boolean shouldFill = true;
    final static boolean shouldWeightX = true;
    final static boolean RIGHT_TO_LEFT = false;

    protected static JLabel redLabel;
    protected static JLabel greenLabel;
    protected static JLabel blueLabel;

    protected static JTextField redTextField;
    protected static JTextField greenTextField;
    protected static JTextField blueTextField;

    protected static JButton redButtonM;
    protected static JButton greenButtonM;
    protected static JButton blueButtonM;

    protected static JButton redButtonP;
    protected static JButton greenButtonP;
    protected static JButton blueButtonP;

    protected static JButton saveButton;
    protected static JButton resetButton;

    protected static JList listColors;

    protected static DrawingTester drawTest;



    public static void addComponentsToPane(Container pane) 
    {
        if (RIGHT_TO_LEFT) {
            pane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
        }


        pane.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        if (shouldFill) {
        //natural height, maximum width
        c.fill = GridBagConstraints.HORIZONTAL;
        }


        /**
         * Setup the RGB Labels
         * 
         * R <0,1>
         * G <0,2>
         * B <0,3>
         * 
         */

//        c.insets = new Insets(0,10,0,5);

        c.gridwidth = 1;
        redLabel = new JLabel("Red:");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 1;
        pane.add(redLabel, c);

        greenLabel = new JLabel("Green:");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 2;
        pane.add(greenLabel, c);

        blueLabel = new JLabel("Blue:");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 3;
        pane.add(blueLabel, c);

        /**
         * Setup the RGB Text Fields
         * 
         * R<1,1>
         * G<1,2>
         * B<1,3>
         * 
         */


//        c.insets.set(0, 0, 0, 5);

        redTextField = new JTextField("255");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 1;
        pane.add(redTextField, c);

        greenTextField = new JTextField("0");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 2;
        pane.add(greenTextField, c);

        blueTextField = new JTextField("0");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 1;
        c.gridy = 3;
        pane.add(blueTextField, c);

        /**
         * Setup the RGB (-) Button Fields
         * 
         * R<2,1>
         * G<2,2>
         * B<2,3>
         * 
         */

//        c.insets.set(5,5,0,10);

        redButtonM = new JButton("-");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 2;
        c.gridy = 1;
        pane.add(redButtonM, c);

        greenButtonM = new JButton("-");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 2;
        c.gridy = 2;
        pane.add(greenButtonM, c);

        blueButtonM = new JButton("-");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 2;
        c.gridy = 3;
        pane.add(blueButtonM, c);

        /**
         * Setup the RGB (+) Button Fields
         * 
         * R<3,1>
         * G<3,2>
         * B<3,3>
         * 
         */

//        c.insets.set(5,0,0,10);

        redButtonP = new JButton("+");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 3;
        c.gridy = 1;
        pane.add(redButtonP, c);

        greenButtonP = new JButton("+");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 3;
        c.gridy = 2;
        pane.add(greenButtonP, c);

        blueButtonP = new JButton("+");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 3;
        c.gridy = 3;
        pane.add(blueButtonP, c);

        /**
         * Setup the Save/Reset Buttons
         * 
         * save <0,4>
         * reset<1,4>
         * 
         */

        saveButton = new JButton("Save");
        c.insets.set(10,10,10,5);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.ipady = 10;      //make this component tall
        c.ipadx = 10;
        //c.weightx = 0.0;
        c.gridwidth = 2;
        c.gridx = 0;
        c.gridy = 4;
        pane.add(saveButton, c);


        resetButton = new JButton("Reset");
        c.insets.set(10,5,10,10);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.ipady = 10;      
        c.ipadx = 10;
        //c.weighty = 1.0;   //request any extra vertical space
        //c.anchor = GridBagConstraints.PAGE_END; //bottom of space
        c.gridx = 2;       //aligned with button 2
        c.gridwidth = 2;   //2 columns wide
        c.gridy = 4;       //third row
        pane.add(resetButton, c);

        /**
         * Setup the Color Selection List
         * 
         * <4,0>
         * 
         */

        c.insets.set(5,5,5,5);

        listColors = new JList(new Object[] {"Test 1", "Test 2", "Test 3"});
        /**
            File reading shenanigans to fill up the list
        */
        c.fill = GridBagConstraints.BOTH;
        c.gridy = 0;       
        c.gridx = 4;       
        c.gridheight = 5;   
        c.gridwidth = 1;

        pane.add(listColors, c);

        /**
         * Setup the Graphics
         * 
         * <0,0>
         * 
         */

        drawTest = new DrawingTester();
        c.insets = new Insets(5,5,5,5);
        c.fill = GridBagConstraints.BOTH;
        c.gridx = 0;       //top leftw
        c.gridy = 0;       //bottom
        c.gridheight = 1;
        c.gridwidth = 4;
        pane.add(drawTest,c);
    }


    public static void main (String argv[])
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI("Color Sampler");
            }
        });
    }

    public static void createAndShowGUI(String title)
    {
        // Create and setup the window
        JFrame frame = new JFrame (title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Setup the content pane
        addComponentsToPane(frame.getContentPane());

        // Display the window
        frame.pack();
        frame.setVisible(true);

    }


}

class DrawingTester extends JComponent {

  public void paintComponent(Graphics g){
      super.paintComponent(g);
      g.setColor(Color.red);
      g.fillRect(0,0, g.getClipBounds().width, g.getClipBounds().height);   
  }
}

查看结果:

从那时起,您应该能够继续更改它以满足您的需要,例如取回所有 insets 并更改组件的 heightwidth。请记住,您正在重复使用 GridBagConstraints,因此您必须小心。如果您不确定,只需实例化一个新的并测试您的代码。