java - Swing(JComboBox)错误?打印尺寸

标签 java swing printing jcombobox

我正在检查 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);

但是尺寸改变了!!!

enter image description here

请看:

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                   
}

最佳答案

我能够通过简化 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(...) 在单独的线程上执行。 Swing 组件的所有更新都应该在事件调度线程上执行。因此,组合框上的 getPreferredSize() 方法导致 EDT 之外的组合框发生更改,这在某种程度上导致了问题。

一种解决方案是将代码包装在 SwingUtilities.invokeLater 中。另一个解决方案是将 System.out.println(...) 语句移至方法的末尾。这两种解决方案都将允许在打印高度之前在 EDT 上正确实现组合框。

关于java - Swing(JComboBox)错误?打印尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36274053/

相关文章:

java - 通过php运行jar

java - jComboBox 与隐藏数据 java

javascript - 如何在 MathJax 中的 "Processing Math"达到 100% 时触发 javascript 函数

java - PrintServiceLookup.lookupDefaultPrintService() 始终返回 null

java - 为什么我的 Controller setter 在我的 PrimeFaces 项目中不起作用?

java - 滚动时保持 ImageView 的最终 View

Java:多个 JScrollPanes 在 1 个公共(public)组件上显示 View

java - 如何创建一个内部包含多个图像的矩形?

css - 在谷歌浏览器上打印时删除空白页

java - Morphia:使用 Morphia 过滤 ArrayList 中的元素