【问题标题】:How to custom the shape of a JPanel or JLabel?如何自定义 JPanel 或 JLabel 的形状?
【发布时间】:2013-04-03 09:28:42
【问题描述】:

我在 JLabel 中显示图像。我想以圆形显示该图像,即我希望 JLabel 的形状为圆形,默认为矩形。如何设置 JPanel 或 JLabel 的形状? setUndecorated() 和 setShape() 只为 Frame 定义?有没有可能改变 JPanel 和 JLabel 等其他组件的形状??

【问题讨论】:

    标签: java image swing jpanel jlabel


    【解决方案1】:

    组件始终是矩形的,但是,您可以使用自定义绘画和透明度使组件显示为非矩形

    看看Perfoming Custom Painting2D Graphics

    更新示例

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.RenderingHints;
    import java.awt.geom.Path2D;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class FunkyShapedComponent {
    
        public static void main(String[] args) {
            new FunkyShapedComponent();
        }
    
        public FunkyShapedComponent() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JPanel testPane = new JPanel();
                    testPane.setBackground(Color.RED);
                    testPane.setLayout(new GridBagLayout());
                    testPane.add(new FunkyPane());
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(testPane);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class FunkyPane extends JPanel {
    
            public FunkyPane() {
                setLayout(new GridBagLayout());
                add(new JLabel("This is a simple test"));
                setOpaque(false);
            }
    
            @Override
            public Insets getInsets() {
                return new Insets(10, 10, 10, 10);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
    
                int width = getWidth() - 1;
                int height = getHeight() - 1;
    
                int radius = Math.min(width, height) / 10;
    
                Path2D p = new Path2D.Float();
                p.moveTo(0, radius / 2);
                p.curveTo(0, 0, 0, 0, radius / 2, 0);
                p.curveTo(width / 4, radius, width / 4, radius, (width / 2) - radius, radius / 2);
                p.curveTo(width / 2, 0, width / 2, 0, (width / 2) + radius, radius / 2);
                p.curveTo(width - (width / 4), radius, width - (width / 4), radius, width - (radius / 2), 0);
                p.curveTo(width, 0, width, 0, width, radius / 2);
    
                p.curveTo(width - radius, height / 4, width - radius, height / 4, width - (radius / 2), (height / 2) - radius);
                p.curveTo(width, height / 2, width, height / 2, width - (radius / 2), (height / 2) + radius);
                p.curveTo(width - radius, height - (height / 4), width - radius, height - (height / 4), width, height - (radius / 2));
                p.curveTo(width, height, width, height, width - (radius / 2), height);
    
                p.curveTo(width - (width / 4), height - radius, width - (width / 4), height - radius, (width / 2) + radius, height - (radius / 2));
                p.curveTo(width / 2, height, width / 2, height, (width / 2) - radius, height - (radius / 2));
                p.curveTo((width / 4), height - radius, (width / 4), height - radius, (radius / 2), height);
                p.curveTo(0, height, 0, height, 0, height - (radius / 2));
    
                p.curveTo(radius, height - (height / 4), radius, height - (height / 4), (radius / 2), (height / 2) + radius);
                p.curveTo(0, height / 2, 0, height / 2, (radius / 2), (height / 2) - radius);
                p.curveTo(radius, (height / 4), radius, (height / 4), 0, (radius / 2));
    
                p.closePath();
    
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
                g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
                g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
                g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
                g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
                g2d.setColor(getBackground());
                g2d.fill(p);
                g2d.dispose();
    
            }
        }
    }
    

    【讨论】:

    • 你能告诉我如何以圆形显示矩形 JPanel 吗?
    • 您将如何为 JLabel 构建它,因为目前您的类扩展了 JPanel,然后更改了标签。如果您希望这只是用于 JLabel sot,您可以以您构建的任何形式创建并实例化它,然后相应地设置其属性。
    • 就个人而言,我不会。问题是(以及我这样做的原因)是 JLabel 的 paintComponen 实际上呈现文本,这意味着如果您在调用 super.paintComponet 后尝试在标签上绘画,您将在文本上绘画
    【解决方案2】:

    我认为你想要的是显示透明区域。 您不需要设置形状,例如,您可以使用:

    setOpaque(false);
    

    对于有边框的组件,可以通过以下方式隐藏:

    setBorder(null);
    

    对于按钮,你可以使用

    setBorderPainted(false);
    setContentAreaFilled(false);
    

    【讨论】:

    • 你能告诉我如何以圆形显示矩形 JPanel 吗?
    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-11
    • 2017-01-10
    • 1970-01-01
    • 2018-10-10
    相关资源
    最近更新 更多