【问题标题】:Java Swing how to fix JLabel sizeJava Swing如何修复JLabel大小
【发布时间】:2017-06-04 00:05:00
【问题描述】:

我已尽力修复 JLabel 的大小,但它一直在变化,这会导致 GUI 中的其他项目四处移动。

我已经指定了组件的大小和间距。根据 GridBagLayout 的documentationipadxipady “指定内部填充:要添加多少到组件的大小。” 根据@987654322 @post、setMinimumSizesetMaximumSize 允许您设置组件的实际大小。既然我已经固定了大小和间距,那么每当文本出现在 JLabel 中时,组件怎么可能一直跳来跳去?

在实践中我可以通过在空文本中添加一个空格来解决这个问题,但这一直困扰着我。这有什么我不明白的?

这是一个演示问题的 SSCCE。它具有排列在 GridBagLayout 中的元素,并且在一个单元格中更改一个 JLabel 的内容会导致所有项目移动。

import javax.swing.*;
import java.awt.*;
import java.io.*;

public class F {
public static void main(String[] args) throws IOException, InterruptedException {
    JFrame frame = new JFrame();

    JPanel mainView = new JPanel();
    mainView.setPreferredSize(new Dimension(300, 300));
    mainView.setLayout(new GridBagLayout());

    JPanel contents = new JPanel(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.insets = new Insets(1,3,3,3);
    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.ipady = 2;
    gbc.anchor = GridBagConstraints.EAST;

    JLabel text1 = new JLabel("Some text: ");
    contents.add(text1, gbc);
    gbc.gridy++;
    JLabel text2 = new JLabel("More text: ");
    contents.add(text2, gbc);
    gbc.gridy++;
    JLabel text3 = new JLabel("Third line: ");
    contents.add(text3, gbc);
    gbc.gridx++;
    gbc.gridy = 0;

    JTextField textField1 = new JTextField(10);
    contents.add(textField1, gbc);
    gbc.gridx++;
    gbc.gridy++;
    gbc.gridx--;

    JTextField textField2 = new JTextField(10);
    contents.add(textField2, gbc);
    gbc.gridy++;

    JLabel sitePass = new JLabel("");
    sitePass.setMaximumSize(new Dimension(100, 15));
    sitePass.setMinimumSize(new Dimension(100, 15));
    //sitePass.setPreferredSize(new Dimension(100, 15)); // <-- this line fixes the problem
    contents.add(sitePass, gbc);

    mainView.add(contents);

    frame.add(mainView);
    frame.setSize(400, 400);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    while (true) {
        Thread.sleep(1000);
        sitePass.setText("Pushup time");
        Thread.sleep(1000);
        sitePass.setText("");
    }
}
}

【问题讨论】:

标签: java swing user-interface layout-manager gridbaglayout


【解决方案1】:

解决问题的一种方法。变化:

    JLabel sitePass = new JLabel("");

收件人:

    JTextField sitePass = new JTextField("", 12);
    sitePass.setOpaque(false);
    sitePass.setBorder(null);

解释:JTextField 的默认大小由列数以及字体和字号决定。下面的两个语句确保它具有JLabel 的外观。

一个改进是让文本字段act像一个标签,这可能是这样的:

    sitePass.setEditable(false);
    sitePass.setFocusable(false);

【讨论】:

    【解决方案2】:

    还有另一种使用虚拟空格的方法,例如 JComboBox

    //javax.swing.plaf.basic.BasicComboBoxUI#getDefaultSize()
    /**
     * Return the default size of an empty display area of the combo box using
     * the current renderer and font.
     *
     * @return the size of an empty display area
     * @see #getDisplaySize
     */
    protected Dimension getDefaultSize() {
      // Calculates the height and width using the default text renderer
      Dimension d = getSizeForComponent(getDefaultListCellRenderer()
        .getListCellRendererComponent(listBox, " ", -1, false, false));
      return new Dimension(d.width, d.height);
    }
    
    import java.awt.*;
    import java.util.Objects;
    import javax.swing.*;
    
    public class DummyWhiteSpaceTest {
      public JComponent makeUI(String dummy) {
        JPanel mainView = new JPanel(new GridBagLayout());
    
        JPanel contents = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(1, 3, 3, 3);
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.ipady = 2;
        gbc.anchor = GridBagConstraints.EAST;
    
        /* Text labels. */
        JLabel text1 = new JLabel("Some text: ");
        contents.add(text1, gbc);
        gbc.gridy++;
        JLabel text2 = new JLabel("More text: ");
        contents.add(text2, gbc);
        gbc.gridy++;
        JLabel text3 = new JLabel("Third line: ");
        contents.add(text3, gbc);
        gbc.gridx++;
        gbc.gridy = 0;
    
        JTextField textField1 = new JTextField(10);
        contents.add(textField1, gbc);
        gbc.gridx++;
        gbc.gridy++;
        gbc.gridx--;
    
        JTextField textField2 = new JTextField(10);
        contents.add(textField2, gbc);
        gbc.gridy++;
    
        //@see javax.swing.plaf.basic.BasicComboBoxUI#getDefaultSize()
        //JLabel sitePass = new JLabel(" ");
        JLabel sitePass = new JLabel(dummy);
        sitePass.setFont(new Font("Monospaced", Font.PLAIN, 14));
        contents.add(sitePass, gbc);
    
        mainView.add(contents);
    
        (new Timer(1000, e -> {
          if (Objects.equals(sitePass.getText(), dummy)) {
            sitePass.setText("Pushup time");
          } else {
            sitePass.setText(dummy);
          }
        })).start();
    
        return mainView;
      }
      public static void main(String... args) {
        EventQueue.invokeLater(() -> {
          DummyWhiteSpaceTest test = new DummyWhiteSpaceTest();
          JPanel p = new JPanel(new GridLayout(1, 2));
          p.add(test.makeUI(""));
          p.add(test.makeUI(" "));
          JFrame f = new JFrame();
          f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
          f.getContentPane().add(p);
          f.setSize(640, 240);
          f.setLocationRelativeTo(null);
          f.setVisible(true);
        });
      }
    }
    

    【讨论】:

      【解决方案3】:

      Swing 使用preferredSize 进行一些布局。 设置它会更正您的标签。

      我习惯于通过设置minimummaximumpreferred 的大小来修复JComponent 以确保确定;)

      PS:我会尝试添加更多关于如何使用它的信息。

      【讨论】:

      • @MadProgrammer,谢谢。那么在那个线程中有优点和缺点。将仔细研究每一个。但接受的答案建议使用外部 API (JGoodies) 来填补提供的布局中的空白......
      • @MadProgrammer,您可以在 Oracle 的 demo 中看到这些属性的大量使用。
      • 教程充满了在现实生活中值得怀疑的“好”想法。在具有不同分辨率和字体设置的不同系统上运行代码,看看它需要多长时间才能崩溃
      • @mad 谢谢你的信息。
      猜你喜欢
      • 2021-03-08
      • 1970-01-01
      • 2017-05-16
      • 2011-11-15
      • 2014-05-08
      • 1970-01-01
      • 2021-02-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多