0

I am having a JFrame looking like this:

enter image description here

When it is resized, it will make the JComboBoxes adapt to the size of the JFrame like this:

enter image description here

which is what I want. But when I add a JScrollPane, the JComboBoxes no longer adapt:

enter image description here

Any ideas how to make the JComboBoxes still fill HORIZONTAL with the added JScrollPane?(making the JScrollPane only effect the VERTICAL scrolling)

public class FillHorizonScrollVertical extends JFrame {

    private boolean withScroller = true;
    private JPanel content;

    public FillHorizonScrollVertical() {

        // FILL = BOTH for JFrame
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 1;
        c.weighty = 1;
        this.setLayout(new GridBagLayout());

        // GridLayout = All content gets the same size
        content = new JPanel(new GridLayout());

        // ADD TO THE FRAME
        JScrollPane scroller = new JScrollPane(content);
        if (withScroller)
            this.add(scroller, c);
        else
            this.add(content, c);

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);

        // ADDING THE BOXES AFTER SETTING VISIBLE
        addBoxes();
        this.pack();
    }

    /**
     * Create JComboBoxes and adding them to the JPanel
     */
    private void addBoxes() {

        // CREATE JCOMBOBOXES
        JComboBox cb1 = new JComboBox();
        cb1.addItem("");
        cb1.addItem("aaaaaaaaaaaaaaaaaa");

        JComboBox cb2 = new JComboBox();
        cb2.addItem("");

        JComboBox cb3 = new JComboBox();
        cb3.addItem("");

        content.add(cb1);
        content.add(cb2);
        content.add(cb3);
    }

    public static void main(String[] args) {
        new FillHorizonScrollVertical();
    }
}
Grains
  • 950
  • 3
  • 16
  • 35
  • WRF to your question I don't think you can do this. It will scroll vertically iff there is a Vertical scrollbar present. – Prasad Nov 15 '13 at 07:40
  • If thats the case: JScrollPane extends JComponent. Would it not be possible to @override setHorizontalScrollBar() somehow?.. – Grains Nov 15 '13 at 07:54
  • Instead of adding JComboBoxes(addBoxes()), replace with: JTextArea area = new JTextArea(); area.setPreferredSize(new Dimension(200, 200)); content.add(area);. This will make the JFrame fill Horizontal and scroll vertical. But do not manage to do the same thing with JComboBoxes. – Grains Nov 15 '13 at 08:06
  • Your use case is complete ambiguous. If you want the comboboxs to adapt with resized window, what is the point of using `JScrollPane` ? – Sage Nov 15 '13 at 08:19
  • As stated in the question I would like the JScrollPane to scroll only Vertical and not Horizontal. That is: Fill Horizontal but not Vertical. – Grains Nov 15 '13 at 08:24

3 Answers3

2

You make use of the Scrollable interface which will allows you to flag of it should track the viewports width or height. In this case, you want to track the width, which will force the view to always be the same size as the view port...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Rectangle;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ScrollableExample {

    public static void main(String[] args) {
        new ScrollableExample();
    }

    public ScrollableExample() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(new TestPane()));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements Scrollable {

        public TestPane() {
            setLayout(new GridLayout());
            JComboBox cb1 = new JComboBox();
            cb1.addItem("");
            cb1.addItem("aaaaaaaaaaaaaaaaaa");

            JComboBox cb2 = new JComboBox();
            cb2.addItem("");

            JComboBox cb3 = new JComboBox();
            cb3.addItem("");

            add(cb1);
            add(cb2);
            add(cb3);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return getPreferredSize();
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 32;
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 32;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            return true;
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            return false;
        }

    }

}

Take a look at How to use scroll panes for more details

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • 1
    +1, You can also try using the [Scrollable Panel](http://tips4java.wordpress.com/2009/12/20/scrollable-panel/) which has a simple API that allows you to control the scrolling behaviour. It seems like you want to use `FIT` for the width hint. – camickr Nov 15 '13 at 16:19
0

You can set the scrolling policy on the JScrollPane:

JScrollPane scroller = new JScrollPane(content, 
    ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

You might want to check out the Scrollable interface too, which allows fine-tuning of scrolling behaviour.

Peter Walser
  • 15,208
  • 4
  • 51
  • 78
0

Solved by adding:

cb1.setPreferredSize(new Dimension(0, 30));
cb2.setPreferredSize(new Dimension(0, 30));
cb3.setPreferredSize(new Dimension(0, 30));
Grains
  • 950
  • 3
  • 16
  • 35
  • 1
    You may wan to take a look at [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi) – MadProgrammer Nov 15 '13 at 08:47
  • Thanks for pointing that out. My problem was that the preferedWidth of JComboBox were to wide. This forced me to reset the width which seems to be highly unrecommended. As I understand it: a correctly used Layout Manager are the solution to not change PreferredSize. Unfortunately I cant see any Layout Manager to help me with the issue I were having. – Grains Nov 15 '13 at 09:44