0

I'm currently designing a GUI assignment planner. I have run across a few issues along the way. For one part of my program I have a panel to hold assignments that still need to be completed. What I would like to create is a panel that will add containers (holding the components to display an assignment) to a panel. However, the only way I can conceive of doing this is by lengthening the panel each time a container is added. Unfortunately, to the best of knowledge, this isn't possible since a panel is given a defined width and depth when it is created. Ideally, if possible, I'd like to increase the panel length every time a container is added. A scrollbar would scroll down the panel.

So is this possible? Am I approaching this the right way? I am very new to GUI so I am open to improvements and suggestions. If anyone would like me to post my code so far, I will. (Beware, it is in very rough shape at the moment)

Attached below is a rough draft of what I am trying to make:

enter image description here

TIA

This is the majority of my code so far. The problem is that once i add a certain amount of containers it starts to make them smaller. I just want to extend it every time a container is added. Most of the comments are for documentation or to remind to do something.

import javax.swing.*;
import java.awt.*;
//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;
    //ArrayList<JFrame> frame = new ArrayList<>();

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

    private void contents()
    {//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, 250));
        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(assignment());
        toDoList.add(Box.createRigidArea(new Dimension(0,1)));
        toDoList.add(assignment());
        toDoList.add(Box.createRigidArea(new Dimension(0,1)));
        toDoList.add(assignment());
        toDoList.add(Box.createRigidArea(new Dimension(0,1)));
        beginningScrollPaneValue += 110;
        toDoList.setPreferredSize(new Dimension(250, beginningScrollPaneValue));
        toDoList.revalidate(); //scroll.revalidate();
        toDoList.repaint(); //scroll.repaint();

        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 c = new GridBagConstraints();
        c.weightx = 0.5;

        JCheckBox cb = new JCheckBox();
        c.fill = GridBagConstraints.NONE;
        c.gridx = 1;
        c.gridy = 0;
        container.add(cb, c);
        container.setBackground(Color.red);//does no fill area behind checkbox

        return container;
    }
}
John
  • 77
  • 2
  • 11
  • 1
    *"Unfortunately, to the best of knowledge, this isn't possible since a panel is given a defined width and depth when it is created"* - It should be, it should be given a layout manager which can calculate the size requirements based on the child components - This would then allow you to use a `JScrollPane` to wrap the container and automatically display the scrollbars as the container exceeded the view bounds of the scollpane – MadProgrammer May 20 '17 at 02:13
  • 2
    Maybe you should have a look at [Laying Out Components Within a Container](http://docs.oracle.com/javase/tutorial/uiswing/layout/index.html) and [How to Use Scroll Panes](http://docs.oracle.com/javase/tutorial/uiswing/components/scrollpane.html) – MadProgrammer May 20 '17 at 02:14
  • @MadProgrammer So if I were to add an assignment (container), it would just recalculate the size of the panel? I ask because my panel will constantly have assignments added to it or taken away from it (moved to the completed panel). – John May 20 '17 at 02:17
  • More or less. When dynamically adding components, you can invoke a layout pass using `revalidate` and paint pass using `repaint` – MadProgrammer May 20 '17 at 02:20
  • @MadProgrammer Lastly, in your first comment you mentioned that a layout manager would do the calculations. Since all managers differ, which would you recommend to me for this purpose. I'm using BoxLayout for this particular panel at the moment. – John May 20 '17 at 02:27
  • That's a matter of opinion, I'm partial to GridBagLayout myself, but VerticalLayout from the SwingX library might also be a good fit – MadProgrammer May 20 '17 at 02:30
  • 1
    I'd look at a custom renderer in a `Scrollable` component, for [example](http://stackoverflow.com/a/5760093/230513). – trashgod May 20 '17 at 06:00
  • 1
    I agree with @trashgod re. using a scrollable component. The linked example demonstrates use of a list, which is the first component I'd thought of when looking at the drawings. OTOH the requirement to 'move completed tasks to end' would be simpler if using a `JTable` (with a row filter / sorter). – Andrew Thompson May 20 '17 at 08:28
  • 1
    Endorsing @AndrewThompson's `JTable` suggestion, note that it supports editors, as well as renderers, for [example](http://stackoverflow.com/a/11179669/230513). – trashgod May 20 '17 at 11:51
  • @AndrewThompson What I meant by move completed assignments was to a separate, "completed" panel. Also, could you elaborate why the way suggested by you and trashgod would better solve my issue than the way suggested by MadProgrammer. – John May 20 '17 at 13:05
  • @trashgod Do you mind explaining a custom renderer to me, I'm not familiar. Also, if you wouldn't mind following suit with Andrew, could you explain why this is better than MadProgrammer's suggestion? – John May 20 '17 at 13:06
  • Lists and tables are purpose built for displaying lists and tabular information. They have lots of built in methods for making it easier. Note that the list in this case would be holding a group of custom objects each with its own attributes. That's where the renderer comes in handy. It could use a panel as the base, and layout a check box, due date, description and ..I'm not sure what that last datum is, a 'course ID'? The table would probably make it a little trickier to get the exact layout as seen above (they are specialised for columns of data) but also provides inbuilt sorting. .. – Andrew Thompson May 20 '17 at 13:16
  • .. Each of the list and table uses a model for the data, so change the model and the changes are automatically reflected in the component (the 'view' of model-view-controller). – Andrew Thompson May 20 '17 at 13:17
  • @MadProgrammer I was wondering if you still stand by what you said or if you suggest what trash and Andrew suggested? – John May 20 '17 at 20:52
  • We're all suggesting `Scrollable`; look at how many `JComponent` subclasses implement it; the [tutorial](https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#editrender) explains renderer's and editors; after reading, please edit your question to include a [mcve] that demonstrates any problem you encounter in your chosen an approach. – trashgod May 20 '17 at 21:39
  • @trashgod I haven't been home all day so I'll try and upload my progress in a timely manor. – John May 20 '17 at 21:52
  • @JohnEakin It depends on the complexity of the data – MadProgrammer May 20 '17 at 22:04
  • @MadProgrammer After some further research and trial and error, I'v learned that JScrollPane has its own layout manager. In order to use something like grid layout I would have to add a panel to the scroolPane. Doesn't this defeat the purpose of dynamically changing the size? Will JScrollPane's layout manager suffice for adding containers vertically? Correct me if I'm wrong, but aren't I at square one again? – John May 20 '17 at 22:56
  • @JohnEakin The idea of `JScrollPane` is that you place some other component within it (applied to the `JViewport` to be exact), so your component can have what ever layout manager you want, the `JScrollPane` will then manage the `JScrollBar`s and the `JViewport` and the `JViewport` will manage your component – MadProgrammer May 20 '17 at 22:58
  • @MadProgrammer Update, please ignore the comment above. My current problem is outlined above the code. Is it just a matter of changing the preferred size of the scrollpane and re-validating? – John May 21 '17 at 01:09
  • Never mind it has been fixed. – John May 21 '17 at 02:17

0 Answers0