2

I've created an SSCCE to demonstrate my problem. I have a multi-line JLabel which wraps beautifully, but when packed into a JFrame, the extra height required due to line wrapping is not taken into account, so the window needs to be scrolled or resized. Here is the window at creation time:

enter image description here

I would prefer the window to be initialised with correct size, like so:

enter image description here

I have tried every combination of fill, growth, span, minimum, preferred, maximum, etc., but I can't get the behaviour I want. I've also experimented with JTextAreas, but they have given me even more problems than JLabels.

Here's my single-file SSCCE:

package SSCCE;

import net.miginfocom.swing.MigLayout;
import java.awt.*;
import javax.swing.*;
import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS;
import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS;

public class App
{
    public static void main( String[] args ) {
        App program = new App();
        SwingUtilities.invokeLater(program::run);
    }

    private void run() {
        JFrame w = new JFrame();
        w.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);



        // "main" shall contain everything to be packed into the JFrame.
        JPanel main = new JPanel();
        main.setLayout(new MigLayout(
                "debug",
                "[][][][][]", // cols
                "[][][fill, grow]" // rows
        ));

        // First row (search UI)
        main.add(new JLabel("Chinese character:"), "spany 2");
        main.add(new JTextField("type here"), "growx, spanx 3");
        main.add(new JButton("Search"), "spany 2, wrap");

        // Second row (checkboxes)
        main.add(new JCheckBox("box1"));
        main.add(new JCheckBox("box2"));
        main.add(new JCheckBox("box3"), "wrap");



        // Third row setup: a 'content' JPanel to be viewed by a JScrollPane, the latter which is to be added to the main JPanel.
        JPanel content = new JPanel();
        content.setLayout(new MigLayout(
                "debug, wrap 4",
                "[left][][][fill, grow]", // cols
                "[top][fill]" // rows
        ));

        // First row of 'content' JPanel: The multi-line JLabel which wraps beautifully but doesn't pack properly.
        JLabel tutorial = new JLabel("<html>" +
                "**WELCOME**<br>This is an English-language interface for the Chinese character etymology search engine     'XiaoXue', " +
                "produced by the Taiwanese academic institution Academia Sinica (中央研究院).<br> NOTE: if the text     between " +
                "those brackets doesn't display, Chinese language support is not configured on your computer." +
                "<br><br>" +
                "**HOW TO USE**<br>Simply enter a single Chinese character into the search field and press 'enter' or     the " +
                "Search button. The checkboxes below the search field are non-operational and merely proof-of-concept     for a future capability to " +
                "combine resources from different databases.<br>NOTE: supports traditional Chinese characters (and those     shared with Japanese), " +
                "but not simplified."
                + "</html>");
        tutorial.setPreferredSize(new Dimension(1,1)); // This encourages the JLabel to wrap.
        content.add(tutorial, "grow, spanx 4");

        // Second row of 'content' JPanel:
        content.add(new JLabel("label1"), "");
        content.add(new JLabel("label2"), "");
        content.add(new JLabel("label3"), "");
        content.add(new JLabel("label4"), "");

        // JScrollPane view of the 'content' JPanel
        JScrollPane contentScrollPane = new JScrollPane(content, VERTICAL_SCROLLBAR_ALWAYS, HORIZONTAL_SCROLLBAR_ALWAYS);
        contentScrollPane.getVerticalScrollBar().setUnitIncrement(20);
        contentScrollPane.getHorizontalScrollBar().setUnitIncrement(50);

        // Third row finally added to main JPanel.
        main.add(contentScrollPane, "span, width :100%:");



        w.add(main);
        w.pack();
        w.setVisible(true);
    }
}
Jamie Birch
  • 5,839
  • 1
  • 46
  • 60

1 Answers1

-2

You don't necessarily have to change all of the contents inside your JPanel. You could just change the size of the JFrame from the start. Try putting w.setSize(200, 400); or something like that to change the size of the JFrame.

Another solution would be to use w.pack() but I'm not sure if that would work.

Eames
  • 321
  • 2
  • 19
  • I'm looking rather for a dynamic solution. The size required to pack the window correctly on my system will surely vary between platforms, and I don't want to recalculate it any time I change the text anyway. – Jamie Birch Apr 07 '16 at 13:10
  • when you use the 'setSize()' method, it won't resize automatically (granted you didn't use the 'pack()' method. You can also use the 'setResizable(false)' method so it won't resize. You might also want to look into getting the screen resolution from the computer and working with that. – Eames Apr 07 '16 at 13:16