Home > Enterprise >  Tell BoxLayout which component to stretch, and and to disallow others?
Tell BoxLayout which component to stretch, and and to disallow others?

Time:12-01

I've got a basic swing GUI set up, including a dialog window. It looks the way I want it to, and acts the way I want it to... except that when I resize the dialog window vertically, it stretches a text field instead of the JScrollPane like I would like it to do.

I've found lots of advice around the web about resizing in general, but I couldn't figure out how to apply what I'd found to this specific issue.

Following is an example to replicate the behavior. I'd rather keep the BoxLayout managers, as I've already been through many other issues with other managers, and this setup is finally working... only with this one small remaining issue.

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;

public class ExampleDialog extends JDialog {
    private static final long serialVersionUID = 1L;

    public static void main(String[] args) {
        ExampleDialog dialog = new ExampleDialog(null, "Title", true);
        dialog.setVisible(true);
    }
    
    public ExampleDialog(JFrame parent, String title, boolean modal) 
    {
        super(parent, title, modal);
        
        
        // Top panel
        
        JTextField field = new JTextField();
        field.setText("Text");
        field.setEnabled(false);

        JButton button1 = new JButton("Button 1");
        
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
        topPanel.add(field);
        topPanel.add(button1);
        
        
        // Middle panel
        
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
        for (int i=0; i<30; i  )
            root.add(new DefaultMutableTreeNode(String.format("00d", i)));
        ExamplePanel middlePanel = new ExamplePanel(new DefaultTreeModel(root));
        
        
        // Bottom panel
        
        JButton button2 = new JButton("Button 2");
        JButton button3 = new JButton("Button 3");
        
        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
        
        bottomPanel.add(button2);
        bottomPanel.add(button3);
        
        
        // Content panel
        
        JPanel contentPanel = new JPanel();
        contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
        contentPanel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
        
        contentPanel.add(topPanel);
        contentPanel.add(middlePanel);
        contentPanel.add(bottomPanel);
        
        this.setContentPane(contentPanel);
        
        this.pack();
    }

    public class ExamplePanel extends JScrollPane {
        private static final long serialVersionUID = 1L;
        
        public ExamplePanel(TreeModel model) {
            super();
            
            JTree tree = new JTree(model);
            
            tree.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
            this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            this.setViewportView(tree);
        }
    }
}

Looks good: Before scaling

Until I scale it (vertically): After vertical scaling

Horizontal scaling works great. Can you help me figure out what I need to change?

Note, all the border stuff in the code is leftover from a coworker, and I haven't played with it much. Nor do I understand what exactly it's trying to accomplish. So I don't know if that's part of the problem, unrelated, or perhaps even accomplishing absolutely nothing.

Thanks!

CodePudding user response:

As mentioned in the comment:

  • BoxLayout has same space for all components.
  • BorderLayout would give maximum space to the center component.
  • GridBagLayout allows you to grow components indiviually. It is the most capable yet most complex one to use - but it is worth taking a look. It can replace almost all the other available layout managers.

CodePudding user response:

Based on Gilbert Le Blanc's comment on the question, I swapped out a BoxLayout for a BorderLayout-- and will hope that I can fix any errors that I run into because of it!

There were a few other small changes needed-- here's the updated version:

// ADDED
import java.awt.BorderLayout;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;

public class ExampleDialog extends JDialog {
    private static final long serialVersionUID = 1L;

    public static void main(String[] args) {
        ExampleDialog dialog = new ExampleDialog(null, "Title", true);
        dialog.setVisible(true);
    }
    
    public ExampleDialog(JFrame parent, String title, boolean modal) 
    {
        super(parent, title, modal);
        
        
        // Top panel
        
        JTextField field = new JTextField();
        field.setText("Text");
        field.setEnabled(false);

        JButton button1 = new JButton("Button 1");
        
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
        topPanel.add(field);
        topPanel.add(button1);
        
        
        // Middle panel
        
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
        for (int i=0; i<30; i  )
            root.add(new DefaultMutableTreeNode(String.format("00d", i)));
        ExamplePanel middlePanel = new ExamplePanel(new DefaultTreeModel(root));
        
        
        // Bottom panel
        
        JButton button2 = new JButton("Button 2");
        JButton button3 = new JButton("Button 3");
        
        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
        
        bottomPanel.add(button2);
        bottomPanel.add(button3);

        // ADDED
        JPanel bottomPanelHolder = new JPanel();
        bottomPanelHolder.setLayout(new BoxLayout(bottomPanelHolder, BoxLayout.Y_AXIS));
        bottomPanelHolder.add(bottomPanel);
        
        
        // Content panel
        
        JPanel contentPanel = new JPanel();

        // REMOVED
        //contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
        // ADDED
        contentPanel.setLayout(new BorderLayout());

        contentPanel.setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));

        // REMOVED
        //contentPanel.add(topPanel);
        //contentPanel.add(middlePanel);
        //contentPanel.add(bottomPanel);
        // ADDED
        contentPanel.add(topPanel, BorderLayout.PAGE_START);
        contentPanel.add(middlePanel, BorderLayout.CENTER);
        contentPanel.add(bottomPanelHolder, BorderLayout.PAGE_END);
        
        this.setContentPane(contentPanel);
        
        this.pack();
    }

    public class ExamplePanel extends JScrollPane {
        private static final long serialVersionUID = 1L;
        
        public ExamplePanel(TreeModel model) {
            super();
            
            JTree tree = new JTree(model);
            
            tree.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
            this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            this.setViewportView(tree);
        }
    }
}
  • Related