使用图像的java自定义形状框架
我喜欢创建一个类似于此图像的java jframe。我已经用不同的形状(如三角形、圆形、多边形和一些疯狂的形状)包装了jframe。但问题是,要创建类似此图像的形状太难了[99%不可能]。因此,我如何才能创建这样的jframe。我使用此代码创建了形状窗口使用图像的java自定义形状框架,java,swing,jframe,Java,Swing,Jframe,我喜欢创建一个类似于此图像的java jframe。我已经用不同的形状(如三角形、圆形、多边形和一些疯狂的形状)包装了jframe。但问题是,要创建类似此图像的形状太难了[99%不可能]。因此,我如何才能创建这样的jframe。我使用此代码创建了形状窗口 setUndecorated(true); Polygon polygon = new Polygon(); polygon.addPoint(0, 0); polygon.addPoint(100,100); GeneralPath pat
setUndecorated(true);
Polygon polygon = new Polygon();
polygon.addPoint(0, 0);
polygon.addPoint(100,100);
GeneralPath path = new GeneralPath();
path.append(polygon, true);
setShape(path);
现在我可以把这个图像转换成一个形状。然后设置形状。有什么想法吗?
或者,是否有任何方法可以使jframe的完全透明和可伸缩,从而使图像完全可见?您必须根据图像创建一个形状。这里有不同的线程,因此提供了一些方法来实现这一点。最好的(根据描述,我自己没有试过)可能是。对于更复杂的图像,另一种选择是
另一个解决方案可能是使用未装饰的框架和“每像素透明度”,正如Oracle在这里解释的那样:您必须根据图像创建形状。这里有不同的线程,因此提供了一些方法来实现这一点。最好的(根据描述,我自己没有试过)可能是。对于更复杂的图像,另一种选择是
另一种解决方案可能是使用未装饰的帧以及“每像素透明度”,正如Oracle在这里解释的那样:要制作透明窗口,需要将帧背景颜色的alpha设置为
0
。这可能是我在一段时间内看到的最违反直觉的调用,如果对任何其他Swing组件执行此操作,则会完全破坏绘制过程
您不希望更改窗口的不透明度,因为它会对整个窗口及其内容产生同等效果
例如
JWindow frame = new JWindow();
frame.setBackground(new Color(0, 0, 0, 0));
您不必使用JWindow
,但这意味着我不需要自己去装饰它
您还需要确保添加到窗口中的任何内容都是透明的(不透明=假),这样它就不会“隐藏”它下面的内容
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();
}
}
}
}
此示例向内容添加了一个线条边框,因为您可以看到原始窗口边框是什么。它还使用
EmptyBorder
将JButton
强制到图形上,但这只是一个示例…要创建透明窗口,需要将帧背景颜色的alpha设置为0
。这可能是我在一段时间内看到的最违反直觉的调用,如果对任何其他Swing组件执行此操作,则会完全破坏绘制过程
JWindow frame = new JWindow();
frame.setBackground(new Color(0, 0, 0, 0));
您不希望更改窗口的不透明度,因为它会对整个窗口及其内容产生同等效果
例如
JWindow frame = new JWindow();
frame.setBackground(new Color(0, 0, 0, 0));
您不必使用JWindow
,但这意味着我不需要自己去装饰它
您还需要确保添加到窗口中的任何内容都是透明的(不透明=假),这样它就不会“隐藏”它下面的内容
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();
}
}
}
}
此示例向内容添加了一个线条边框,因为您可以看到原始窗口边框是什么。它还使用
EmptyBorder
将JButton
强制到图形上,但这只是一个示例…老实说,如果使用透明帧并将图像绘制到背景中,将获得更好的效果,您将获得抗锯齿效果,而不是锐利的像素下降。通过一些巧妙的工作,如果需要,还可以生成一个剪切矩形it@MadProgrammer当我搜索的时候,我找到了很多你回答的答案。你能再解释一下怎么做吗?我不需要代码,只需要过程。我的英语不流利。我尝试将“帧不透明度”设置为0。但所有帧均隐藏。我尝试将“不透明”设置为false。我记得我是用c#使用透明键做的。但是我仍然没有找到一种方法使窗口透明,图像完全可见。对不起,应该是不要改变不透明度,因为它会影响框架和内容。相反,您希望将帧背景颜色的alpha设置为0,并使添加到其中的内容透明(不透明=假)。我添加了一个可运行的示例来演示,并稍加解释……老实说,使用透明帧并将图像绘制到背景中,您将获得更好的效果,您将获得抗锯齿效果,而不是急剧下降的像素。通过一些巧妙的工作,如果需要,还可以生成一个剪切矩形it@MadProgrammer当我搜索的时候,我找到了很多你回答的答案。你能再解释一下怎么做吗?我不需要代码,只需要过程。我的英语不流利。我尝试将“帧不透明度”设置为0。但所有帧均隐藏。我尝试将“不透明”设置为false。我记得我是用c#使用透明键做的。但是我仍然没有找到一种方法使窗口透明,图像完全可见。对不起,应该是不要改变不透明度,因为它会影响框架和内容。相反,您希望将帧背景颜色的alpha设置为0,并使添加到其中的内容透明(不透明=假)。我添加了一个可运行的示例进行演示,并提供了更多的解释……非常感谢。太棒了……您玩得很开心,很高兴它有所帮助;)非常感谢。那太棒了。你会玩得很开心,很高兴它帮了你;)
JWindow frame = new JWindow();
frame.setBackground(new Color(0, 0, 0, 0));