我正在使用Netbeans的GUI构建器设计Swing表单,并且我使用HTML来自动换行JRadioButton
。这是有效的,但现在封装JFrame
不会调整JFrame的大小以适应内容。我使用默认的GUI构建器的LayoutManager GroupLayout
。
我尝试计算组件被HTML包装后的高度。这有效(见下面的代码),但在设置JRadioButton
的大小和首选大小后,窗口不会调整大小。
我该如何解决?
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));
}
以下是整个代码。由于它是由GUI构建器生成的,因此很难删除不必要的代码。
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;
}