以前或許大家對(duì)一個(gè)UI組件是否透明沒(méi)有那么關(guān)心,但是自從Vista的毛玻璃出現(xiàn)后,UI透明就成了大家非常關(guān)注的一個(gè)話題,于是Java陣營(yíng)開(kāi)始了鋪天蓋地的討論如何實(shí)現(xiàn)透明的效果,但是很不幸的是無(wú)論組件如何透明和變換,但是能夠放置于屏幕任何位置的Window一族就是沒(méi)法透明和變形,原生代碼的問(wèn)題還是交給原生代碼來(lái)解決吧。
自己寫(xiě)原生代碼是可怕的,特別是對(duì)我這種只知道Java的平凡程序員,所以我們得借助一個(gè)非常方便的跨平臺(tái)的調(diào)用OS function方便的Lib,JNA便是最佳選擇(那個(gè)誰(shuí),這里不是討論JRuby&JPython的)。
so, all robots, transform!
下面我們要做一個(gè)界面是圓角四邊形的,中間有一個(gè)滑動(dòng)條來(lái)滑動(dòng)調(diào)節(jié)透明度。先看看做好的截圖。

注意圖中的JFrame邊角已經(jīng)變成了圓弧,滑動(dòng)滑塊,JFrame開(kāi)始透明,桌面的圖標(biāo)顯現(xiàn)出來(lái),下面是代碼。
/**
* @(#)TransparentFrame.java v0.1.0 2007-10-21
*/
package ruislan.rswing.test;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import com.sun.jna.examples.WindowUtils;
/**
* Transparent JFrame use JNA
*
* @author ruislan <a href="mailto:z17520@126.com"/>
* @version 0.1.0
*/
public class TransparentFrame {
private JFrame frame;
private JPanel container;
private JSlider slider;
private JPanel titleBar;
private JLabel titleLabel;
private JButton closeButton;
public static void main(String[] args) {
new TransparentFrame().launch();
}
private void launch() {
createUI();
launchUI();
}
protected void launchUI() {
frame.setVisible(true);
}
protected void createUI() {
System.setProperty("sun.java2d.noddraw", "true");
frame = new JFrame();
frame.setSize(200, 150);
frame.setAlwaysOnTop(true);
frame.setUndecorated(true);
container = new JPanel();
frame.setContentPane(container);
container.setLayout(new BorderLayout());
container.add(new JLabel("Ubunto vs Vista, I like both."),
BorderLayout.CENTER);
container.setBorder(new LineBorder(Color.BLACK));
titleBar = new JPanel();
titleBar.setLayout(new BorderLayout());
titleLabel = new JLabel("JNA is great!");
titleBar.add(titleLabel, BorderLayout.CENTER);
titleBar.setBorder(new LineBorder(Color.GRAY));
closeButton = new JButton("X");
closeButton.setFocusPainted(false);
closeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
titleBar.add(closeButton, BorderLayout.EAST);
container.add(titleBar, BorderLayout.NORTH);
slider = new JSlider(0, 100);
slider.setValue(100);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
float value = slider.getValue();
WindowUtils.setWindowAlpha(frame, value * 0.01f);
}
});
container.add(slider, BorderLayout.SOUTH);
RoundRectangle2D.Float mask = new RoundRectangle2D.Float(0, 0, frame
.getWidth(), frame.getHeight(), 20, 20);
WindowUtils.setWindowMask(frame, mask);
centerWindow(frame);
}
public static void centerWindow(Container window) {
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int w = window.getSize().width;
int h = window.getSize().height;
int x = (dim.width - w) / 2;
int y = (dim.height - h) / 2;
window.setLocation(x, y);
}
}
利用JNA來(lái)制作透明效果非常簡(jiǎn)單,只需要調(diào)用
WindowUtils.setWindowAlpha(window, alpha)就可以了。當(dāng)然這是JNA特別為UI寫(xiě)的工具代碼。如果要改變形狀,用WindowUtils.setWindowMask(window, shape)或者WindowUtils.setWindowMask(window, icon)就可以了,但是要注意一點(diǎn)必須設(shè)置System.setProperty("sun.java2d.noddraw", "true"),否則JNA會(huì)告訴你這個(gè)程序不支持透明。當(dāng)然要運(yùn)行起來(lái),還得需要兩個(gè)Jar,jna.jar 和 examples.jar ,都不是很大,只有200多K。
雖然這篇文章只是介紹了一下JNA關(guān)于Swing的簡(jiǎn)單用法,但是有了這個(gè)我最先到的便是可以做類(lèi)似于Yahoo Widget和Google Widget之類(lèi)的東西了,還可以做好看的fishEye,SideBar,JNA的JAR兩個(gè)合起來(lái)不過(guò)400K,卻能讓這么多復(fù)雜的事情簡(jiǎn)單化,真是精湛的藝術(shù)啊,嗯。
posted on 2007-10-21 13:43
ruislan 閱讀(4385)
評(píng)論(12) 編輯 收藏