Frage

I have made a layout using a GridBagLayout to force sub-components to stack from the bottom and up.

The only thing I have left is to make the "container" component scrollable.

I have tried inserting the JScrollPane in different locations, but I fail to find a working spot.

My 2 inner JPanels are aligned correctly at the bottom and they resize correctly when I resize the window. But when I resize the window too small for the text to fit, I want the "container" component to scroll.

Please help a newbie :)

UPDATE 1: The scroll should be for the whole GridBagLayout. Not for each individual textpane's.

UPDATE 2: Changed the code to use BorderLayout instead, as it makes no difference to my scroll problem.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;

public class BorderTest extends JFrame {

private static final long serialVersionUID = 1L;

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new BorderTest().setVisible(true);
        }
    });
}

public BorderTest() {

    UIManager.put("swing.boldMetal", Boolean.FALSE);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("Grid Bag");
    setSize(500, 300);
    setLocationRelativeTo(null);

    JPanel container = new JPanel();
    container.setLayout(new BorderLayout());
    container.setBorder(new LineBorder(Color.RED, 2));
    add(container);

    JPanel bottom = new JPanel();
    bottom.setBorder(new LineBorder(Color.YELLOW, 2));
    bottom.setLayout(new BoxLayout(bottom, BoxLayout.Y_AXIS));
    container.add(bottom, BorderLayout.SOUTH);

    JTextPane textPane = new JTextPane();
    textPane.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
    textPane.setBorder(new LineBorder(Color.GREEN, 2));
    bottom.add(textPane);

    JTextPane textPane2 = new JTextPane();
    textPane2.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
    textPane2.setBorder(new LineBorder(Color.BLUE, 2));
    bottom.add(textPane2);

}

}

Screenshot when running the above code:

enter image description here

When I make the window smaller, the items does not fit (of course) and I then want vertical scrollbars to appear (but not horizontal as the words should just wrap instead)

enter image description here

As you can see, the "red" border are "outside" of the window, so putting a scrollpane here seems like a good idea. Here is the code with a scrollpane added:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;

public class BorderTest extends JFrame {

private static final long serialVersionUID = 1L;

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new BorderTest().setVisible(true);
        }
    });
}

public BorderTest() {

    UIManager.put("swing.boldMetal", Boolean.FALSE);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("Grid Bag");
    setSize(500, 300);
    setLocationRelativeTo(null);

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setBorder(new LineBorder(Color.CYAN, 2));
    add(scrollPane);

    JPanel container = new JPanel();
    container.setLayout(new BorderLayout());
    container.setBorder(new LineBorder(Color.RED, 2));
    scrollPane.setViewportView(container);

    JPanel innerContainer = new JPanel();
    innerContainer.setLayout(new BorderLayout());
    innerContainer.setBorder(new LineBorder(Color.PINK, 2));
    scrollPane.setViewportView(innerContainer);

    JPanel bottom = new JPanel();
    bottom.setBorder(new LineBorder(Color.YELLOW, 2));
    bottom.setLayout(new BoxLayout(bottom, BoxLayout.Y_AXIS));
    innerContainer.add(bottom, BorderLayout.SOUTH);

    JTextPane textPane = new JTextPane();
    textPane.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
    textPane.setBorder(new LineBorder(Color.GREEN, 2));
    bottom.add(textPane);

    JTextPane textPane2 = new JTextPane();
    textPane2.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
    textPane2.setBorder(new LineBorder(Color.BLUE, 2));
    bottom.add(textPane2);

}

}

But the result is not what I want. Now horizontal scoll bars are added and making my text items one huge row wide:

enter image description here

War es hilfreich?

Lösung

To add a JScrollPane to a component, you simply have to create a JScrollPane with that component and then add the JScrollPane to the panel where you want the component.

So instead of:

panel.add(component, constraints);

use

JScrollPane scrollPane = new JScrollPane(component);
panel.add(scrollPane, constraints);

Of course you can use the scrollPane variable to customize the JScrollPane a little bit, check the documentation for it, but by simpling putting this in your code we have:

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;

public class GridBag extends JFrame
{

    private static final long serialVersionUID = 1L;

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run()
            {
                new GridBag().setVisible(true);
            }
        });
    }

    public GridBag()
    {

        UIManager.put("swing.boldMetal", Boolean.FALSE);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Grid Bag");
        setSize(500, 300);
        setLocationRelativeTo(null);

        JPanel container = new JPanel(new GridBagLayout());
        container.setBorder(new LineBorder(Color.RED, 2));
        add(container);

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 1;
        c.weightx = 1.0;
        c.weighty = 1.0;
        c.anchor = GridBagConstraints.LAST_LINE_START;

        JPanel bottom = new JPanel();
        bottom.setLayout(new BoxLayout(bottom, BoxLayout.Y_AXIS));
        bottom.setBorder(new LineBorder(Color.GREEN, 2));
        container.add(bottom, c);

        JTextPane textPane = new JTextPane();
        textPane.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
        textPane.setBorder(new LineBorder(Color.BLACK, 2));
        bottom.add(new JScrollPane(textPane));

        JTextPane textPane2 = new JTextPane();
        textPane2.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
        textPane2.setBorder(new LineBorder(Color.BLUE, 2));
        bottom.add(new JScrollPane(textPane2));
    }
}

And makes it look like this:

enter image description here

Which works but doesn't look very nice, so let me show you an example of how to make the proper height distribution using the GridBagConstraints.weighty properties.

What I'm going to do is add two panels to the GridBagLayout (2 cells) one over the other and use the weighty numbers to tell them how much space to take. For this I'll want to change the c.fill to BOTH.

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;

public class GridBag extends JFrame
{

    private static final long serialVersionUID = 1L;

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run()
            {
                new GridBag().setVisible(true);
            }
        });
    }

    public GridBag()
    {

        UIManager.put("swing.boldMetal", Boolean.FALSE);

        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setTitle("Grid Bag");
        setSize(500, 300);
        setLocationRelativeTo(null);

        JPanel container = new JPanel(new GridBagLayout());
        container.setBorder(new LineBorder(Color.RED, 2));
        add(container);

        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH; //make it fill both directions
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1.0;
        c.weighty = 1.0; //modify this number to change the proportion of the screen division
        c.anchor = GridBagConstraints.CENTER; //for this example anything here goes.

        JPanel topPanel = new JPanel();
        topPanel.add(new JTextField("Put other components here"));
        //topPanel.setBorder(new LineBorder(Color.YELLOW, 2));
        container.add(topPanel, c);

        c.gridy = 1;
        c.weighty = 1.0; //modify this number to change the proportion of the screen division

        JPanel bottom = new JPanel();
        bottom.setLayout(new BoxLayout(bottom, BoxLayout.Y_AXIS));
        bottom.setBorder(new LineBorder(Color.GREEN, 2));
        container.add(bottom, c);

        JTextPane textPane = new JTextPane();
        textPane.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
        textPane.setBorder(new LineBorder(Color.BLACK, 2));
        bottom.add(new JScrollPane(textPane));

        JTextPane textPane2 = new JTextPane();
        textPane2.setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et ");
        textPane2.setBorder(new LineBorder(Color.BLUE, 2));
        bottom.add(new JScrollPane(textPane2));
    }
}

And looks like this:

enter image description here

This takes half of the screen for the top components and half for the two textPanes, this is because the weighty of both cells (topPanel and bottom) is 1.0, the same value, so the proportion is 1:1. You can change those numbers to change how much space do they take. For example putting the first weighty to 0.5 will make it a proportion 1:2.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top