如何从添加到 JLabel 的 JComponent 返回 XxxSize

发布于 2024-12-22 03:07:37 字数 4306 浏览 2 评论 0原文

如何从添加到 JLabel

1st 的 JComponent 正确返回 XxxSize。图>> 让 LayoutManager 像 JPanel 一样工作,JLabel 返回 Size(0, 0)

在此处输入图像描述

第二。图>> 向 JLabel 添加了一些 PreferredSize

在此处输入图像描述

第三。图>> 根据添加到 JLabel 的 JComponent 计算出的 PreferredSize

在此处输入图像描述

第四。图>> 让 LayoutManager 工作将 JLabel 更改为 JPanel,现在 LayoutManager 可以正确计算 Dimension,无需使用任何 XxxSize

在此处输入图像描述

注意,这里使用了 Nimbus L&F,所有可访问的 L&F 都有相同的输出

import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.*;

public class NimbusBorderPainterDemo extends JFrame {

    private static final long serialVersionUID = 1L;
    private JFrame frame = new JFrame();
    private JPanel fatherPanel = new JPanel(), titlePanel = new JPanel();
    private JLabel buttonPanel = new JLabel();


    //figure  ---> 4th. switch JLabel with JPanel
    //private JPanel buttonPanel = new JPanel();
    private Queue<Icon> iconQueue = new LinkedList<Icon>();

    public NimbusBorderPainterDemo() {
        iconQueue.add(UIManager.getIcon("OptionPane.errorIcon"));
        iconQueue.add(UIManager.getIcon("OptionPane.informationIcon"));
        iconQueue.add(UIManager.getIcon("OptionPane.warningIcon"));
        JButton button0 = createButton();
        JButton button1 = createButton();
        JButton button2 = createButton();
        button2.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                System.exit(1);
            }
        });
        int gap = 5;
        buttonPanel.setLayout(new GridLayout(0, 3, gap, 0));
        buttonPanel.add(button0);
        buttonPanel.add(button1);
        buttonPanel.add(button2);

        // figure 1st. --->  without PreferredSize

        // figure 2nd. --->
        //buttonPanel.setPreferredSize(new Dimension(160, 30));

        // figure 3rd. --->
        /*Dimension dim = button0.getPreferredSize();
        int w = dim.width;
        int h = dim.height;
        w = (w + 5) * 3;
        h += 4;
        dim = new Dimension(w, h);
        buttonPanel.setPreferredSize(dim);*/

        titlePanel.setLayout(new BorderLayout());
        titlePanel.add(new JLabel(nextIcon()), BorderLayout.WEST);
        titlePanel.add(new JLabel("My Frame"), BorderLayout.CENTER);
        titlePanel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
        titlePanel.add(buttonPanel, BorderLayout.EAST);
        fatherPanel.setLayout(new BorderLayout());
        fatherPanel.add(titlePanel, BorderLayout.CENTER);
        frame.setUndecorated(true);
        frame.add(fatherPanel);
        frame.setLocation(50, 50);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.setVisible(true);
    }

    private JButton createButton() {
        JButton button = new JButton();
        button.setBorderPainted(false);
        button.setBorder(null);
        button.setFocusable(false);
        button.setMargin(new Insets(0, 0, 0, 0));
        button.setContentAreaFilled(false);
        button.setIcon(nextIcon());
        //button.setRolloverIcon(nextIcon());
        //button.setPressedIcon(nextIcon());
        //button.setDisabledIcon(nextIcon());
        nextIcon();
        return button;
    }

    private Icon nextIcon() {
        Icon icon = iconQueue.peek();
        iconQueue.add(iconQueue.remove());
        return icon;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch (Exception fail) {
                }
                UIManager.getLookAndFeelDefaults().put("nimbusFocus", Color.RED);
                NimbusBorderPainterDemo nimbusBorderPainterDemo = new NimbusBorderPainterDemo();
            }
        });
    }
}

how can I correctly returns XxxSize from JComponent(s) added to the JLabel

1st. figure >> lets LayoutManager works like as for JPanel, JLabel returns Size(0, 0)

enter image description here

2nd. figure >> added some PreferredSize to the JLabel

enter image description here

3rd. figure >> calculated PreferredSize from JComponent(s) added to the JLabel

enter image description here

4th. figure >> lets LayoutManager works changed JLabel to JPanel, now LayoutManager correctly calculated Dimension without using any XxxSize

enter image description here

notice sice there is used Nimbus L&F, same output is there for all accesible L&F

import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.*;

public class NimbusBorderPainterDemo extends JFrame {

    private static final long serialVersionUID = 1L;
    private JFrame frame = new JFrame();
    private JPanel fatherPanel = new JPanel(), titlePanel = new JPanel();
    private JLabel buttonPanel = new JLabel();


    //figure  ---> 4th. switch JLabel with JPanel
    //private JPanel buttonPanel = new JPanel();
    private Queue<Icon> iconQueue = new LinkedList<Icon>();

    public NimbusBorderPainterDemo() {
        iconQueue.add(UIManager.getIcon("OptionPane.errorIcon"));
        iconQueue.add(UIManager.getIcon("OptionPane.informationIcon"));
        iconQueue.add(UIManager.getIcon("OptionPane.warningIcon"));
        JButton button0 = createButton();
        JButton button1 = createButton();
        JButton button2 = createButton();
        button2.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                System.exit(1);
            }
        });
        int gap = 5;
        buttonPanel.setLayout(new GridLayout(0, 3, gap, 0));
        buttonPanel.add(button0);
        buttonPanel.add(button1);
        buttonPanel.add(button2);

        // figure 1st. --->  without PreferredSize

        // figure 2nd. --->
        //buttonPanel.setPreferredSize(new Dimension(160, 30));

        // figure 3rd. --->
        /*Dimension dim = button0.getPreferredSize();
        int w = dim.width;
        int h = dim.height;
        w = (w + 5) * 3;
        h += 4;
        dim = new Dimension(w, h);
        buttonPanel.setPreferredSize(dim);*/

        titlePanel.setLayout(new BorderLayout());
        titlePanel.add(new JLabel(nextIcon()), BorderLayout.WEST);
        titlePanel.add(new JLabel("My Frame"), BorderLayout.CENTER);
        titlePanel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
        titlePanel.add(buttonPanel, BorderLayout.EAST);
        fatherPanel.setLayout(new BorderLayout());
        fatherPanel.add(titlePanel, BorderLayout.CENTER);
        frame.setUndecorated(true);
        frame.add(fatherPanel);
        frame.setLocation(50, 50);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.setVisible(true);
    }

    private JButton createButton() {
        JButton button = new JButton();
        button.setBorderPainted(false);
        button.setBorder(null);
        button.setFocusable(false);
        button.setMargin(new Insets(0, 0, 0, 0));
        button.setContentAreaFilled(false);
        button.setIcon(nextIcon());
        //button.setRolloverIcon(nextIcon());
        //button.setPressedIcon(nextIcon());
        //button.setDisabledIcon(nextIcon());
        nextIcon();
        return button;
    }

    private Icon nextIcon() {
        Icon icon = iconQueue.peek();
        iconQueue.add(iconQueue.remove());
        return icon;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
                } catch (Exception fail) {
                }
                UIManager.getLookAndFeelDefaults().put("nimbusFocus", Color.RED);
                NimbusBorderPainterDemo nimbusBorderPainterDemo = new NimbusBorderPainterDemo();
            }
        });
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

只等公子 2024-12-29 03:07:37

默认的首选尺寸计算是使用布局管理器来确定组件的首选尺寸。这意味着布局管理器会迭代所有子组件以确定每个子组件的首选大小。对于打算用作容器的 JPanel,使用此计算。

但是,对于其他 Swing 组件,始终会重写 getPreferredSize() 方法以为给定组件提供合理的大小。

对于 JLabel,首选尺寸计算会考虑所使用的文本和图标。由于您没有提供首选大小为零。当然,如果您使用 setPreferredSize() 方法手动覆盖此计算,则组件将具有首选大小。

因此,即使 Swing 允许您向任何组件添加组件并使用布局管理器来布局子组件,这些子组件也不会用于首选大小计算。

这不仅仅是 Nimbus 的问题。

The default preferred size calculation is to use the layout manager to determine the preferred size of a component. This means the layout manager iterates through all the child components to determine the preferred size of each. For a JPanel, which is meant to be used as a Container this calculation is used.

However, for other Swing components, the getPreferredSize() method is always overridden to provide a reasonable size for the given component.

In the case of a JLabel, the preferred size calculation takes into account the text and the icon used. Since you didn't provide either the preferred size is zero. Of course if you manually override this calculation by using the setPreferredSize() method then the component will have a preferred size.

So even though Swing allows you to add components to any component and use a layout manager to layout the child components, these child components are not used in the preferred size calculation.

This is not just a Nimbus issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文