Заставка не работает в Mac
Из-за проблем с отображением заставки 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();
Это прозрачное изображение, так как мне нужно, чтобы в моем окне была прямоугольная форма с закругленными углами. Это работает на Win 7, но в Mac 10.8. Mac по-прежнему показывает прямоугольник формы фона. На самом деле это не выглядит как фон. Может кто-нибудь сказать мне, что может быть причиной этого. Ниже приведены изображения для каждой платформы.
На окнах
На макинтош
Заранее спасибо.
РЕДАКТИРОВАТЬ:
Ответы отличные, но я видел, что AWTUtilities не всегда получает поддержку системы. Таким образом, в некоторых системах ответные методы могут давать сбой. Разве не существует решения, формального? Я имею в виду решение приходит с базового уровня?
4 ответа
Чтобы получить единое решение, вы должны использовать Java7. Полупрозрачность на пиксель была почти "экспериментальной" функцией в Java 6, и не считалось, что на нее можно положиться (именно поэтому AWTUtilities входит в пакет com.sun, который не является частью общедоступного API Java).
Тем не менее, и хотя у меня нет Mac для его тестирования, я видел людей, сообщавших, что установка фона рамки в Color(0, 0, 0, 0) (последний параметр - альфа-канал) работает для них в MacOS, Я не помню четко, работал ли он в Windows (мне пришлось использовать его пару лет назад), но я только что проверил его в Linux, и это не так.
В Java 7 полупрозрачные окна полностью поддерживаются и работают безупречно в Windows, MacOS и Linux. JFrame имеет новый метод setOpacity(Alpha) (который работает только с неокрашенными кадрами), и setColor(новый цвет (R, G, B, Alpha)) также работает (это эквивалентно, и снова работает только с неокрашенными кадрами).
Как видите, вы не можете полагаться на закрытый API AWTUtilities. В Java 6 у вас нет никакого "формального решения" этой проблемы, только хаки, частные API и неопределенность... Я не знаю, если это вариант, но вы должны подумать о переходе на Java7, если можете.
http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html Это показывает, как создать фасонное окно
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 Platform, выпуска Standard Edition 6 (Java SE 6), обновление 10, вы можете добавлять полупрозрачные и фигурные окна в свои приложения Swing.
Как уже говорилось, начиная с Java 1.6 update 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;
}
}
}
Как я уже сказал, использование AWTUtilities может не поддерживаться определенной системой и должно быть согласовано с Eneko. Также я сделал это следующим образом. Кажется, что-то похожее на идею eneko. Я проверил это в Windows 7 Ultimate Edition и Apple Mac OS Snow Leopard. Это сработало на обоих. Опять же, если это не работает на 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));