I'm making an assignment planner program. For the containers (the assignments), I want to place certain components into certain places. However. I can only seem to move components around by using anchor. It seems as if my gridx and gridy do nothing. Could anyone point out my problem and possibly offer some suggestions. My code and a picture of the intended final result are provided below.
Code:
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;
}
}
What I want the container to look like:
This just concerns my lack of knowledge with GridBagLayout.
Start with the section from the Swing tutorial on How to Use GridBagLayout for working examples and an explanation of all the constraints.
A few things about the code:
//container.setMaximumSize(new Dimension(500,100));
Don't set a maximum size. The layout manager will determine the size of the panel.
//cCb.weightx = 0.5;
//cCb.weighty = 1;
The above code assigns all the extra space of the panel to the check box, since it is the only component with a weightx/y constraint. I doubt you want that. Try commenting out those statements to see what happens.
dueDate.setOpaque(true);
dueDate.setBackground(Color.BLUE);
Yes, that is a good idea to set a background to see the actual size of the component. Problem is a JLabel is transparent by default so the background is never painted. You need need to make your labels opaque if you want to see the background. Another approach to help with debugging is to add LineBorder to the label, then you don't need to worry about transparency.
//e.gridx = 4;
e.gridx = 3;
Be careful with the grid value. You can't just use an value. The first component has a width of 1 and the second a width of 2, so the this component should start at 3.
I can only seem to move components around by using anchor
Actually, I don't this the anchor is doing anything. As I understand it, the anchor only has meaning when the component size is smaller than the grid size. In your original code, only the check box used weightx/y values, so that is the only component where this is true.
The GridBagLayout is one of the most complicated (and flexible) layout manager to use, so yes it takes practice to learn how to use it. Reread the tutorial and play with the constraints.