Java 改变 JPanel 的形状

标签 java swing jpanel shapes java-2d

我正在尝试做一些我认为相当容易但找不到直接答案的事情。基本上我想将 JPanel 的默认形状更改为圆形(或矩形以外的任何其他形状)。

最佳答案

您需要提供自己的自定义绘画例程。

您将遇到的另一个问题是让布局管理器使用它,但您可以提供自己的插图以在面板内提供一个可以安全使用的区域

您还需要使组件透明,以允许组件圆圈位置之外的区域透明。

查看

可能还需要操作Graphics上下文的剪切矩形。这是棘手且危险的,如果你能避免它,我会的。

已更新示例

enter image description here

public class CirclePaneTest {

    public static void main(String[] args) {
        new CirclePaneTest();
    }

    public CirclePaneTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setBackground(Color.RED);
            setLayout(new GridBagLayout());
            CirclePane circlePane = new CirclePane();
            JLabel label = new JLabel("This is a test");
            label.setHorizontalAlignment(JLabel.CENTER);
            label.setVerticalAlignment(JLabel.CENTER);
            // This is a test to show the usable bounds
            label.setBorder(new LineBorder(Color.RED));
            circlePane.setLayout(new BorderLayout());
            circlePane.add(label);
            add(circlePane);
        }

    }

    public class CirclePane extends JPanel {

        public CirclePane() {
            setOpaque(false);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected int getRadius() {
            // Determines the radius based on the smaller of the width
            // or height, so we stay symmetrical
            return Math.min(getWidth(), getHeight());
        }

        @Override
        public Insets getInsets() {
            int radius = getRadius();
            int xOffset = (getWidth() - radius) / 2;
            int yOffset = (getHeight() - radius) / 2;
            // These are magic numbers, you might like to calculate
            // your own values based on your needs
            Insets insets = new Insets(
                    radius / 6,
                    radius / 6,
                    radius / 6,
                    radius / 6);
            return insets;
        }

        @Override
        protected void paintComponent(Graphics g) {

            super.paintComponent(g);

            int radius = getRadius();
            int xOffset = (getWidth() - radius) / 2;
            int yOffset = (getHeight() - radius) / 2;

            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(getBackground());
            g2d.fillOval(xOffset, yOffset, radius, radius);
            g2d.setColor(Color.GRAY);
            g2d.drawOval(xOffset, yOffset, radius, radius);
//            This is test code to test the insets/usable area bounds...
//            Insets insets = getInsets();
//            g2d.drawRect(xOffset + insets.left, 
//                    yOffset + insets.top,
//                    (xOffset + radius) - (insets.right + insets.left), 
//                    (yOffset + radius) - (insets.bottom + insets.top));
            g2d.dispose();

        }
    }
}

关于Java 改变 JPanel 的形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14675766/

相关文章:

java - 如何在JFrame中设置glasspane的位置?

java - JTabbedPane 选项卡

java - 将参数传递给 jpa 转换器

c# - 无法对非静态方法进行静态引用

java - 如何将第三方Java库编译成我可以使用的jar文件?

java - TestNG @BeforeClass 初始化代码在 Test 之前未运行

JAVA表单检测变化

java - 在 netbeans 中构建后,Jar 文件无法正常运行

java - 如果 setLayout 为 null,面板不显示任何内容

java - JTable 在初始化时不显示