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


          常用鏈接

          留言簿(4)

          隨筆檔案

          相冊

          我的兄弟們

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

              以前或許大家對一個UI組件是否透明沒有那么關(guān)心,但是自從Vista的毛玻璃出現(xiàn)后,UI透明就成了大家非常關(guān)注的一個話題,于是Java陣營開始了鋪天蓋地的討論如何實現(xiàn)透明的效果,但是很不幸的是無論組件如何透明和變換,但是能夠放置于屏幕任何位置的Window一族就是沒法透明和變形,原生代碼的問題還是交給原生代碼來解決吧。
              自己寫原生代碼是可怕的,特別是對我這種只知道Java的平凡程序員,所以我們得借助一個非常方便的跨平臺的調(diào)用OS function方便的Lib,JNA便是最佳選擇(那個誰,這里不是討論JRuby&JPython的)。
              so, all robots, transform!
              下面我們要做一個界面是圓角四邊形的,中間有一個滑動條來滑動調(diào)節(jié)透明度。先看看做好的截圖。
              
              注意圖中的JFrame邊角已經(jīng)變成了圓弧,滑動滑塊,JFrame開始透明,桌面的圖標(biāo)顯現(xiàn)出來,下面是代碼。
             
          /**
           * @(#)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來制作透明效果非常簡單,只需要調(diào)用WindowUtils.setWindowAlpha(window, alpha)就可以了。當(dāng)然這是JNA特別為UI寫的工具代碼。如果要改變形狀,用WindowUtils.setWindowMask(window, shape)或者WindowUtils.setWindowMask(window, icon)就可以了,但是要注意一點必須設(shè)置System.setProperty("sun.java2d.noddraw""true"),否則JNA會告訴你這個程序不支持透明。當(dāng)然要運行起來,還得需要兩個Jar,jna.jarexamples.jar ,都不是很大,只有200多K。
              雖然這篇文章只是介紹了一下JNA關(guān)于Swing的簡單用法,但是有了這個我最先到的便是可以做類似于Yahoo Widget和Google Widget之類的東西了,還可以做好看的fishEye,SideBar,JNA的JAR兩個合起來不過400K,卻能讓這么多復(fù)雜的事情簡單化,真是精湛的藝術(shù)啊,嗯。

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

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

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 临沭县| 襄汾县| 丹棱县| 桑植县| 潢川县| 图们市| 扬中市| 陆川县| 青田县| 泰安市| 西林县| 庆阳市| 集贤县| 方城县| 田阳县| 镇安县| 奎屯市| 太保市| 利辛县| 邹城市| 丹东市| 五台县| 峨山| 边坝县| 响水县| 浮山县| 纳雍县| 六安市| 瓦房店市| 清镇市| 句容市| 通渭县| 云和县| 苍梧县| 杭锦旗| 安仁县| 册亨县| 万山特区| 同江市| 凌源市| 丰县|