3

当我将 Swing 组件(如 JButton)添加到 JPanel 时,它会以其“首选大小”呈现。

但是,首选尺寸实际上比绘制的按钮大。它周围似乎有一个看不见的边框。

这是我的测试面板的简单框架:

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

TestPanel pnl = new TestPanel();
frame.getContentPane().add(pnl);

frame.pack();
frame.setVisible(true);

这是我的测试面板...

public class TestPanel extends JPanel {

    JButton btn1 = new JButton("Test1");
    JButton btn2 = new JButton("Test2");

    public TestPanel() {
        this.add(btn1);
        this.add(btn2);
    }

    public void paint(Graphics g) {
        super.paint(g);

        g.setColor(Color.RED);
        Dimension dim = btn1.getPreferredSize();
        g.drawRect(btn1.getX(), btn1.getY(), (int)(dim.getWidth()), (int)(dim.getHeight()));
    }

}

请注意,我在 RED 中绘制了 btn1 的“PreferredSize”,以证明preferredSize 实际上比按钮本身大。

在此处输入图像描述

我的问题是,如何确定绘制按钮的宽度和高度,而不是 JButton 的preferredSize?

非常感谢任何帮助,谢谢!

更新

因为我实际上需要它来为所有 Swing 组件工作,所以这是一个包含更多组件的屏幕截图。

不幸的是,我需要弄清楚这一点,确定可见小部件的“真实”大小对我的应用程序至关重要。

在此处输入图像描述

4

2 回答 2

3

我不认为这是特别的或实际上可以实现的。

问题是,按钮正在使用“未绘制”区域来绘制其他元素,例如焦点突出显示。

你可以试试看AbstractButton#set/getMargin

于 2013-03-19T00:40:42.423 回答
3

如果没有更好的结果,请注意作者“建议您将组件放在 a 中并在 .上JPanel设置边框JPanel。”

附录:根据您在下面的评论,很明显您的问题不是关于渲染边界,而是关于建立组件的边界。您认为未使用的空间实际上由 UI 代表保留用于任意数量的用途,例如选择突出显示或美学连贯性。您可以通过在此处此处的示例中选择不同的外观主题来了解其变化方式。

使用getbounds()

图片

使用setBorder()

图片

import component.Laf;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 * @see https://stackoverflow.com/a/15490187/230513
 */
public class Test {

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new FlowLayout());
        // https://stackoverflow.com/a/11949899/230513
        f.add(Laf.createToolBar(f));
        f.add(decorate(new JButton("Test")));
        f.add(decorate(new JTextField("Test")));
        f.add(decorate(new JTextArea(3, 8)));
        f.add(decorate(new JCheckBox("Test")));
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private JPanel decorate(final JComponent c) {
        JPanel p = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Rectangle r = c.getBounds();
                g.setColor(Color.red);
                // NB pen hangs down and to the right
                g.drawRect(r.x - 1, r.y - 1, r.width + 1, r.height + 1);
            }
        };
        p.add(c);
        return p;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test().display();
            }
        });
    }
}
于 2013-03-19T01:51:56.980 回答