随笔 - 18  文章 - 96  trackbacks - 0
<2007年10月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910


常用链接

留言簿(4)

随笔档案

相册

我的兄弟们

搜索

  •  

最新评论

阅读排行榜

评论排行榜

    以前或许大家对一个UI组件是否透明没有那么关心,但是自从Vista的毛玻璃出现后,UI透明就成了大家非常关注的一个话题,于是Java阵营开始了铺天盖地的讨论如何实现透明的效果,但是很不幸的是无论组件如何透明和变换,但是能够放置于屏幕任何位置的Window一族就是没法透明和变形,原生代码的问题还是交给原生代码来解决吧。
    自己写原生代码是可怕的,特别是对我这种只知道Java的平凡程序员,所以我们得借助一个非常方便的跨平台的调用OS function方便的Lib,JNA便是最佳选择(那个谁,这里不是讨论JRuby&JPython的)。
    so, all robots, transform!
    下面我们要做一个界面是圆角四边形的,中间有一个滑动条来滑动调节透明度。先看看做好的截图。
    
    注意图中的JFrame边角已经变成了圆弧,滑动滑块,JFrame开始透明,桌面的图标显现出来,下面是代码。
   
/**
 * @(#)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(
200150);
        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(0100);
        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(00, frame
                .getWidth(), frame.getHeight(), 
2020);
        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来制作透明效果非常简单,只需要调用WindowUtils.setWindowAlpha(window, alpha)就可以了。当然这是JNA特别为UI写的工具代码。如果要改变形状,用WindowUtils.setWindowMask(window, shape)或者WindowUtils.setWindowMask(window, icon)就可以了,但是要注意一点必须设置System.setProperty("sun.java2d.noddraw""true"),否则JNA会告诉你这个程序不支持透明。当然要运行起来,还得需要两个Jar,jna.jarexamples.jar ,都不是很大,只有200多K。
    虽然这篇文章只是介绍了一下JNA关于Swing的简单用法,但是有了这个我最先到的便是可以做类似于Yahoo Widget和Google Widget之类的东西了,还可以做好看的fishEye,SideBar,JNA的JAR两个合起来不过400K,却能让这么多复杂的事情简单化,真是精湛的艺术啊,嗯。

posted on 2007-10-21 13:43 ruislan 阅读(4363) 评论(12)  编辑  收藏

FeedBack:
# re: Swing透明和变换 2007-10-22 01:36 千里冰封
哈哈, 这么爽,试试先  回复  更多评论
  
# re: Swing透明和变换 2007-10-22 10:26 Eastsun
貌似不错,不晓得对运行速度的影响有多大?  回复  更多评论
  
# re: Swing透明和变换 2007-10-22 10:50 ruislan
对于今天的硬件来说,这个小程序运行速度完全不成问题,不管是不是冷热启动  回复  更多评论
  
# re: Swing透明和变换 2007-10-22 14:53 it123
不错  回复  更多评论
  
# re: Swing透明和变换 2007-10-22 23:46 Lemuel
那要写其他地小程序都要怎样写
Lemuel2525@126.com  回复  更多评论
  
# re: Swing透明和变换 2007-10-22 23:48 Lemuel2525
有一点不好就是如果选择最小
程序就完全看不见了
只好关闭了  回复  更多评论
  
# re: Swing透明和变换 2007-10-23 11:59 ruislan
嗯,要学习一下Lemuel,即便是对于一个example也要认真对待,应该限定一个滑块的底线到透明度的20%就应该不存在程序完全看不见的情况了  回复  更多评论
  
# re: Swing透明和变换 2007-10-23 19:00 老象
越来越nx了  回复  更多评论
  
# re: Swing透明和变换 2007-10-24 11:52 dyerac
但是如何使窗口上的组件不透明呢
仅仅使背景透明?  回复  更多评论
  
# re: Swing透明和变换 2008-06-21 17:52 -.-||
是Ubuntu 不是Ubunto  回复  更多评论
  
# re: Swing透明和变换 2009-05-08 17:35 a276202460
好东西好东西  回复  更多评论
  
# re: Swing透明和变换 2014-03-16 12:07 sd
为何有WindowUtils.setWindowMask(frame, mask);就没法执行?  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: