我正在研究JComboBox
的维度(我不知道是否有其他Swing对象)。
打印尺寸时会出现问题。 这是一个错误吗?
这是我的代码:
JPanel jpPanelOut = new JPanel();
jpPanelOut.setBackground(new java.awt.Color(255, 255, 255));
jpPanelOut.setLayout(new BoxLayout(jpPanelOut, BoxLayout.PAGE_AXIS));
JPanel jpPanel = new JPanel();
jpPanel.setPreferredSize(new Dimension(800, 26));
Font inFont = new Font("Serif", Font.PLAIN, 10);
JPanel jpPanel0 = new JPanel();
jpPanel0.setLayout(new BoxLayout(jpPanel0, BoxLayout.LINE_AXIS));
JLabel jlLabel0 = new JLabel("this is a new text");
jlLabel0.setBorder(javax.swing.BorderFactory.createEtchedBorder());
jlLabel0.setFont(inFont);
JSlider jslSlider0 = new JSlider(JSlider.HORIZONTAL, 0, 1000000000, 1);
jslSlider0.setFont(inFont);
JSpinner jspSpinner0 = new JSpinner(new SpinnerNumberModel(1, 0, 1000000000, 1));
jspSpinner0.setFont(inFont);
JTextField jtfTextField0 = new JTextField("1234567890abcdef_gpqyTÑ",48);
jtfTextField0.setFont(inFont);
JComboBox jcbComboBox0 = new JComboBox<>(new String[] {"Average"});
jcbComboBox0.setFont(inFont);
((JLabel)jcbComboBox0.getRenderer()).setHorizontalAlignment(JLabel.RIGHT);
jpPanel0.add(jlLabel0);
jpPanel0.add(jslSlider0);
jpPanel0.add(jspSpinner0);
jpPanel0.add(jtfTextField0);
jpPanel0.add(jcbComboBox0);
inFont = new Font("Serif", Font.PLAIN, 10);
JPanel jpPanel1 = new JPanel();
jpPanel1.setLayout(new BoxLayout(jpPanel1, BoxLayout.LINE_AXIS));
JLabel jlLabel1 = new JLabel("this is a new text");
jlLabel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
jlLabel1.setFont(inFont);
JSlider jslSlider1 = new JSlider(JSlider.HORIZONTAL, 0, 1000000000, 1);
jslSlider1.setFont(inFont);
JSpinner jspSpinner1 = new JSpinner(new SpinnerNumberModel(1, 0, 1000000000, 1));
jspSpinner1.setFont(inFont);
JTextField jtfTextField1 = new JTextField("1234567890abcdef_gpqyTÑ",48);
jtfTextField1.setFont(inFont);
JComboBox jcbComboBox1 = new JComboBox<>(new String[] {"Average"});
jcbComboBox1.setFont(inFont);
((JLabel)jcbComboBox1.getRenderer()).setHorizontalAlignment(JLabel.RIGHT);
jpPanel1.add(jlLabel1);
jpPanel1.add(jslSlider1);
jpPanel1.add(jspSpinner1);
jpPanel1.add(jtfTextField1);
jpPanel1.add(jcbComboBox1);
System.out.println("Height:"
+ " jtfTextField:" + jtfTextField1.getPreferredSize().getHeight() + ","
+ jtfTextField1.getMinimumSize().getHeight()
+ " jlLabel:" + jlLabel1.getPreferredSize().getHeight() + ","
+ jlLabel1.getMinimumSize().getHeight()
+ " jcbComboBox:" + jcbComboBox1.getPreferredSize().getHeight() + ","
+ jcbComboBox1.getMinimumSize().getHeight()
+ " jslSlider:" + jslSlider1.getPreferredSize().getHeight() + ","
+ jslSlider1.getMinimumSize().getHeight()
+ " jspSpinner:" + jspSpinner1.getPreferredSize().getHeight() + ","
+ jspSpinner1.getMinimumSize().getHeight()
);
jpPanelOut.add(jpPanel);
jpPanelOut.add(jpPanel0);
jpPanelOut.add(jpPanel1);
但维度已经改变!!!
请看:
JTextFields的亮度(宽度)红圈
JComboBoxs 绿线
的上诉(文字)完整代码
package myPackage;
import javax.swing.*;
import java.awt.*;
public class NewJFrame extends javax.swing.JFrame {
public NewJFrame() {
initComponents();
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jButton1 = new javax.swing.JButton();
jPanel1 = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("jButton1");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 220, Short.MAX_VALUE)
);
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(739, Short.MAX_VALUE)
.addComponent(jButton1)
.addContainerGap())
.addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 51, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
JPanel jpPanelOut = new JPanel();
jpPanelOut.setBackground(new Color(255, 255, 255));
jpPanelOut.setLayout(new BoxLayout(jpPanelOut, BoxLayout.PAGE_AXIS));
JPanel jpPanel = new JPanel();
jpPanel.setPreferredSize(new Dimension(600, 26));
Font inFont = new Font("Serif", Font.PLAIN, 10);
JPanel jpPanel0 = new JPanel();
jpPanel0.setLayout(new BoxLayout(jpPanel0, BoxLayout.LINE_AXIS));
JLabel jlLabel0 = new JLabel("this is a new text");
jlLabel0.setBorder(BorderFactory.createEtchedBorder());
jlLabel0.setFont(inFont);
JSlider jslSlider0 = new JSlider(JSlider.HORIZONTAL, 0, 1000000000, 1);
jslSlider0.setFont(inFont);
JSpinner jspSpinner0 = new JSpinner(new SpinnerNumberModel(1, 0, 1000000000, 1));
jspSpinner0.setFont(inFont);
JTextField jtfTextField0 = new JTextField("1234567890abcdef_gpqyTÑ",48);
jtfTextField0.setFont(inFont);
JComboBox jcbComboBox0 = new JComboBox<>(new String[] {"Average"});
jcbComboBox0.setFont(inFont);
((JLabel)jcbComboBox0.getRenderer()).setHorizontalAlignment(JLabel.RIGHT);
jpPanel0.add(jlLabel0);
jpPanel0.add(jslSlider0);
jpPanel0.add(jspSpinner0);
jpPanel0.add(jtfTextField0);
jpPanel0.add(jcbComboBox0);
inFont = new Font("Serif", Font.PLAIN, 10);
JPanel jpPanel1 = new JPanel();
jpPanel1.setLayout(new BoxLayout(jpPanel1, BoxLayout.LINE_AXIS));
JLabel jlLabel1 = new JLabel("this is a new text");
jlLabel1.setBorder(BorderFactory.createEtchedBorder());
jlLabel1.setFont(inFont);
JSlider jslSlider1 = new JSlider(JSlider.HORIZONTAL, 0, 1000000000, 1);
jslSlider1.setFont(inFont);
JSpinner jspSpinner1 = new JSpinner(new SpinnerNumberModel(1, 0, 1000000000, 1));
jspSpinner1.setFont(inFont);
JTextField jtfTextField1 = new JTextField("1234567890abcdef_gpqyTÑ",48);
jtfTextField1.setFont(inFont);
JComboBox jcbComboBox1 = new JComboBox<>(new String[] {"Average"});
jcbComboBox1.setFont(inFont);
((JLabel)jcbComboBox1.getRenderer()).setHorizontalAlignment(JLabel.RIGHT);
jpPanel1.add(jlLabel1);
jpPanel1.add(jslSlider1);
jpPanel1.add(jspSpinner1);
jpPanel1.add(jtfTextField1);
jpPanel1.add(jcbComboBox1);
System.out.println("Height:"
+ " jtfTextField:" + jtfTextField1.getPreferredSize().getHeight() + ","
+ jtfTextField1.getMinimumSize().getHeight()
+ " jlLabel:" + jlLabel1.getPreferredSize().getHeight() + ","
+ jlLabel1.getMinimumSize().getHeight()
+ " jcbComboBox:" + jcbComboBox1.getPreferredSize().getHeight() + ","
+ jcbComboBox1.getMinimumSize().getHeight()
+ " jslSlider:" + jslSlider1.getPreferredSize().getHeight() + ","
+ jslSlider1.getMinimumSize().getHeight()
+ " jspSpinner:" + jspSpinner1.getPreferredSize().getHeight() + ","
+ jspSpinner1.getMinimumSize().getHeight()
);
jpPanelOut.add(jpPanel);
jpPanelOut.add(jpPanel0);
jpPanelOut.add(jpPanel1);
jPanel1.removeAll();
jPanel1.setLayout(new GridLayout(1, 1));
jPanel1.add(jpPanelOut);
}
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NewJFrame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;
// End of variables declaration
}
答案 0 :(得分:1)
我能够通过简化actionListener代码来更轻松地演示导致问题的组件,从而创建更好的SSCCE。 SSCCE应该只包含证明问题的相关代码。
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
JPanel jpPanelOut = new JPanel();
jpPanelOut.setBackground(new Color(255, 255, 255));
jpPanelOut.setLayout(new BoxLayout(jpPanelOut, BoxLayout.PAGE_AXIS));
JPanel jpPanel0 = new JPanel();
JComboBox jcbComboBox0 = new JComboBox<>(new String[] {"Average"});
jpPanel0.add(jcbComboBox0);
JPanel jpPanel1 = new JPanel();
JComboBox jcbComboBox1 = new JComboBox<>(new String[] {"Average"});
jpPanel1.add(jcbComboBox1);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
System.out.println("Height:"
+ " jcbComboBox:" + jcbComboBox1.getPreferredSize().getHeight() + ","
);
}
});
jpPanelOut.add(jpPanel0);
jpPanelOut.add(jpPanel1);
jPanel1.removeAll();
jPanel1.setLayout(new GridLayout(1, 1));
jPanel1.add(jpPanelOut);
}
所以基本上问题是System.out.println(...)在单独的Thread上执行。应该在Event Dispatch Thread上执行对Swing组件的所有更新。因此,组合框上的getPreferredSize()
方法导致EDT之外的组合框发生变化,这在某种程度上导致了问题。
一种解决方案是将代码包装在SwingUtilities.invokeLater中。另一种解决方案是将System.out.println(...)语句移动到方法的末尾。这两种解决方案都允许在打印高度之前在EDT上正确实现组合框。
答案 1 :(得分:0)
也许这个问题只发生在Nimbus(Synth)LookAndFeel
:
<强> SynthArrowButtonUI 强>
public Dimension getPreferredSize(JComponent c) { SynthContext context = getContext(c); Dimension dim = null; if (context.getComponent().getName() == "ScrollBar.button") { //... } if (dim == null) { // For all other cases (including Spinner, ComboBox), we will // fall back on the single ArrowButton.size value to create // a square return value int size = context.getStyle().getInt(context, "ArrowButton.size", 16); dim = new Dimension(size, size); } //...
<强> NimbusComboBoxSizeTest 强>
import java.awt.*;
import javax.swing.*;
public class NimbusComboBoxSizeTest {
public JComponent makeUI() {
String[] model = {"Average"};
JPanel p0 = new JPanel();
JComboBox<String> combo0 = new JComboBox<>(model);
p0.add(combo0);
JPanel p1 = new JPanel();
JComboBox<String> combo1 = new JComboBox<>(model);
p1.add(combo1);
Box box = Box.createVerticalBox();
box.add(p0);
box.add(p1);
EventQueue.invokeLater(() -> System.out.println("combo0: " + combo0.getPreferredSize()));
System.out.println("combo1: " + combo1.getPreferredSize());
JPanel p = new JPanel(new BorderLayout());
p.add(box, BorderLayout.NORTH);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
try {
for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(laf.getName())) {
UIManager.setLookAndFeel(laf.getClassName());
UIDefaults d = UIManager.getLookAndFeelDefaults();
System.out.println("ArrowButton.size: " + d.getInt("ArrowButton.size"));
System.out.println("ComboBox.arrowButton.size: " + d.getInt("ComboBox:\"ComboBox.arrowButton\".size"));
d.put("ArrowButton.size", 19);
//or: d.put("ComboBox:\"ComboBox.arrowButton\".size", 16);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new NimbusComboBoxSizeTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
ArrowButton.size: 16
ComboBox.arrowButton.size: 19
combo1: java.awt.Dimension[width=74,height=26]
combo0: java.awt.Dimension[width=77,height=26]