1

I have a JPanel using GridBagLayout inside a JScrollPane. The GridBagLayout, has line split borders set between some columns (colored in blue). The issue is I can't get the behavior to act correctly, while removing the unnecessary right scroll bar from the JScrollPane.

The Code...

import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TestGui extends JFrame {
    //**************************************************************************************
    //************************************** Variables *************************************
    //**************************************************************************************
    private String[] showHideComboBoxValue = {"Show hiddenLabel", "Hide hiddenLabel"};
    private JComboBox showHideComboBox = createShowHideComboBox(showHideComboBoxValue);
    private JLabel labelHiddenOrShown = createDefaultLabel("This label is hidden or shown depending on the status of the combo box", 14);
    private JPanel topFrame = createTopFrame();
    private JScrollPane topFrameScroll = createTopScrollPane();
    private JScrollPane centerFrameScroll = createCenterScrollPane();

    //**************************************************************************************
    //************************************* Constructor ************************************
    //**************************************************************************************
    private TestGui() {
        add(topFrameScroll, BorderLayout.NORTH);
        add(centerFrameScroll, BorderLayout.CENTER);

        setSize(800,600);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    //**************************************************************************************
    //*********************************** Support Method ***********************************
    //**************************************************************************************
    private static GridBagConstraints setGbc(int gridx, int gridy, int gridWidth, int gridHeight, int ipadx, int ipady, String anchorLocation, double weightx, double weighty, Insets insets, boolean fillCell){
        GridBagConstraints gbc = new GridBagConstraints();

        if (anchorLocation.toUpperCase().equals("NORTHWEST")){
            gbc.anchor = GridBagConstraints.NORTHWEST;
        } else if (anchorLocation.toUpperCase().equals("NORTH")){
            gbc.anchor = GridBagConstraints.NORTH;
        } else if (anchorLocation.toUpperCase().equals("NORTHEAST")){
            gbc.anchor = GridBagConstraints.NORTHEAST;
        } else if (anchorLocation.toUpperCase().equals("WEST")){
            gbc.anchor = GridBagConstraints.WEST;
        } else if (anchorLocation.toUpperCase().equals("EAST")){
            gbc.anchor = GridBagConstraints.EAST;
        } else if (anchorLocation.toUpperCase().equals("SOUTHWEST")){
            gbc.anchor = GridBagConstraints.SOUTHWEST;
        } else if (anchorLocation.toUpperCase().equals("SOUTH")){
            gbc.anchor = GridBagConstraints.SOUTH;
        } else if (anchorLocation.toUpperCase().equals("SOUTHEAST")){
            gbc.anchor = GridBagConstraints.SOUTHEAST;
        } else {
            gbc.anchor = GridBagConstraints.CENTER;
        }

        gbc.gridx = gridx; // column
        gbc.gridy = gridy; // row
        gbc.gridwidth = gridWidth; // number of columns
        gbc.gridheight = gridHeight; // number of rows
        gbc.ipadx = ipadx; // width of object
        gbc.ipady = ipady; // height of object
        gbc.weightx = weightx; // shifts columns to side of set anchor
        gbc.weighty = weighty; // shifts rows to side of set anchor
        gbc.insets = insets; // placement inside cell
        if (fillCell){
            gbc.fill = GridBagConstraints.BOTH;
        }

        return gbc;
    }

    //**************************************************************************************
    //*********************************** Object Methods ***********************************
    //**************************************************************************************
    private JComboBox createShowHideComboBox(String[] comboValues){
        JComboBox comboBox = new JComboBox(comboValues);
        comboBox.setPrototypeDisplayValue("X" + comboValues[0] + "X");

        return comboBox;
    }

    private void createShowHideComboBoxAction(){
        showHideComboBox.addActionListener(
                new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        String selection = ((JComboBox) (e.getSource())).getSelectedItem().toString();
                        if (selection.equals(showHideComboBoxValue[1])){
                            labelHiddenOrShown.setVisible(false);
                        } else {
                            labelHiddenOrShown.setVisible(true);
                        }
                    }
                }
        );
    }

    private JLabel createDefaultLabel(String text, int textSize){
        JLabel lbl = new JLabel(text);
        lbl.setFont(new Font(text, Font.BOLD, textSize));
        return lbl;
    }

    //**************************************************************************************
    //************************************ Panel Methods ***********************************
    //**************************************************************************************
    private JPanel createTopFrame() {
        JPanel pnl = new JPanel();

        Border lineSplitterBoarder = BorderFactory.createMatteBorder(0, 0, 0, 5, Color.BLUE);
        JLabel lineSplitterOne = new JLabel();
        lineSplitterOne.setBorder(lineSplitterBoarder);
        JLabel lineSplitterTwo = new JLabel();
        lineSplitterTwo.setBorder(lineSplitterBoarder);

        pnl.setLayout(new GridBagLayout());
        createShowHideComboBoxAction();
        pnl.add(showHideComboBox,setGbc(0,1, 1,1, 0,0,"CENTER", 0, 0, new Insets(10, 10, 10, 0), false));
        pnl.add(createDefaultLabel("Label",14), setGbc(1,0,1,1,0,0,"CENTER",0,0,new Insets(10,10,0,10),false));
        pnl.add(createDefaultLabel("Label",14), setGbc(1,1,1,1,0,0,"CENTER",0,0,new Insets(0,10,0,10),false));
        pnl.add(createDefaultLabel("Label",14), setGbc(1,2,1,1,0,0,"CENTER",0,0,new Insets(0,10,0,10),false));
        pnl.add(createDefaultLabel("Label",14), setGbc(1,3,1,1,0,0,"CENTER",0,0,new Insets(0,10,10,10),false));
        pnl.add(lineSplitterOne, setGbc(2,0,1,4,0,0,"CENTER",0,0,new Insets(0,0,0,0),true));
        pnl.add(createDefaultLabel("Hidden Label Below", 14), setGbc(3,0,8,1,9,9,"CENTER",0,0,new Insets(10,10,0,10),false));
        JPanel labelHiddenOrShownPanel = new JPanel();
        labelHiddenOrShownPanel.setLayout(new GridLayout(1,1));
        labelHiddenOrShownPanel.add(labelHiddenOrShown);
        pnl.add(labelHiddenOrShownPanel, setGbc(3,1,1,1,0,0,"WEST",0,0,new Insets(0,5,0,0),false));
        pnl.add(lineSplitterTwo, setGbc(11,0,1,4,0,0,"CENTER",0,0,new Insets(0,5,0,0),true));
        pnl.add(createDefaultLabel("Label",14), setGbc(12,0,1,1,0,0,"CENTER",0,0,new Insets(10,10,0,0),false));
        pnl.add(createDefaultLabel("Label",14), setGbc(12,1,1,1,0,0,"CENTER",0,0,new Insets(0,10,0,0),false));
        pnl.add(createDefaultLabel("Label",14), setGbc(12,2,1,1,0,0,"CENTER",0,0,new Insets(0,10,0,0),false));
        pnl.add(createDefaultLabel("Label",14), setGbc(12,3,1,1,0,0,"CENTER",0,0,new Insets(0,10,10,0),false));

        return pnl;
    }

    private JScrollPane createTopScrollPane(){
        JScrollPane scrollPane = new JScrollPane();
        Border raisedBevel = BorderFactory.createRaisedBevelBorder();
        Border lineBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, new Color(224,224,224));
        Border loweredBevel = BorderFactory.createLoweredBevelBorder();
        Border compoundSetup = BorderFactory.createCompoundBorder(raisedBevel, lineBorder);
        Border compoundFinal = BorderFactory.createCompoundBorder(compoundSetup, loweredBevel);

        //scrollPane.setPreferredSize(new Dimension(0, 160));
        scrollPane.setBorder(compoundFinal);
        scrollPane.getViewport().setView(topFrame);
        return scrollPane;
    }

    private JScrollPane createCenterScrollPane(){
        JScrollPane scrollPane = new JScrollPane();
        Border raisedBevel = BorderFactory.createRaisedBevelBorder();
        Border lineBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, new Color(224,224,224));
        Border loweredBevel = BorderFactory.createLoweredBevelBorder();
        Border compoundSetup = BorderFactory.createCompoundBorder(raisedBevel, lineBorder);
        Border compoundFinal = BorderFactory.createCompoundBorder(compoundSetup, loweredBevel);

        scrollPane.setBorder(compoundFinal);
        return scrollPane;
    }

    //**************************************************************************************
    //************************************ Start Program ***********************************
    //**************************************************************************************
    public static void main(String[] args) {
        new TestGui();
    }
}

Steps to reproduce issue(s)...

Step 1: run the program and observe the unnecessary scroll bar on the right of the top JScrollPane... enter image description here

Step 2: maximize the window, and watch both scroll bars disappear with the objects in the JPanel being put where they should be... enter image description here This behavior is good and we want to keep this. You can close the program now.

Step 3: Now to remove the right scroll bar (in Step 1), lets change a line of code (line#145) from //scrollPane.setPreferredSize(new Dimension(0, 160)); to scrollPane.setPreferredSize(new Dimension(0, 160));, and re-run the program... enter image description here Great! the right bar was removed. But wait a minute...

Step 4: Now lets maximize the window... enter image description here Notice extra space added between the border lines (we don't want this behavior).

Note 1: It's important to keep the option to show/hide hidden label without resizing the cells in the GridBagLayout. After researching, the only way I found to do this was to have the hidden JLabel in it's own JPanel using GridLayout.

Note 2: I noticed this behavior (in Step 1) started happening after the width became long enough to require the horizontal scroll bar to start appearing.

What I need is the behavior from image 3 (when window is not maximized), and image 2 (when window is maximized). If anyone has any idea to get these 2 combinations of behaviors working together, please help. Thanks

Update: due to complaints of code being too large, I shortened it to 169 lines. Every component in this code is required to monitor the 2 behaviors as mentioned above.

Fiddle Freak
  • 1,923
  • 5
  • 43
  • 83
  • 1
    Post a proper [mcve] to demonstrate the problem. This is a layout issue. You don' t need 500 lines of code to demonstrate this. For example you don't need all the combo boxes in the right panel. All you need is a single component with a width greater than the width of the frame to force the horizontal scrollbar. – camickr May 11 '17 at 04:44
  • there is no right panel, what do you mean by this? Add a single component? what component? I feel this question posted a minimal, complete, and verifiable example demonstrating the problem. – Fiddle Freak May 11 '17 at 05:15
  • Also note, the behavior on just adding an (say empty label) to force the width of the 8 combo boxes (so the JPanels were not used), ended up resulting in the 8 combo slots size expanding and collapsing with different behaviors. It was really unmanageable. – Fiddle Freak May 11 '17 at 05:28
  • You reposted this question, so why not delete this question so people don't spend time read that question that already has an answer? – camickr May 11 '17 at 15:23
  • Okay, I'll go ahead and do that. – Fiddle Freak May 11 '17 at 15:32
  • I felt this question needs to be left up for the purpose of being accused of "not updating/fixing my question". To all others, here is where the answer can be found > http://stackoverflow.com/questions/43915822/jscrollpane-sethorizontalscrollbarpolicy-as-needed-without-resizing-content/43916564?noredirect=1#comment74870099_43916564 – Fiddle Freak May 11 '17 at 21:23

0 Answers0