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


          常用鏈接

          留言簿(4)

          隨筆檔案

          相冊(cè)

          我的兄弟們

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

              以前或許大家對(duì)一個(gè)UI組件是否透明沒(méi)有那么關(guān)心,但是自從Vista的毛玻璃出現(xiàn)后,UI透明就成了大家非常關(guān)注的一個(gè)話題,于是Java陣營(yíng)開始了鋪天蓋地的討論如何實(shí)現(xiàn)透明的效果,但是很不幸的是無(wú)論組件如何透明和變換,但是能夠放置于屏幕任何位置的Window一族就是沒(méi)法透明和變形,原生代碼的問(wèn)題還是交給原生代碼來(lái)解決吧。
              自己寫原生代碼是可怕的,特別是對(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開始透明,桌面的圖標(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(
          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來(lái)制作透明效果非常簡(jiǎn)單,只需要調(diào)用WindowUtils.setWindowAlpha(window, alpha)就可以了。當(dāng)然這是JNA特別為UI寫的工具代碼。如果要改變形狀,用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.jarexamples.jar ,都不是很大,只有200多K。
              雖然這篇文章只是介紹了一下JNA關(guān)于Swing的簡(jiǎn)單用法,但是有了這個(gè)我最先到的便是可以做類似于Yahoo Widget和Google Widget之類的東西了,還可以做好看的fishEye,SideBar,JNA的JAR兩個(gè)合起來(lái)不過(guò)400K,卻能讓這么多復(fù)雜的事情簡(jiǎn)單化,真是精湛的藝術(shù)啊,嗯。

          posted on 2007-10-21 13:43 ruislan 閱讀(4394) 評(píng)論(12)  編輯  收藏

          FeedBack:
          # re: Swing透明和變換 2007-10-22 01:36 千里冰封
          哈哈, 這么爽,試試先  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2007-10-22 10:26 Eastsun
          貌似不錯(cuò),不曉得對(duì)運(yùn)行速度的影響有多大?  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2007-10-22 10:50 ruislan
          對(duì)于今天的硬件來(lái)說(shuō),這個(gè)小程序運(yùn)行速度完全不成問(wèn)題,不管是不是冷熱啟動(dòng)  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2007-10-22 14:53 it123
          不錯(cuò)  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2007-10-22 23:46 Lemuel
          那要寫其他地小程序都要怎樣寫
          Lemuel2525@126.com  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2007-10-22 23:48 Lemuel2525
          有一點(diǎn)不好就是如果選擇最小
          程序就完全看不見(jiàn)了
          只好關(guān)閉了  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2007-10-23 11:59 ruislan
          嗯,要學(xué)習(xí)一下Lemuel,即便是對(duì)于一個(gè)example也要認(rèn)真對(duì)待,應(yīng)該限定一個(gè)滑塊的底線到透明度的20%就應(yīng)該不存在程序完全看不見(jiàn)的情況了  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2007-10-23 19:00 老象
          越來(lái)越nx了  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2007-10-24 11:52 dyerac
          但是如何使窗口上的組件不透明呢
          僅僅使背景透明?  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2008-06-21 17:52 -.-||
          是Ubuntu 不是Ubunto  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2009-05-08 17:35 a276202460
          好東西好東西  回復(fù)  更多評(píng)論
            
          # re: Swing透明和變換 2014-03-16 12:07 sd
          為何有WindowUtils.setWindowMask(frame, mask);就沒(méi)法執(zhí)行?  回復(fù)  更多評(píng)論
            

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 周至县| 阿克陶县| 汾阳市| 高邮市| 宁晋县| 老河口市| 湖北省| 宝应县| 濉溪县| 甘泉县| 东辽县| 阳高县| 平顺县| 长治县| 桦甸市| 方正县| 怀仁县| 平凉市| 襄樊市| 乐平市| 钟祥市| 克山县| 乐亭县| 南部县| 建湖县| 荥经县| 颍上县| 余庆县| 姜堰市| 罗甸县| 张家港市| 宜兰县| 盐城市| 郧西县| 科技| 含山县| 巩义市| 新宁县| 绥江县| 晋宁县| 桂林市|