GridBagLayout - 无法放置没有锚点的组件

时间:2017-05-21 14:38:03

标签: java swing user-interface layout-manager gridbaglayout

我正在制作任务计划程序。对于容器(分配),我想将某些组件放入某些位置。然而。我似乎只能通过使用锚移动组件。似乎我的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

1 个答案:

答案 0 :(得分:3)

  

这只是因为我对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开始。

  

我似乎只能使用锚

来移动组件

实际上,我不知道锚是做什么的。据我了解,当组件大小小于网格大小时,锚只有意义。在原始代码中,只有复选框使用了weightx / y值,因此这是唯一的组件。

GridBagLayout是最复杂(也是最灵活)的布局管理器之一,所以是的,需要练习才能学会如何使用它。重读教程并使用约束。