java - GridBagLayout - 无法放置没有 anchor 的组件

标签 java swing user-interface layout-manager gridbaglayout

我正在制作一个作业计划程序。对于容器(作业),我想将某些组件放在某些地方。然而。我似乎只能通过使用 anchor 来移动组件。好像我的 gridx 和 gridy 什么也没做。谁能指出我的问题并可能提供一些建议。下面提供了我的代码和预期最终结果的图片。

代码:

import javax.swing.*;
import java.awt.*;
import static java.awt.GridBagConstraints.*;
//import java.util.ArrayList;

public class MyWindow
{
    private final JFrame frame = new JFrame();
    private final int WINDOW_WIDTH = 500, WINDOW_DEPTH = 500;
    private JPanel panel;
    private JPanel toDoList, completed;
    private int scrollPaneValue = 110;
    //ArrayList<JFrame> frame = new ArrayList<>();

    public MyWindow()
    {
        frame.setTitle("Assignment Planner");
        this.contents();
    }

    private void contents()//make a border above each panel stating "TO-DO" or "COMPLETED"
    {//use an arraylist to create containers    ArrayList<JPanel> container = new ArrayList<>();
        frame.setSize(WINDOW_WIDTH, WINDOW_DEPTH);
        panel = new JPanel(new GridLayout(2, 1));

        toDoList = new JPanel();
        toDoList.setLayout(new /*GridLayout(0,1,5,5)*/BoxLayout(toDoList, BoxLayout.PAGE_AXIS));
        toDoList.setPreferredSize(new Dimension(250, 110));
        panel.add(toDoList);

        completed = new JPanel();
        //panelCompleted.setLayout(new GridLayout(0, 1)); //fix like one above

        panel.add(completed);

        JScrollPane scroll = new JScrollPane(toDoList); 
        panel.add(scroll);                                      //scroll panes for both panels
        JScrollPane scroll2 = new JScrollPane(completed);
        panel.add(scroll2);

        toDoList.add(Box.createRigidArea(new Dimension(0,1)));
        toDoList.add(assignment());    

        scrollPaneValue += 110; //add these 2 lines of code, beginning after the first two containers to increase jscrollpane
        toDoList.setPreferredSize(new Dimension(250, scrollPaneValue));
        //toDoList.revalidate(); may not even need

        frame.getContentPane().add(panel, BorderLayout.CENTER);//add the panel in the JFrame's content pane in the center
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
    JPanel assignment()
    {
        JPanel container = new JPanel(new GridBagLayout());
        container.setMaximumSize(new Dimension(500,100));
        GridBagConstraints cDefault = new GridBagConstraints();
        cDefault.weightx = 0.5;
        cDefault.insets = new Insets(5,5,5,5);

        JCheckBox cb;
        JLabel dueDate, description;
        JButton edit;


        cb = new JCheckBox();
        GridBagConstraints cCb = new GridBagConstraints();
        cCb.weightx = 0.5;
        cCb.weighty = 1;
        cCb.fill = GridBagConstraints.NONE;//originally none
        cCb.gridx = 0;
        cCb.gridy = 0;
        //cCb.gridwidth = 1;
        //cCb.gridheight = 1;
        cCb.anchor = FIRST_LINE_START;//may not need, plus needs static import
        cCb.insets = cDefault.insets;
        cb.setBackground(Color.RED);
        container.add(cb, cCb);

        dueDate = new JLabel("Due Date");
        GridBagConstraints cDueDate = new GridBagConstraints();
        cDueDate.gridx = 1;
        cDueDate.gridy = 0;
        cDueDate.gridwidth = 2;
        //cDueDate.fill = GridBagConstraints.HORIZONTAL;
        cDueDate.anchor = PAGE_START;
        dueDate.setBackground(Color.BLUE);
        //cDueDate.anchor = FIRST_LINE_START;
        container.add(dueDate, cDueDate);

        edit = new JButton("Edit");
        GridBagConstraints e = new GridBagConstraints();
        e.gridx = 4;
        e.gridy = 0;
        e.anchor = GridBagConstraints.FIRST_LINE_END;
        e.insets = cDefault.insets;
        edit.setBackground(Color.GREEN);
        container.add(edit, e);

        description = new JLabel("Description...");
        GridBagConstraints d = new GridBagConstraints();
        d.gridx = 1;
        d.gridy = 3;
        d.gridwidth = 3;
        d.fill = GridBagConstraints.HORIZONTAL;
        description.setBackground(Color.YELLOW);
        container.add(description, d);

        container.setBackground(Color.LIGHT_GRAY);//does no fill area behind checkbox

        return container;
    }
}

我希望容器看起来像什么:

enter image description here

最佳答案

This just concerns my lack of knowledge with GridBagLayout.

How to Use GridBagLayout 上的 Swing 教程部分开始工作示例和所有约束的解释。

关于代码的一些事情:

 //container.setMaximumSize(new Dimension(500,100));

不要设置最大尺寸。布局管理器将确定面板的大小。

//cCb.weightx = 0.5;
//cCb.weighty = 1;

以上代码将面板的所有额外空间分配给复选框,因为它是唯一具有 weightx/y 约束的组件。我怀疑你想要那个。尝试注释掉这些语句,看看会发生什么。

dueDate.setOpaque(true);
dueDate.setBackground(Color.BLUE);

是的,设置背景以查看组件的实际大小是个好主意。问题是 JLabel 默认情况下是透明的,因此永远不会绘制背景。如果你想看到背景,你需要让你的标签不透明。另一种帮助调试的方法是将 LineBorder 添加到标签中,那么您就无需担心透明度问题。

//e.gridx = 4;
e.gridx = 3;

注意网格值。你不能只使用一个值。第一个组件的宽度为 1,第二个组件的宽度为 2,因此该组件应从 3 开始。

I can only seem to move components around by using anchor

其实,我不觉得这个主播在做什么。据我了解,只有当组件尺寸小于网格尺寸时, anchor 才有意义。在您的原始代码中,只有复选框使用了 weightx/y 值,因此这是唯一正确的组件。

GridBagLayout 是使用起来最复杂(也是最灵活)的布局管理器之一,因此是的,学习如何使用它需要练习。重新阅读教程并使用约束。

关于java - GridBagLayout - 无法放置没有 anchor 的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44098121/

相关文章:

Java - 一次分割和修剪

java - 由于属性文件位置类型,应用程序或集成测试 Spring 上下文创建失败

java - swing 组件的名称属性是什么?

java - 如何设置 Swing 计时器在启动时执行

c# - 将禁用的 TextBox 的 ForeColor 设置为与其在 C# 中的 BackColor 相同

java - 导致替代 JVM 语言的真实用例是什么?

java - JSOUP同时提取多个元素

java - 如何在 JTextField 上设置焦点?

objective-c - 工作表从 View 中弹出

java - Swing 上的平铺式窗口