简体   繁体   English

Java Swing如何修复JLabel大小

[英]Java Swing how to fix JLabel size

I've tried my best to fix a JLabel's size, but it keeps changing and that causes other items in the GUI to move around. 我已经尽力修复了JLabel的大小,但是它一直在变化,这会导致GUI中的其他项目移动。

I have specified both the sizing and the spacing of components. 我已经指定了组件的大小和间距。 According to GridBagLayout's documentation , ipadx and ipady "Specifies the internal padding: how much to add to the size of the component." 根据GridBagLayout的文档ipadxipady “指定内部填充: 添加多少组件大小。” According to this post, setMinimumSize and setMaximumSize allows you to the set the actual size of the component. 根据这篇文章, setMinimumSizesetMaximumSize允许您设置组件的实际大小。 Since I have fixed both the size and the spacing, how is it possible that the components keep jumping around whenever text appears in the JLabel? 既然我已经固定了大小和间距,那么当文本出现在JLabel中时,组件怎么可能不断跳来跳去?

I was able to solve this in practice by adding a space into the empty text, but this keeps bugging me. 实际上,我可以通过在空白文本中添加一个空格来解决此问题,但这一直困扰着我。 What is it that I don't understand about this? 我对此不了解是什么?

Here is a SSCCE demonstrating the problem. 这是SSCCE演示的问题。 It has elements arranged in a GridBagLayout and changing the contents of one JLabel in one cell causes all items to move. 它具有布置在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("");
    }
}
}

One way to solve the problem. 解决问题的一种方法。 Change: 更改:

    JLabel sitePass = new JLabel("");

To: 至:

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

Explanation: A JTextField has a default size determined by the number of columns, combined with the font and font size. 说明: JTextField的默认大小由列数以及字体和字体大小决定。 The two statements following ensure it has the look of a JLabel . 下面的两个语句确保它具有JLabel的外观。

An improvement would be to also make the text field act like a label, which might be something along the lines of: 一种改进是还可以使文本字段像标签一样起作用 ,可能类似于以下内容:

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

Swing use the preferredSize for some Layout. 对于某些Layout,Swing使用preferredSize Setting it will correct your label. 设置它会更正您的标签。

I am used to fixe a JComponent by setting minimum , maximum and preferred size just to be sure ;) 我习惯于通过设置minimummaximumpreferred大小来修复JComponent ,以确保;)

PS : I will try to add more information about how to use it. PS:我将尝试添加有关如何使用它的更多信息。

There is another way to use a dummy whitespace like JComboBox . 还有另一种使用伪空白的方式,例如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);
    });
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM