Java 如何在自定义控件中实现类似JLabel的大小管理?

Java 如何在自定义控件中实现类似JLabel的大小管理?,java,swing,jcomponent,Java,Swing,Jcomponent,在下面的代码中,JFrame仅在BorderLayout的中心包含JLabel package test.swing; import java.awt.BorderLayout; import javax.swing.JFrame; import javax.swing.JLabel; public class Try_JLabel_01 { public static void main(String[] arg) { JFrame frame = new J

在下面的代码中,
JFrame
仅在
BorderLayout
的中心包含
JLabel

package test.swing;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Try_JLabel_01 {

    public static void main(String[] arg) {

        JFrame frame = new JFrame() {

            JLabel label = new JLabel("label");

            {
                setLayout(new BorderLayout());
                add(label, BorderLayout.CENTER);
            }

        };

        frame.pack();
        //frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);


    }

}
如果运行,此程序将显示窗口,该窗口正好适合控件大小

同时,如果定义自定义控件,则默认窗口的大小为零:

public class Try_JLabel_02 {

    public static void main(String[] arg) {

        JFrame frame = new JFrame() {

            //JLabel label = new JLabel("label");
            JComponent label = new JComponent() {

                @Override
                protected void paintComponent(Graphics g) {
                    super.paintComponent(g);

                    g.setColor(Color.RED);
                    g.fillOval(0, 0, 200, 100);
                }
            };


            {
                setLayout(new BorderLayout());
                add(label, BorderLayout.CENTER);
            }

        };

        frame.pack();
        //frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);


    }

}
如何正确扩展JComponent,使其行为类似于JLabel,例如,其默认大小为200x100

另外,我不想扩展
JLabel
。我想学习
JLabel
如何扩展
jconomponent

我看到了
JLabel
的源代码,但我不明白,它们是如何控制大小的。事实上,我没有看到任何大小控制代码在那里

更新

我发现,如果我不重写,但如果我设置大小,则可以解决此任务:

//JLabel label = new JLabel("label");
        JComponent label = new JComponent() {

            {
                setMinimumSize(new Dimension(200, 100));
                setPreferredSize(new Dimension(200, 100));
            }

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);

                g.setColor(Color.RED);
                g.fillOval(0, 0, 200, 100);
            }
        };
但这只有在我自己知道的情况下才有效。就字体而言,如果没有
图形
对象,我就无法知道大小


因此,如何确定字体的大小?

之所以
JLabel
(以及其他组件)可以生成您看到的结果,是因为它们向父容器提供有用的大小提示,父容器的布局管理器使用父容器来决定如何最好地布局子组件

pack
使用所有这些信息来确定调用窗口时窗口的最佳大小

默认情况下,
JComponent
的首选大小为0x0,这对您没有多大帮助。首先重写组件
getPreferredSize
方法并返回,类似于
newdimension(200200)


现在,请记住,每个布局管理器使用不同的信息来做出决策,您可能还需要查看
getMinimumSize
getMaximumSize
以及
JLabel
(和其他组件)的原因可以生成您看到的结果是因为它们向父容器提供有用的大小提示,它的布局管理器使用父容器来决定如何最好地布局子组件

pack
使用所有这些信息来确定调用窗口时窗口的最佳大小

默认情况下,
JComponent
的首选大小为0x0,这对您没有多大帮助。首先重写组件
getPreferredSize
方法并返回,类似于
newdimension(200200)

现在,请记住,每个布局管理器使用不同的信息来做出决策,您可能还需要查看
getMinimumSize
getMaximumSize

我不想扩展
JLabel

如果不想扩展
JLabel
,可以使用
EmptyBorder
填充封闭的
容器
,如图所示

我不想扩展
JLabel


如果您不想扩展
JLabel
,您可以使用
EmptyBorder

填充封闭的
容器,如图所示。如果您决定扩展
JLabel
并覆盖
getPreferredSize
,请注意这一点。我看不到,
getPreferredSize()
方法在
JLabel
中被重写:@SuzanCioc很可能是UI委托直接设置了首选大小。在您的案例中,您没有UI委托,因此,您需要提供结果yourself@MadProgrammer是正确的,例如。如果您决定扩展
JLabel
并重写
getPreferredSize
,请注意这一点。我看不出,这是
getPreferredSize()
方法在
JLabel
中被重写:@SuzanCioc很可能是UI委托直接设置了首选大小。在您的案例中,您没有UI委托,因此,您需要提供结果yourself@MadProgrammer是正确的。你到底想实现什么?为什么要扩展JComponent?我想学习编写自定义控件,我想学习如何在
JLabel
中实现所描述的行为。然后阅读源代码。。。JLabel的所有大小计算和布局(图标/文本)都在其ui Delegate中完成。您希望实现什么?为什么要扩展JComponent?我想学习编写自定义控件,我想学习如何在
JLabel
中实现所描述的行为。然后阅读源代码。。。JLabel的所有大小计算和布局(图标/文本)都在其ui中完成delegate@SuzanCioc:否,标签的UI委托使用所选字体的几何图形,例如。@SuzanCioc:否,标签的UI委托使用所选字体的几何图形,例如。