java custom shaped frame using image [duplicate]

旧时模样 提交于 2019-12-20 06:29:31

问题


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);

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?


回答1:


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.

For example...

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

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

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();
            }
        }
    }

}

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...




回答2:


You'll have to create a shape based on your image. There are different threads here on SO that provide some way how to do this. The best one (based on the description, I didn't try it myself) might be Java - Create a shape from border around image. Another option for more complex images could be Image/Graphic into a Shape.

Another solution might be to use an undecorated frame along with "per-pixel transparency", as explained by Oracle here: http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html



来源:https://stackoverflow.com/questions/26205164/java-custom-shaped-frame-using-image

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!