0

Given my requirements:

  • Single vertical column of JPanels.
  • Set the vertical location* of the JPanel without using the properties of a sibling.
  • Component position and size are fixed when the frame is resized.
  • Keep other layout aspects automatic (such as preferred size calculation), as much as possible

(*) Location: I mean location as in Component.setLocation(x, y).

is there a solution which is obvious, and if this is GridBagLayout, how to do this?

Details:

I want to put components vertically in a column container (like a vertical Box) by specifying their vertical location only. What is the best way to do this without loosing the other benefits of a layout such as BoxLayout?

In a vertical Box, setting the vertical position of a component must be done using a filler, or by adjusting the size of the component just above, there is no such possibility like:

panel.setLocation(getLocation().x, y)

On the other hand using a no layout container puts on me the task manage:

  • The initial size of the component
  • The container resizing events.

Here the solution of null layout is recommended, here this is a custom one, and here this is GridBagLaout. Also MIGLayout appears to be universal one (but I'd prefer no adding another library to my project).

Community
  • 1
  • 1
mins
  • 6,478
  • 12
  • 56
  • 75
  • Why not use a `JList`? .. – Andrew Thompson Sep 28 '14 at 09:43
  • *"I was focused on layouts"* Often people ignore layouts when layouts are the key. Sometimes though, people are focused on layouts when an entirely different approach might be better (e.g. list, tree, toolbar, tabbed pane..). E.G. This accepted [answer](http://stackoverflow.com/a/26080729/418556) seemed to lie in Rob Camick's `WrapLayout` but of the 3 approaches in the answer, I probably would have used the `JList`. More than one way to skin that cat. ;) – Andrew Thompson Sep 28 '14 at 10:05
  • Try my solution here http://stackoverflow.com/a/26084135/1966247 – Muhammad Sep 28 '14 at 10:51
  • *"change the y location of the cell"* `JList` supports drag-n-drop list entry reordering. – Andrew Thompson Sep 28 '14 at 13:27
  • @AndrewThompson: I think there is a confusion about what I looking for. I apologize for that, I've added an additional line in my question to clarify. I'm **not** looking for ordering rows in the list (position = index), but positioning manually the component at a specific y location in its container (position = distance from the top of container). Do you confirm you understood ordering rather than distance? – mins Sep 28 '14 at 13:33

1 Answers1

2

I have written the following program for someone who was also looking for the same requirements.

Note: Make sure to add the first element to 0 position because there will be no more components and no position will be available other than 0, 2nd to 0 or 1, 3rd to 0 or 1 or 2 and so on

public class VerticalList extends JFrame {

    JPanel pnl = null;
    TextField tf = new TextField(10);
    Box center = Box.createVerticalBox();
    JScrollPane jsp = new JScrollPane(center);
    JPanel ctrl = new JPanel(new FlowLayout());
    JButton send = new JButton("Send");


    public VerticalList() {
        jsp.setAutoscrolls(true); 
        ctrl.add(send);
        ctrl.add(new JLabel("Position:"));
        ctrl.add(tf); 
        Container cnt = getContentPane();

        cnt.add(jsp, BorderLayout.CENTER);
        cnt.add(ctrl, BorderLayout.SOUTH);
        send.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                pnl = new JPanel(new FlowLayout());

                 pnl.setBorder(BorderFactory.createLineBorder(Color.red)); 
                pnl.add(new JLabel("Added to Position: "+tf.getText()));

                pnl.setMaximumSize(new Dimension(Integer.MAX_VALUE, (int)pnl.getPreferredSize().getHeight()));
                try{
                int index = Integer.parseInt(tf.getText());
                center.add(pnl, index);
                }catch(Exception ex){
                    JOptionPane.showMessageDialog(null, "Please Provide a Valid position", "Position Error", JOptionPane.ERROR_MESSAGE);
                }
                validate();
            }
        });
        setPreferredSize(new Dimension(300, 300));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        pack();

    }

    public static void main(String[] args) {
        new VerticalList();
    }
}
Muhammad
  • 6,725
  • 5
  • 47
  • 54
  • Thanks. I'm not sure I understand well, it seems you add panels to a container, at variable sibling indexes, and let the layout position them in the proper order. What I'm looking for is setting the vertical location expressed in pixels. – mins Sep 28 '14 at 11:06
  • 1
    `setPreferredSize(new Dimension(300, 300));` See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/q/7229226/418556) (Yes.) – Andrew Thompson Sep 28 '14 at 11:12
  • @AndrewThompson setPreferredSize(Dim) is not the problem here but Layouts :) – Muhammad Sep 28 '14 at 11:40