pL4Gu33
pL4Gu33

Reputation: 2095

JComboBox in a JScrollPane

i have many JComboBoxes that i add in a Panel with a BoxLayout. All works fine large Text will be wrapped in two or three Lines, that is why i am using the html Tags.

My problem is, when there are sooo many Checkboxes i will add a ScrollPane. The ScrollPane should only use "VERTICAL_SCROLLBAR_AS_NEEDED" but this will break the format from the text to only one line.

Edit:
The question is, how i can add the panel in the JScrollPane with linebreaks in the Combobox text. With the scrollpane it doesnt work.

Here is a simple Example:

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

private MySwingTest(){
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(createCenterPanel(), BorderLayout.CENTER);
    frame.setSize(400, 400);
    frame.setVisible(true);
}

private Component createCenterPanel() {

    JPanel panel = new JPanel();
    panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
    for(int i = 0 ; i < 10;i++){
        panel.add(new JCheckBox("<html>das das das das das da d da fdfsdf dfsd fsdfsdf sdfsd fsdfsd fsdf fsd fss fs </html>"));
    }
    JScrollPane pane = new JScrollPane(panel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    return pane;
}

Upvotes: 1

Views: 1022

Answers (2)

VGR
VGR

Reputation: 44414

What you really want, if I understand you correctly, is a panel that is never wider than the JScrollPane that contains it. Swing has an interface, Scrollable, specifically intended for this purpose:

class CheckboxPanel
extends JPanel
implements Scrollable {
    private final int checkBoxHeight;

    public CheckboxPanel() {
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        checkBoxHeight = new JCheckBox("Example").getPreferredSize().height;
    }

    @Override
    public boolean getScrollableTracksViewportWidth() {
        // This prevents a horizontal scrollbar from appearing.
        return true;
    }

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

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

    @Override
    public int getScrollableUnitIncrement(Rectangle visibleRect,
                                          int orientation,
                                          int direction) {
        if (orientation == SwingConstants.HORIZONTAL) {
            return 1;
        }

        return Math.min(checkBoxHeight, direction < 0 ?
            visibleRect.y : getHeight() - (visibleRect.y + visibleRect.height));
    }

    @Override
    public int getScrollableBlockIncrement(Rectangle visibleRect,
                                           int orientation,
                                           int direction) {
        if (orientation == SwingConstants.HORIZONTAL) {
            return 10;
        }

        return Math.min(visibleRect.height, direction < 0 ?
            visibleRect.y : getHeight() - (visibleRect.y + visibleRect.height));
    }
}

Upvotes: 2

Maxim Shoustin
Maxim Shoustin

Reputation: 77930

I would add some addComponentListener and set setPreferredSize for panel:

public class MySwingTest {

    JScrollPane scrollPane;

    JPanel panel;

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

    private MySwingTest(){
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createCenterPanel(), BorderLayout.CENTER);
        frame.setSize(400, 400);
        frame.setVisible(true);
    }

    private Component createCenterPanel() {

        panel = new JPanel();
        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
        for(int i = 0 ; i < 10;i++){
            panel.add(new JCheckBox("<html>das das das das das da d da fdfsdf dfsd fsdfsdf sdfsd fsdfsd fsdf fsd fss fs </html>"));
        }   

        scrollPane = new JScrollPane(panel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);   

        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

          scrollPane.addComponentListener(new ComponentAdapter() {   
             @Override
             public void componentResized(ComponentEvent e) {              
                Rectangle rect = scrollPane.getViewportBorderBounds();

              panel.setPreferredSize(new Dimension((int)rect.getWidth()-10, (int)panel.getPreferredSize().getHeight()+100)); // dummy offset
             }
          });

        return scrollPane;
    }
}

Its not ideal what you want but direction.

Hope it will help

Upvotes: 2

Related Questions