使用图像的java自定义形状框架

2022-01-24 00:00:00 java swing jframe

我喜欢创建一个看起来像这张图片的 java jframe.我已经创建了具有不同形状的 jframe,如三角形、圆形、多边形和一些疯狂的形状.但问题是太难了 [99% 不可能] 创建这样的形状image.so 如何制作这样的 jframe.我使用此代码创建形状窗口..

i like to create a java jframe look like this image.i have already crated jframes with different shapes like triangles ,circles ,polygons and some crazy shapes .but the problem it's too hard[99% impossible ] to create shape like this image.so how can i make a jframe like this.i used this code for create shaped window..

setUndecorated(true);
Polygon polygon = new Polygon();
polygon.addPoint(0, 0);
polygon.addPoint(100,100);

GeneralPath path = new GeneralPath();
path.append(polygon, true);
setShape(path);

现在我可以将此图像转换为形状.然后设置 setshapes.任何想法?或者有没有办法让 jframe 完全透明和 jlable 保持图像完全可见?

now can i convert this image to a shape .then set setshapes.any idea? or is there anyway to make jframe's fully transperent and jlable which hold image completely visible?

推荐答案

要制作透明窗口,需要将框架背景颜色的 alpha 设置为 0.这可能是我一段时间以来见过的最反直觉的调用,就好像你对任何其他 Swing 组件这样做一样,你会完全搞砸绘制过程.

To make a transparent window, you need to set the frames background color's alpha to 0. This is probably the most counter intuitive call I've seen in a while, as if you do this to any other Swing component, you will completely screw up the paint process.

您不想更改窗口的不透明度,因为它会影响整个窗口及其内容.

You don't want to change the opacity of the window, as it effectives the entire window and it's contents equally.

例如...

JWindow frame = new JWindow();
frame.setBackground(new Color(0, 0, 0, 0));

您不必使用 JWindow,但这意味着我不需要自己取消装饰...

You don't have to use a JWindow, but this means I don't need to undecorate it myself...

您还需要确保添加到窗口中的任何内容都是透明的(不透明 = false),这样它就不会隐藏"它下面的内容...

You also need to make sure that whatever content you add to the window is transparent (opaque = false), so that it doesn't "hide" what's underneath it...

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.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class LeafWindow {

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

    public LeafWindow() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JWindow frame = new JWindow();
                frame.setBackground(new Color(0, 0, 0, 0));
                frame.setContentPane(new LeafPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                frame.setAlwaysOnTop(true);
            }
        });
    }

    public class LeafPane extends JPanel {

        private BufferedImage leaf;

        public LeafPane() {

            setBorder(new CompoundBorder(
                            new LineBorder(Color.RED),
                            new EmptyBorder(0, 0, 250, 0)));

            try {
                leaf = ImageIO.read(getClass().getResource("/Leaf.png"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            setOpaque(false);
            setLayout(new GridBagLayout());

            JButton button = new JButton("Close");
            button.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.exit(0);
                }
            });

            add(button);

        }

        @Override
        public Dimension getPreferredSize() {
            return leaf == null ? new Dimension(200, 200) : new Dimension(leaf.getWidth(), leaf.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (leaf != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.drawImage(leaf, 0, 0, this);
                g2d.dispose();
            }
        }
    }

}

这个例子故意为内容添加了一个线条边框,因为你可以看到原始窗口的边界是什么.它还使用 EmptyBorderJButton 强制到图形上,但这只是一个示例...

This example deliberate adds a line border to the content as you can see what the original window bounds would be. It also uses a EmptyBorder to force the JButton onto the graphics, but this is just an example...

相关文章