3

I am designing a Swing form using the GUI builder of Netbeans, and I'm using HTML to word wrap a JRadioButton. That works, but now the encapsulating JFrame does not resize the JFrame to fit the contents. I'm using the default GUI builder's LayoutManager, GroupLayout.

I tried to calculate the height of the component after it is word wrapped by HTML. That worked (see code below), but after setting the size and preferred size of the JRadioButton, the window does not get resized.

How can I fix it?

private void recalculateSize(JComponent component, int width) {
    View v = (View) component.getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey);
    float preferredSpan = v.getPreferredSpan(View.Y_AXIS);
    int height = component.getHeight();
    float margin = height - preferredSpan;

    Dimension actualSize = getActualSize(component, width);
    int actualHeight = (int) (actualSize.height + margin);

Dimension d = new Dimension(component.getPreferredSize().width, actualHeight);
    component.setPreferredSize(d);
    component.setSize(d);

    // This height is the real height. I tested it setting the background
    // color to red.
    System.out.println("Actual height: " + actualHeight);
}

private static Dimension getActualSize(JComponent component, int width) {
    View view = (View) component.getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey);
    view.setSize(width, 0);
    float w = view.getPreferredSpan(View.X_AXIS);
    float h = view.getPreferredSpan(View.Y_AXIS);
    return new java.awt.Dimension((int) Math.ceil(w), (int) Math.ceil(h));
}

Below is the whole code. Since it is generated by the GUI builder, it it hard to remove the unnecessary code.

import java.awt.Dimension;
import javax.swing.JComponent;
import javax.swing.text.View;

public class Test extends javax.swing.JFrame {

    Test() {
        initComponents();
        initMoreComponents();
    }

    private void initComponents() {

        one = new javax.swing.ButtonGroup();
        two = new javax.swing.ButtonGroup();
        three = new javax.swing.JTextField();
        four = new javax.swing.JLabel();
        five = new javax.swing.JLabel();
        six = new javax.swing.JTextField();
        seven = new javax.swing.JRadioButton();
        eight = new javax.swing.JRadioButton();
        nine = new javax.swing.JLabel();
        ten = new javax.swing.JLabel();
        eleven = new javax.swing.JCheckBox();
        twelve = new javax.swing.JCheckBox();
        thirteen = new javax.swing.JCheckBox();
        fourteen = new javax.swing.JCheckBox();
        fifteen = new javax.swing.JCheckBox();
        sixteen = new javax.swing.JCheckBox();
        seventeen = new javax.swing.JButton();
        eightteen = new javax.swing.JButton();
        nineteen = new javax.swing.JButton();
        twenty = new javax.swing.JRadioButton();
        twentyone = new javax.swing.JRadioButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setPreferredSize(new java.awt.Dimension(300, 420));
        setResizable(false);
        setSize(new java.awt.Dimension(0, 0));

        four.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        four.setText("Four");
        five.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        five.setText("Five");
        one.add(seven);
        seven.setSelected(true);
        seven.setText("<html>A very long sentence, which might take up more than one line.</html>");
        one.add(eight);
        eight.setText("<html>Another multiline sentence.</html>");
        nine.setText("Nine");
        ten.setText("Ten");
        eleven.setText("Eleven");
        twelve.setText("Twelve");
        thirteen.setText("Thirteen");
        fourteen.setText("Fourteen");
        fifteen.setText("Fifteen");
        sixteen.setText("Sixteen");
        seventeen.setText("Seventeen");
        eightteen.setText("Eightteen");
        nineteen.setText("Nineteen");
        two.add(twenty);
        twenty.setText("<html>Twenty with another line of text</html>");
        two.add(twentyone);
        twentyone.setText("Twenty one");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                    .addComponent(three)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(seventeen))
                .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                    .addComponent(six)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(eightteen))
                .addGroup(layout.createSequentialGroup()
                    .addGap(0, 0, Short.MAX_VALUE)
                    .addComponent(nineteen))
                .addComponent(eight, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(nine)
                            .addComponent(four)
                            .addComponent(five)
                            .addComponent(ten)
                            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(fourteen)
                                    .addComponent(fifteen))
                                .addGap(87, 87, 87)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(twelve)
                                    .addComponent(thirteen))))
                        .addGroup(layout.createSequentialGroup()
                            .addComponent(eleven)
                            .addGap(67, 67, 67)
                            .addComponent(sixteen)))
                    .addGap(0, 101, Short.MAX_VALUE))
                .addComponent(seven, javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                    .addGap(21, 21, 21)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(twenty)
                        .addComponent(twentyone, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(nine)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(seven, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(twenty, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(twentyone)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(eight, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(29, 29, 29)
            .addComponent(four)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(three, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(seventeen))
            .addGap(18, 18, 18)
            .addComponent(five)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(six, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(eightteen))
            .addGap(18, 18, 18)
            .addComponent(ten)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(eleven)
                .addComponent(sixteen))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(fourteen)
                .addComponent(thirteen))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(fifteen)
                .addComponent(twelve))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(nineteen)
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

        pack();
    }

    private void initMoreComponents() {
        recalculateSize(this.seven, 280);
    }

    private void recalculateSize(JComponent component, int width) {
        View v = (View) component.getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey);
        float preferredSpan = v.getPreferredSpan(View.Y_AXIS);
        int height = component.getHeight();
        float margin = height - preferredSpan;

        Dimension actualSize = getActualSize(component, width);
        int actualHeight = (int) (actualSize.height + margin);

        Dimension d = new Dimension(component.getPreferredSize().width, actualHeight);
        component.setPreferredSize(d);
        component.setSize(d);
        component.revalidate();

        System.out.println("Actual height: " + actualHeight);
        System.out.println("Dimension preferred and set size: " + d);
        System.out.println("Dimension after revalidate: " + component.getPreferredSize());

        pack();
    }

    private static Dimension getActualSize(JComponent component, int width) {
        View view = (View) component.getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey);
        view.setSize(width, 0);
        float w = view.getPreferredSpan(View.X_AXIS);
        float h = view.getPreferredSpan(View.Y_AXIS);
        return new java.awt.Dimension((int) Math.ceil(w), (int) Math.ceil(h));
    }

    public static void main(String args[]) {
        new Test().setVisible(true);
    }

    private javax.swing.JCheckBox eleven;
    private javax.swing.JCheckBox fourteen;
    private javax.swing.JButton eightteen;
    private javax.swing.JButton seventeen;
    javax.swing.JTextField six;
    private javax.swing.JLabel five;
    private javax.swing.JRadioButton twentyone;
    private javax.swing.JCheckBox fifteen;
    private javax.swing.JButton nineteen;
    private javax.swing.JRadioButton seven;
    private javax.swing.ButtonGroup one;
    private javax.swing.JLabel nine;
    private javax.swing.JRadioButton twenty;
    private javax.swing.ButtonGroup two;
    private javax.swing.JRadioButton eight;
    javax.swing.JTextField three;
    private javax.swing.JLabel four;
    private javax.swing.JCheckBox sixteen;
    private javax.swing.JCheckBox thirteen;
    private javax.swing.JCheckBox twelve;
    private javax.swing.JLabel ten;                
}
MC Emperor
  • 22,334
  • 15
  • 80
  • 130
  • 2
    How can I fix it? - by post an SSCCE / MCVE short, runnable, compilable, just about JFrame and JRadioButton labeled by Html, (I hope that isn't about add JRadioButton to JEditorPanel) – mKorbel Sep 05 '15 at 15:10
  • 1
    `pack()` "Causes this `Window` to be sized to fit the preferred size and layouts of its subcomponents." – trashgod Sep 05 '15 at 16:53
  • @mKorbel That's not easy, since it is code generated by the GUI builder. – MC Emperor Sep 06 '15 at 17:43

0 Answers0