Является ли пример полупрозрачного окна обучающих программ Java проблематичным для тех, кто играет с jdk7?
Вот пример.
Если вы строите и запускаете TranslucentWindow
скажем, в среде IDE NetBeans 7.0, которая поддерживает jdk7, вы получите следующее исключение:
Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: The frame is decorated
at java.awt.Frame.setOpacity(Frame.java:960)
at main.TranslucentWindow.<init>(TranslucentWindow.java:23)
at main.TranslucentWindow$1.run(TranslucentWindow.java:47)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
BUILD SUCCESSFUL (total time: 1 second)
Согласно этой трассировке стека, ошибочная строка tw.setOpacity(0.55f)
, Но, как показывает ошибка, если вы вызываете setUndecorated(true)
на кадре, тогда он не сгенерирует исключение и создаст полупрозрачное окно, хотя и без какого-либо украшения (что является болью). Это нормально? Разве этот код не должен работать прямо "из коробки"? Я что-то пропускаю?
РЕДАКТИРОВАТЬ
Почему их полупрозрачное окно выглядит декорированным, или это пользовательский рендеринг?
Что это...
Что это должно быть...
5 ответов
Прямо из JavaDocs для java.awt.frame.setOpacity() в JDK7:
Следующие условия должны быть выполнены, чтобы установить значение непрозрачности менее 1,0f:
- Прозрачная прозрачность должна поддерживаться базовой системой
- Окно должно быть неукрашенным (см. SetUndecorated(логическое) и Dialog.setUndecorated(логическое))
- Окно не должно быть в полноэкранном режиме (см. GraphicsDevice.setFullScreenWindow(Window))
Если запрошенное значение непрозрачности меньше 1,0f и любое из вышеперечисленных условий не выполняется, непрозрачность окна не изменится, и будет выдано исключение IllegalComponentStateException.
Поведение, которое вы видите, задокументировано и является ожидаемым поведением.
Это проверенная ошибка. Я отправил Oracle информацию об ошибке своего примера кода, используя стандартную установку JDK 1.7.0 или JRE7. Используя приведенный ниже исходный код, скомпилированный в TranslucentWindow.java, он завершается ошибкой и создает исключение, первоначально указанное выше.
С веб-страницы Oracle Прозрачность / Shaped Windows Page
// Taken from http://download.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html#uniform
import java.awt.*;
import javax.swing.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;
public class TranslucentWindow extends JFrame {
public TranslucentWindow() {
super("TranslucentWindow");
setLayout(new GridBagLayout());
setSize(300,200);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add a sample button.
add(new JButton("I am a Button"));
}
public static void main(String[] args) {
// Determine if the GraphicsDevice supports translucency.
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
//If translucent windows aren't supported, exit.
if (!gd.isWindowTranslucencySupported(TRANSLUCENT))
{
System.err.println("Translucency is not supported");
System.exit(0);
}
// Create the GUI on the event-dispatching thread
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
TranslucentWindow tw = new TranslucentWindow();
// Set the window to 55% opaque (45% translucent).
tw.setOpacity(0.55f);
// Display the window.
tw.setVisible(true);
}
});
}
}
Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: The frame is decorated
at java.awt.Frame.setOpacity(Frame.java:960)
at TranslucentWindow$1.run(TranslucentWindow.java:38)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Я думаю, что вам нужно установить Undecorated перед setBackground это решит проблему
Использование com.sun.awt.AWTUtilities.setWindowOpacity(w, 0.5f)
в JDK 7.
Смотрите здесь.
Привет, проблема с этим кодом в том, что в методе main() отсутствует следующая строка кода:
JFrame.setDefaultLookAndFeelDecorated(true);
Он должен идти сразу после кода, который проверяет, не поддерживаются ли полупрозрачные окна, и завершается:
//If translucent windows aren't supported, exit.
if (!gd.isWindowTranslucencySupported(TRANSLUCENT)) {
System.err.println(
"Translucency is not supported");
System.exit(0);
}
JFrame.setDefaultLookAndFeelDecorated(true);
// Create the GUI on the event-dispatching thread
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
TranslucentWindow tw = new TranslucentWindow();
// Set the window to 55% opaque (45% translucent).
tw.setOpacity(0.55f);
// Display the window.
tw.setVisible(true);
}
});
Кроме того, изображение однородного полупрозрачного изображения вводит в заблуждение, потому что оно использует внешний вид Java. Вместо этого образ должен использовать внешний вид системы Windows (при условии, что вы работаете в Windows). Если вы попытаетесь использовать внешний вид Java (т.е. JFrame.setDefaultLookAndFeelDecorated(false);
), то он выдаст ту же ошибку, что и раньше. Я надеялся, что полупрозрачное окно будет работать с внешним видом Java, но я не думаю, что это возможно.