Статьи

Java 7: прозрачность и фасонные окна

Java 7 представляет очень интересные функции для окон рабочего стола:

  • Transclucency for windows : сделать полное окно полупрозрачным с указанным альфа-уровнем
  • Пиксельная прозрачность : сделать часть окна прозрачной.
  • Shaped windows : теперь вы можете создавать окна определенной формы, такие как круг, овал, треугольник,…

Мы увидим все эти функции в этом посте. Все примеры протестированы в 64-разрядной версии Windows Seven, поскольку прозрачность не поддерживается в Ubuntu 10.04 на момент написания статьи.

Прежде всего, теперь вы можете установить непрозрачность окна с помощью setOpacity (float opacity) класса Window. При этом все окно становится прозрачным. У этого нового метода есть некоторые ограничения. Непрозрачность менее 1,0 не поддерживается, если в окне используется полноэкранный режим или если не поддерживается простая прозрачность. Вы можете проверить, поддерживается ли прозрачность окна с помощью метода isWindowTranslucencySupported (), добавленного в класс GraphicsDevice:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
if (ge.getDefaultScreenDevice().isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT)) {
System.out.println("Window translucency is supported on your system. ");
}

Мы знаем достаточно, чтобы написать первое полупрозрачное окно:

package com.wicht.java7.swing;
 
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
 
import java.awt.*;
 
public class TranslucentWindow extends JFrame {
public TranslucentWindow() {
super("Simple Translucency Demo");
 
setSize(300, 200);
 
setDefaultCloseOperation(EXIT_ON_CLOSE);
 
getRootPane().setDoubleBuffered(false);
setOpacity(0.5f);
 
setLocationRelativeTo(null);
setVisible(true);
}
 
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
 
if (ge.getDefaultScreenDevice().isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT)) {
new TranslucentWindow();
}
}
});
}
}

Примечание. Мы отключаем двойную буферизацию, чтобы удалить артефакты, возникающие при двойной буферизации полупрозрачного окна.

Вот и производим этот результат на моем компьютере:

Полупрозрачное окно Java 7

Полупрозрачное окно Java 7

Так что сделать окно полупрозрачным очень просто. Но вы можете сделать больше. Вы также можете сделать только набор пикселей полупрозрачным, используя их цвет фона. Как и у полупрозрачного окна, есть некоторые ограничения, окно не должно быть полноэкранным, и система должна поддерживать полупрозрачность на пиксель. Вы можете проверить это так же, как в первый раз:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
if (ge.getDefaultScreenDevice().isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT)) {
System.out.println("Window translucency is supported on your system. ");
}

Простое создание сетки из 16 панелей, все более прозрачных:

package com.wicht.java7.swing;
 
import javax.swing.*;
 
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
public class GriddedTranslucentWindow extends JFrame {
public GriddedTranslucentWindow() {
super("Java 7 Per Pixel Translucency");
 
setSize(300, 320);
 
getContentPane().setLayout(new GridLayout(4, 4));
 
for(int i = 0; i < 16; i++){
add(new AlphaPanel(255 - i * 12));
}
 
setBackground(new Color(0, 0, 0, 0));
 
setLocationRelativeTo(null);
setVisible(true);
}
 
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
 
if (ge.getDefaultScreenDevice().isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT)) {
new GriddedTranslucentWindow();
}
}
});
}
 
private class AlphaPanel extends JPanel {
private AlphaPanel(int alpha) {
super();
 
setBackground(new Color(0, 0, 255, alpha));
}
}
}

Это дает мне такой результат:

Java 7: полупрозрачность на пиксель

Java 7: полупрозрачность на пиксель

Пример очень прост, конечно, но вы можете представить, что делаете много вещей, используя эту функцию.

А теперь сумасшедшая новая особенность: фасонные окна!

Java 7 позволяет создавать окна любой формы, которую вы хотите. Вы можете создать круг, треугольник, эллиптические окна или более сложную форму, например, смайлик. Для этого у вас теперь есть доступ к методу setShape (Shape shape) в классе Window. Как и два других, полноэкранный режим не разрешен, и ваш компьютер должен поддерживать прозрачность на пиксель:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
if (ge.getDefaultScreenDevice().isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT )) {
System.out.println("Window translucency is supported on your system. ");
}

Вот небольшой пример, объединяющий треугольник и круг:

package com.wicht.java7.swing;
 
import javax.swing.*;
 
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
 
public class ShapedWindow extends JFrame {
public ShapedWindow() {
super("Shaped Window");
 
setUndecorated(true);
 
setSize(new Dimension(200, 300));
 
Polygon polygon = new Polygon();
polygon.addPoint(0, 200);
polygon.addPoint(100, 0);
polygon.addPoint(200, 200);
 
Ellipse2D.Double theCircle = new Ellipse2D.Double(0, 100, 1.0*200, 1.0*200);
 
GeneralPath path = new GeneralPath();
path.append(polygon, true);
path.append(theCircle, true);
 
setShape(path);
 
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.X_AXIS));
 
add(Box.createHorizontalGlue());
JLabel label = new JLabel("Shaped window");
label.setForeground(Color.white);
add(label);
add(Box.createHorizontalGlue());
 
getContentPane().setBackground(Color.blue);
 
setLocationRelativeTo(null);
setVisible(true);
}
 
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
 
if (ge.getDefaultScreenDevice().isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT)) {
new ShapedWindow();
}
}
});
}
}

Это продукты такого рода окно:

Java 7: Фасонные окна

Java 7: Фасонные окна

И, конечно, вы можете комбинировать прозрачность и фасонные окна, добавляя setOpacity (0.5f) к вашему фрейму. Для этого должны поддерживаться прозрачность на пиксель и прозрачность на пиксель. Это дает нам такие окна:

Java 7: полупрозрачное окно

Java 7: полупрозрачное окно

Мы здесь. Теперь мы рассмотрели новые функции прозрачности в Java 7. Я думаю, что это действительно интересно и делает настольные приложения Java более конкурентоспособными. Но я думаю, что в Swing еще есть над чем поработать, прежде чем делать такие забавные вещи.

С http://www.baptiste-wicht.com/2010/06/java-7-translucency-shaped-windows/