【问题标题】:How to indeed center object in a JFrame?如何在 JFrame 中真正居中对象?
【发布时间】:2019-05-26 12:25:08
【问题描述】:

我有一个扩展 Jframe 的类,我使用 setLocationRelativeTo(null); 将其居中。 layoutManager 也是null

我的 JFrame:

mport com.sxf.protocol.chat.util.window.AbstractField;

import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;

public class Field extends AbstractField {

    private Container cp;

    public Field() {
        super("Test");

        buildWindow();
    }

    private void buildWindow() {

        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setPreferredSize(new Dimension(frameWidth, frameHeight));
        setResizable(false);

        cp = getContentPane();
        cp.setLayout(null);

        initComponents();

        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void initComponents() {
        JLabel label = new JLabel("Test", SwingConstants.CENTER);
        JLabel border = new JLabel("");
        label.setSize(200, 30);
        label.setLocation((frameWidth - label.getWidth()) / 2, (frameHeight - label.getHeight()) / 2);
        border.setBounds(frameWidth / 2, 0, frameWidth / 2, frameHeight);
        label.setBorder(new LineBorder(new Color(0, 0, 0)));
        border.setBorder(new LineBorder(new Color(255, 0, 0)));

        cp.add(label);
        cp.add(border);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Field();
            }
        });
    }
}

我添加到边框以查看它是否正确居中。

AbstractField(里面只有一些计算):

public abstract class AbstractField extends JFrame {

    private final static Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    private static final Dimension frameSize = new Dimension(screenSize.width / 4, screenSize.height / 4);
    protected static final int frameWidth;
    protected static final int frameHeight;
    protected static final int x;
    protected static final int y;

    static {
        frameWidth = frameSize.width;
        frameHeight = frameSize.height;
        x = (screenSize.width - frameWidth) / 2;
        y = (screenSize.height - frameHeight) / 2;
    }

    public AbstractField(String title) {
        super(title);
    }
}

但是当我尝试将组件居中时,例如JLabel,做
(frame.getWidth - component.getWidth) / 2,高度也一样,它实际上不是居中而是向右一点。

这是由于 jframe 的原生移动开头,我可以计算吗?

【问题讨论】:

  • 1) AbstractField extends JFrame 请给类起描述性、逻辑性和合理性的名称。例如,这个类可能是抽象的,但绝不是像JTextField 这样的字段。 AbstractFrame 会更有意义。 2) private final static.. 使用static 修饰符通常会隐藏更大的问题,同时也会产生自己的问题。删除static 的所有实例并弄清楚如何使用字段的非静态实例。 3)..frameSize = new Dimension(screenSize.width / 4, screenSize.height / 4);这充其量只是猜测框架的大小。相反..
  • .. pack() 确保它是显示内容所需的(最小)尺寸。 4) x = (screenSize.width - frameWidth) / 2; (a) xy 不仅已经为 mot 组件和窗口定义,而且它们还用于其他用途。给你的属性起不同的名字。 (b) 要在屏幕上居中显示窗口,请在添加所有组件后调用window.setLocationRelativeTo(null;)。 5) 不要无故延长框架。这是什么原因? 6) cp.setLayout(null); Java GUI 必须在不同的操作系统上工作,..
  • .. 屏幕尺寸、屏幕分辨率等在不同区域使用不同的 PLAF。因此,它们不利于像素完美布局。而是使用布局管理器,或combinations of them 以及white space 的布局填充和边框。 7) label.setLocation((frameWidth - label.getWidth()) / 2, (frameHeight - label.getHeight()) / 2); 这不考虑框架装饰或“镀铬”。这就是为什么我们通常会在添加到框架中的 JPanel 中重新定位所有内容。
  • 8) 以最小尺寸提供 ASCII 艺术或 GUI 的 预期 布局的简单绘图,如果可调整大小,则具有更大的宽度和高度 - 以显示额外的应该使用空间。 9)如需更好的帮助,请edit添加minimal reproducible exampleShort, Self Contained, Correct Example
  • 这更像是一个小型私人项目,但我会尝试转换您的提示。

标签: java swing jframe window layout-manager


【解决方案1】:

如何在 JFrame 中真正居中?

确实将其作为唯一的组件添加到带有GridBagLayoutJPanel。将该面板用作内容窗格。

例子:

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

public class CenteredLabel {

    private JComponent ui = null;

    CenteredLabel() {
        initUI();
    }

    public final void initUI() {
        if (ui!=null) return;

        ui = new JPanel(new GridBagLayout());
        ui.setBorder(new EmptyBorder(4,4,4,4));

        JLabel centeredLabel = new JLabel("Test");
        centeredLabel.setBorder(new LineBorder(Color.RED));
        ui.add(centeredLabel);
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception useDefault) {
            }
            CenteredLabel o = new CenteredLabel();

            JFrame f = new JFrame(o.getClass().getSimpleName());
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setLocationByPlatform(true);

            f.setContentPane(o.getUI());
            f.pack();
            f.setMinimumSize(f.getSize());

            f.setVisible(true);
        };
        SwingUtilities.invokeLater(r);
    }
}

【讨论】:

  • 感谢您的快速回复。我不喜欢使用这些布局,而且我有很多项目。我发现原生缩进是 10 像素,所以在计算帧的中间后我必须减去 10:D
  • "native indent is 10 pixel" 在哪个操作系统上?就是这样。框架装饰改变。因此,虽然您可能会在一台机器、操作系统或 PLAF 上“正确”,但它会在下一台机器上发生变化。 “我不喜欢使用这些布局” 如果您仅仅因为不“喜欢”布局而拒绝使用正确的工具来完成这项工作,这将更加困难 - 而且会可能会失败。
  • @HerbertGrönemeyer “我不喜欢使用这些布局”不幸的是,这是你应该做的。使用布局管理器并避免使用空布局管理器。
猜你喜欢
  • 2016-09-28
  • 2012-03-28
  • 2011-11-05
  • 2013-10-22
  • 2014-05-22
  • 2015-03-23
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多