显示JAVA 6启动画面时出现问题我使用以下方法显示启动窗口。
File splashImageFile = new File(Constants.PATH_IMAGE + "splash.png");
final BufferedImage img = ImageIO.read(splashImageFile);
final JWindow window = new JWindow() {
private static final long serialVersionUID = -132452345234523523L;
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Rectangle windowRect = getBounds();
try {
Robot robot = new Robot(getGraphicsConfiguration().getDevice());
BufferedImage capture = robot.createScreenCapture(new Rectangle(windowRect.x, windowRect.y, windowRect.width, windowRect.height));
g2.drawImage(capture, null, 0, 0);
} catch (IllegalArgumentException iae) {
System.out.println("Argumets mis matched.\n" + iae.getMessage());
} catch(SecurityException se){
System.out.println("Security permission not supported\n" + se.getMessage());
} catch (AWTException ex) {
System.out.println("Exception found when creating robot.\n" + ex.getMessage());
}
g2.drawImage(img, 0, 0, null);
g2.setFont(new Font("TimesRoman", Font.BOLD, 15));
g2.drawString("Loading...", 320, 260);
g2.dispose();
}
};
window.setAlwaysOnTop(true);
window.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
window.pack();
window.setLocationRelativeTo(null);
window.setVisible(true);
window.repaint();
图像是png透明图像,因为我需要在窗口中使用圆角矩形。它适用于Win 7但在mac 10.8中。 Mac仍然显示矩形形状背景。它实际上似乎不是背景。有人可以告诉我可能导致什么。以下是每个平台的图像。
在Windows上
在Mac上
提前致谢。
编辑:
答案很棒,但我已经看到AWTUtilities并不总是获得系统支持。所以在一些系统中,回答方法可能会失败。难道没有正式的解决方案吗?我的意思是解决方案来自基础水平?
答案 0 :(得分:6)
http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html#shaped 这显示了如何创建形状窗口
addComponentListener(new ComponentAdapter() {
// Give the window an elliptical shape.
// If the window is resized, the shape is recalculated here.
@Override
public void componentResized(ComponentEvent e) {
setShape(new Ellipse2D.Double(0,0,getWidth(),getHeight()));
}
});
setUndecorated(true);
他们说:从Java平台标准版6(Java SE 6)更新版本10开始,您可以为Swing应用程序添加半透明和整形窗口。
答案 1 :(得分:5)
正如已经开始声明的那样,从Java 1.6更新10开始,您可以访问com.sun.awt.AWTUtilities
(私有API),它提供每像素分区支持。
这一切的一个技巧是确保将内容窗格设置为透明。
在Mac OS 10.7.5,10.8.2下测试;使用Java 1.6.0_37和1.7.0_06
public class TestWindowTransparency {
public static void main(String[] args) {
new TestWindowTransparency();
}
public TestWindowTransparency() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
SplashWindow window = new SplashWindow();
window.setVisible(true);
}
});
}
public class SplashWindow extends JWindow {
public SplashWindow() {
ImageIcon icon = null;
try {
icon = new ImageIcon(ImageIO.read(getClass().getResource("/Splash02.png")));
} catch (Exception e) {
e.printStackTrace();
}
setAlwaysOnTop(true);
JPanel content = new JPanel(new BorderLayout());
content.setOpaque(false);
setContentPane(content);
JLabel lbl = new JLabel(icon);
lbl.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
dispose();
}
}
});
add(lbl);
if (!supportsPerAlphaPixel()) {
System.out.println("Per Pixel Alpher is not supported by you system");
}
setOpaque(false);
pack();
setLocationRelativeTo(null);
}
public boolean supportsPerAlphaPixel() {
boolean support = false;
try {
Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
support = true;
} catch (Exception exp) {
exp.printStackTrace();
}
return support;
}
public void setOpaque(boolean opaque) {
try {
Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
if (awtUtilsClass != null) {
Method method = awtUtilsClass.getMethod("setWindowOpaque", Window.class, boolean.class);
method.invoke(null, this, opaque);
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
public void setOpacity(float opacity) {
try {
Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
if (awtUtilsClass != null) {
Method method = awtUtilsClass.getMethod("setWindowOpacity", Window.class, float.class);
method.invoke(null, this, opacity);
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
public float getOpacity() {
float opacity = 1f;
try {
Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
if (awtUtilsClass != null) {
Method method = awtUtilsClass.getMethod("getWindowOpacity", Window.class);
Object value = method.invoke(null, this);
if (value != null && value instanceof Float) {
opacity = ((Float) value).floatValue();
}
}
} catch (Exception exp) {
exp.printStackTrace();
}
return opacity;
}
}
}
答案 2 :(得分:4)
要获得统一的解决方案,您应该使用Java7。每个像素半透明几乎是一个&#34;实验&#34; Java 6中的功能,并没有被认为是你可以依赖的东西(这就是AWTUtilities进入com.sun包的原因,which is not part of Java public API)。
然而,虽然我还没有Mac测试它,但是我看到人们报告将帧背景设置为Color(0,0,0,0)(最后一个参数是alpha频道)在MacOS为他们工作。我不清楚它是否在Windows中工作(几年前我不得不使用它),但我刚刚在Linux上测试过它并没有。
在Java 7中,半透明窗口完全受支持,并且在Windows,MacOS和Linux中完美运行。 JFrame有新的setOpacity(Alpha)方法(仅适用于未修饰的帧)和setColor(新的Color(R,G,B,Alpha))也在工作(它是等效的,并且只能用于未修饰的帧)。
如您所见,您无法依赖私有API AWTUtilities。在Java 6中,您还没有获得任何正式的解决方案&#34;对于这个问题,只有黑客,私有API和不确定性......我不知道它是否是一个选项,但你应该考虑切换到Java7,如果可以的话。
答案 3 :(得分:2)
正如我所说,某些系统可能不支持使用AWTUtilities,并且必须同意Eneko。我也这样做了如下。似乎有点类似于eneko的想法。我已经在Windows 7终极版和苹果mac os雪豹中进行了测试。它同时适用于两者。再次,如果这不适用于Linux,那么这也不是一个广泛适用的解决方案。希望有人可以发布这个答案。
final JWindow window = new JWindow() {
private static final long serialVersionUID = -132452345234523523L;
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Rectangle windowRect = new Rectangle(getSize());
g2.setColor(new Color(255, 255, 255, 0));
g2.draw(new RoundRectangle2D.Float(windowRect.x, windowRect.y, windowRect.width, windowRect.height, 85, 85));
g2.drawImage(img, 0, 0, null);
g2.dispose();
}
};
window.setBackground(new Color(0,0,0,0));