<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 18  文章 - 96  trackbacks - 0
    <2007年9月>
    2627282930311
    2345678
    9101112131415
    16171819202122
    23242526272829
    30123456


    常用鏈接

    留言簿(4)

    隨筆檔案

    相冊

    我的兄弟們

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    看來我們的JTextField之旅也到了一個階段,已經(jīng)很不錯了,現(xiàn)在我們來改造JButton,讓那個呆板的Swing看起來舒服一些。

    還是先放上完成后的效果圖:

    普通的狀態(tài)


    鼠標(biāo)滑過


    鼠標(biāo)按下

    和代碼:
      1 /**
      2  * @(#)RJButton.java  0.1.0  2007-9-11
      3  */
      4 package ruislan.rswing;
      5 
      6 import java.awt.AlphaComposite;
      7 import java.awt.Color;
      8 import java.awt.Font;
      9 import java.awt.GradientPaint;
     10 import java.awt.Graphics;
     11 import java.awt.Graphics2D;
     12 import java.awt.RenderingHints;
     13 import java.awt.Shape;
     14 import java.awt.event.MouseAdapter;
     15 import java.awt.event.MouseEvent;
     16 import java.awt.geom.RoundRectangle2D;
     17 
     18 import javax.swing.JButton;
     19 
     20 /**
     21  * Custom JButton
     22  * 
     23  * @version 0.1.0
     24  * @author ruislan <a href="mailto:z17520@126.com"/>
     25  */
     26 public class RButton extends JButton {
     27     private static final long serialVersionUID = 39082560987930759L;
     28     public static final Color BUTTON_COLOR1 = new Color(205255205);
     29     public static final Color BUTTON_COLOR2 = new Color(5115447);
     30     // public static final Color BUTTON_COLOR1 = new Color(125, 161, 237);
     31     // public static final Color BUTTON_COLOR2 = new Color(91, 118, 173);
     32     public static final Color BUTTON_FOREGROUND_COLOR = Color.WHITE;
     33     private boolean hover;
     34 
     35     public RButton() {
     36         setFont(new Font("system", Font.PLAIN, 12));
     37         setBorderPainted(false);
     38         setForeground(BUTTON_COLOR2);
     39         setFocusPainted(false);
     40         setContentAreaFilled(false);
     41         addMouseListener(new MouseAdapter() {
     42             @Override
     43             public void mouseEntered(MouseEvent e) {
     44                 setForeground(BUTTON_FOREGROUND_COLOR);
     45                 hover = true;
     46                 repaint();
     47             }
     48 
     49             @Override
     50             public void mouseExited(MouseEvent e) {
     51                 setForeground(BUTTON_COLOR2);
     52                 hover = false;
     53                 repaint();
     54             }
     55         });
     56     }
     57 
     58     @Override
     59     protected void paintComponent(Graphics g) {
     60         Graphics2D g2d = (Graphics2D) g.create();
     61         int h = getHeight();
     62         int w = getWidth();
     63         float tran = 1F;
     64         if (!hover) {
     65             tran = 0.3F;
     66         }
     67 
     68         g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
     69                 RenderingHints.VALUE_ANTIALIAS_ON);
     70         GradientPaint p1;
     71         GradientPaint p2;
     72         if (getModel().isPressed()) {
     73             p1 = new GradientPaint(00new Color(000), 0, h - 1,
     74                     new Color(100100100));
     75             p2 = new GradientPaint(01new Color(00050), 0, h - 3,
     76                     new Color(255255255100));
     77         } else {
     78             p1 = new GradientPaint(00new Color(100100100), 0, h - 1,
     79                     new Color(000));
     80             p2 = new GradientPaint(01new Color(255255255100), 0,
     81                     h - 3new Color(00050));
     82         }
     83         g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
     84                 tran));
     85         RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(00, w - 1,
     86                 h - 12020);
     87         Shape clip = g2d.getClip();
     88         g2d.clip(r2d);
     89         GradientPaint gp = new GradientPaint(0.0F0.0F, BUTTON_COLOR1, 0.0F,
     90                 h, BUTTON_COLOR2, true);
     91         g2d.setPaint(gp);
     92         g2d.fillRect(00, w, h);
     93         g2d.setClip(clip);
     94         g2d.setPaint(p1);
     95         g2d.drawRoundRect(00, w - 1, h - 12020);
     96         g2d.setPaint(p2);
     97         g2d.drawRoundRect(11, w - 3, h - 31818);
     98         g2d.dispose();
     99         super.paintComponent(g);
    100     }
    101 }
    102 


    注意代碼中的幾個部分:

    首先是paintComponent方法中最后一行,我們調(diào)用了父類的paintComponent方法,這是因為我們要靠父類來繪制字符,但是父類的這個方法除了繪制字符之外還會繪制其他的,所以我們需要關(guān)閉掉其他的(當(dāng)然我們也可以自己來繪制字符,但是JButton提供了方法為什么不用呢),所以我們在構(gòu)造方法那里調(diào)用了:
    setBorderPainted(false);
    setFocusPainted(false);
    setContentAreaFilled(false);
    告訴父類不用繪制邊框,不用繪制焦點,不用繪制內(nèi)容部分,這部分我們自己來搞*o*。

    然后就是這一句了g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)告訴繪制API我們需要平滑一點,否則繪制出來會有很多鋸齒喲。

    接下來的這一句g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,tran))告訴繪圖API我們需要繪制一個有透明度的,tran就是透明度(0-1)。

    然后就是將邊框的邊角變直角為圓角,我們繪制一個RoundRectangle2D,這個就是邊角都為圓角的方形,然后我們根據(jù)這個方形來clip我們的方形,這樣方形就被RoundRectangle2D的圓角方形包裹,從而變成了圓角方形。

    最后就是繪制外邊線和內(nèi)邊線,通過改變內(nèi)邊線和外邊線的色變從而造成陷入或者突出效果。

    整個JButton改造完畢,如果你能夠活用clip的話,你也可以做一個五角星的JButton喲。

    整個源代碼我連同Eclipse工程文件已經(jīng)打包成zip放在我的文件里面,下載鏈接如下:
    http://www.tkk7.com/Files/ruislan/rswing-0.1.0.zip

    posted on 2007-09-11 12:24 ruislan 閱讀(5555) 評論(20)  編輯  收藏

    FeedBack:
    # re: JButton大改造 2007-09-11 13:14 千里冰封
    不錯不錯,寫得很好
    期待樓主更好的作品,有機(jī)會共同研究一下SWING:)  回復(fù)  更多評論
      
    # re: JButton大改造[未登錄] 2007-09-11 18:28 zc
    樓主,源代碼可以不帶行號嗎?這樣直接COPY到編輯器里還要自己修改,非常的麻煩。  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-11 18:34 ruislan
    好好好
    我就遷就你們這些懶人,下次不帶行號了。  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-11 21:36 Rene
    樓住能否公布一下你Blogspot的地址呢?
    或者在頁面上加個鏈接就更好了^_^  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-11 23:32 BeanSoft
    更好的方法是開發(fā)一個 ButtonUI. Swing 本身的 MVC 就是這樣分的. 呵呵, 這樣不影響原始的 JButton 的代碼.

    /**
    * $ $ License.
    *
    * Copyright $ L2FProd.com
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    * http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing, software
    * distributed under the License is distributed on an "AS IS" BASIS,
    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */
    package com.l2fprod.common.swing.plaf.blue;

    import java.awt.Color;
    import java.awt.Graphics;

    import javax.swing.AbstractButton;
    import javax.swing.BorderFactory;
    import javax.swing.JComponent;
    import javax.swing.plaf.basic.BasicButtonUI;

    /**
    * BlueishButtonUI. <br>
    *
    */
    public class BlueishButtonUI
    extends BasicButtonUI {

    private static Color blueishBackgroundOver = new Color(224, 232, 246);
    private static Color blueishBorderOver = new Color(152, 180, 226);

    private static Color blueishBackgroundSelected = new Color(193, 210, 238);
    private static Color blueishBorderSelected = new Color(49, 106, 197);

    public BlueishButtonUI() {
    super();
    }

    public void installUI(JComponent c) {
    super.installUI(c);

    AbstractButton button = (AbstractButton)c;
    button.setRolloverEnabled(true);
    button.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
    }

    public void paint(Graphics g, JComponent c) {
    AbstractButton button = (AbstractButton)c;
    if (button.getModel().isRollover()
    || button.getModel().isArmed()
    || button.getModel().isSelected()) {
    Color oldColor = g.getColor();
    if (button.getModel().isSelected()) {
    g.setColor(blueishBackgroundSelected);
    } else {
    g.setColor(blueishBackgroundOver);
    }
    g.fillRect(0, 0, c.getWidth() - 1, c.getHeight() - 1);

    if (button.getModel().isSelected()) {
    g.setColor(blueishBorderSelected);
    } else {
    g.setColor(blueishBorderOver);
    }
    g.drawRect(0, 0, c.getWidth() - 1, c.getHeight() - 1);

    g.setColor(oldColor);
    }

    super.paint(g, c);
    }

    }
      回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-12 00:39 ruislan
    BeanSoft兄,何必舍近求遠(yuǎn)去找一個L2fprod呢,JDK里面就有現(xiàn)成的Metal和windows等等LookAndFeel的范例。

    不過我想問一下,LookAndFeel的這種設(shè)計是一種MVC嗎?也許在下駑鈍,理解的是一種策略模式,將組件的paint方式交給了各個LookAndFeel的實現(xiàn)來完成,然后由用戶通過UIManager來決定裝載的不同,從而調(diào)用不同的繪制策略。

    “更好的”方法比“更適合”的方法獲得的效率差太多了,如果采用了BeanSoft兄的方案,那不知道要有多少步才能看到在下這個界面了,繼承LookAndFeel,寫B(tài)uttionUI,...,啟動程序的時候裝載這個LookAndFeel類...,在下只是改造一下JButton,何必非要為了JButton弄一個LookAndFeel出來呢。其實為什么大家都喜歡Spring多過EJB呢,為了迎合一個框架我們做得無用功太多了,而Spring給了我們自由的選擇,但為了Spring我們也做了很多無用的東西,所以才有了AppFuse(大師說代碼生成是罪惡,所以我們也該反對AppFuse?),才有了ruby on rails。聰明的人雖然也會按照成規(guī)辦事,但是他會選擇最適合他的成規(guī),如果沒有他寧愿嘗試創(chuàng)新,否則,也不會有這么多新的框架如春筍般冒出來了。

    也許可能會覺得我太注重實際的結(jié)果,用戶的感受而忽略了作為一名不斷上進(jìn)的開發(fā)人員需要的學(xué)者學(xué)術(shù)般的研究和討論,這可能才是BeanSoft兄“更好的”含義吧。我會多多改進(jìn)的。

    P.S 怎么感覺像是DDL和蝎在討論什么才是藝術(shù)?嗯  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-12 06:58 BeanSoft
    我倒... 我有沒說你要開發(fā) Look and Feel, 實際上ButtonUI 類和任何 L&F 無關(guān), 用 L2fprod 也只是懶得寫更多代碼而已. 我也是跟你討論 Swing 呢, 不是嗎? 只需要一步就能看到效果, 不需要多少步. PS 我以前可是狠狠學(xué)過一陣 Swing, 理解的不對的地方還可以繼續(xù)討論. 我這也不是學(xué)術(shù)般的討論, 也是實用出發(fā). 我不喜歡高談闊論, 只喜歡代碼說話.

    Swing 的 MVC 我不想贅述, 我想說的是要改外觀用 ButtonUI 會更方便一些而已, 不用對原來的界面邏輯代碼做太多改動. 剛才那個例子用法很簡單,
    button.setUI(new BlueishButtonUI()); 即可改變單個按鈕的外觀, 而 L&F 是為了改變所有組件的外觀.

    用法示例:
    import java.awt.FlowLayout;

    import javax.swing.JButton;
    import javax.swing.WindowConstants;

    public class NewJFrame extends javax.swing.JFrame {
    private JButton jButton1;
    private JButton jButton2;

    public static void main(String[] args) {
    NewJFrame inst = new NewJFrame();
    inst.setVisible(true);
    }

    public NewJFrame() {
    super();
    initGUI();
    // 設(shè)置 UI 來加入不同的繪制方法, 可以切換不同的繪制方法, 例如換膚
    jButton1.setUI(new BlueishButtonUI());
    }

    private void initGUI() {
    try {
    FlowLayout thisLayout = new FlowLayout();
    getContentPane().setLayout(thisLayout);
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    {
    jButton1 = new JButton();
    getContentPane().add(jButton1);
    jButton1.setText("自定義外觀,需要UI嗎?需要");
    }
    {
    jButton2 = new JButton();
    getContentPane().add(jButton2);
    jButton2.setText("默認(rèn)外觀");
    }
    pack();
    setSize(400, 300);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    }
      回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-12 08:52 交口稱贊
    一個SWT死忠幸福的看著樓上一群人

    呵呵。  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-12 13:28 BeanSoft
    呵呵, SWT 啥時候能換膚作出像 Office 2003, 2007 那樣漂亮的界面就好了. 說實話 SWT 也土的掉渣.  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-12 13:36 ruislan
    我也改造過SWT的,是有點古板,土的掉渣這個就有點...  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-12 13:39 darkhe
    又頂。  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-12 15:22 交口稱贊
    @BeanSoft

    SWT是跟本地操作系統(tǒng)界面一致,這是他最大的優(yōu)點啊
    比如你用XP換個什么蘋果主題,swt自動就是這個主題的樣子。

    樓主的代碼,放到swt里也差不多。
    也能定義一堆PP的swt控件。  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-12 21:58 天若無情
    樓主有時間的話可以考慮用Graphics直接在AWT上繪制些控件并加上Event處理,Swing雖然以AWT為基礎(chǔ),但很多地方都被優(yōu)化了,圖像緩存也不用考慮太多,如果要在AWT開發(fā)的系統(tǒng)使用還需要很多修改(或者說,我習(xí)慣重寫JRE發(fā)布[反正Sun犯不上告我……],能將Swing部分包去掉就可以節(jié)省不少的資源,既然重繪界面,干脆徹底點,只留AWT作基礎(chǔ)就好了。)。即使不考慮版本的兼容性與大小,也是盡量用Graphics繪制從界面到事件觸發(fā)的算法比較值得學(xué)習(xí)。  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-13 09:34 Matthew Chen
    UI delegate 是swing在mvc基礎(chǔ)上加的一些提高靈活性的擴(kuò)展,外觀同樣是隨操作系統(tǒng)本地的外觀呈現(xiàn)的,awt只是swing最底層的基礎(chǔ),老實說這個基礎(chǔ)薄弱而且過于依賴平臺對等體,swing就好像借awt這只雞生的蛋,用的只是那個殼,而繪制了其他的一切來確保了幾乎沒有平臺差異,可能用慣了swt的對awt不會怎么反感,但是用慣了swing的卻不會想去用awt。
    覺得setUI的方法確實比在button上編碼修改好,起碼可以動態(tài)裝卸。其實swing只對平臺共有的個性化組件使用了UI delegate,自然是認(rèn)為這些組件才被用戶視為理當(dāng)呈現(xiàn)為平臺上的樣子,而如樓主的這個例子,使得任何平臺和任何laf下按鈕都會是同一個樣子,談不上有什么問題,這個看項目的需要。
    swing是個不錯的平臺差異化下桌面解決方法。  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-13 11:04 天若無情
    Swing和AWT的關(guān)系其實非常微妙,Swing的基礎(chǔ)組件,都是以AWT的底層白板組件實現(xiàn),或者說繪制的。它以一種理論上的純Java方式,將AWT中所有無用部分加以摒棄。也就是說,AWT可以做到的,Swing一定可以做到,而Swing做得到的,AWT不一定可以做到。但是對Swing特性的依賴,一定會某種程度減少代碼的可移植性。比如說,我現(xiàn)在有一組完全以Graphics在AWT白板上繪制的圖形控件,那么在C#中使用它的話,大體只是算法的移植,只需要很少的代碼修改就可以在C#中實現(xiàn)相同的效果。但是以Swing為基礎(chǔ)的話,由于其自父類JComponent起便開始加入自己的本地化算法,轉(zhuǎn)為C#平臺就需要更多的事件與參數(shù)轉(zhuǎn)換(主要體現(xiàn)在圖象的緩存與變更上)。

    事實上是,如果我有完全AWT為基礎(chǔ)開發(fā)的一組控件,我想將其轉(zhuǎn)為Swing,需要做什么呢?很簡單,將所有awt包轉(zhuǎn)為swing包,并且加上j開頭就好,別無其他,因為Swing底層繼承自JComponent起便繼承自Container,而反之則是不可能的。

    從SWT完全摒棄Swing這種做法上,我們就已經(jīng)可以感知這種行為的意義何在,他為將來的擴(kuò)充和發(fā)展提供了堅實的基礎(chǔ)。

    本人開源項目:
    http://looframework.sourceforge.net/

    www.open-open.com

    雖然不是一個Java控件項目,但是原理上是非常類似的,完全以AWT開發(fā)。(或者說,近乎完全繪制的界面,不需要Swing。)

      回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-13 11:27 天若無情
    我要說的是,這類以繪制而非繼承Swing組件為主的應(yīng)用,完全可以采用AWT作為底層,這樣效率上會更高,而且算法更容易移植。  回復(fù)  更多評論
      
    # re: JButton大改造 2007-10-21 21:25 classic20082003@163.com
    樓主知道怎么樣把圖片變成控件么。比如說frame
    window 之類的!  回復(fù)  更多評論
      
    # re: JButton大改造 2007-12-17 18:14 lan
    有人編過計算器嗎  回復(fù)  更多評論
      
    # re: JButton大改造 2008-01-25 01:08 damagegod
    @天若無情
    非常不錯。呵呵。  回復(fù)  更多評論
      
    # re: JButton大改造 2008-07-24 12:41 法法
    樓主的文章很不錯,非常感謝。  回復(fù)  更多評論
      

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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲AV无码一区二区三区鸳鸯影院| 精品亚洲成a人片在线观看 | 日韩插啊免费视频在线观看| 亚洲AV永久无码精品一福利| 亚洲精品自在线拍| 亚洲精品国精品久久99热一| 全亚洲最新黄色特级网站 | 亚洲丁香婷婷综合久久| 亚洲欧洲中文日产| 亚洲电影国产一区| 亚洲欭美日韩颜射在线二| 免费a级毛片视频| 免费鲁丝片一级观看| 青娱分类视频精品免费2| 久久A级毛片免费观看| a毛片免费全部播放完整成| 一级毛片免费不卡| 老司机免费午夜精品视频| 亚洲国产精品日韩av不卡在线| 亚洲 欧洲 视频 伦小说| 亚洲国产美女精品久久久久| 91亚洲国产成人久久精品网站| 亚洲精品无码不卡在线播HE| 相泽亚洲一区中文字幕| 亚洲精品第一国产综合精品99| 国产无遮挡裸体免费视频 | 亚洲精品色在线网站| 亚洲成熟丰满熟妇高潮XXXXX| 精品亚洲AV无码一区二区三区| 亚洲高清无在码在线无弹窗| 2022年亚洲午夜一区二区福利 | 国产成人免费午夜在线观看| 一区二区三区观看免费中文视频在线播放| 国产精品成人69XXX免费视频| 一级毛片试看60分钟免费播放 | 亚洲精品无码AV人在线播放| 亚洲毛片αv无线播放一区| 国产国拍亚洲精品mv在线观看| 久久精品视频亚洲| 亚洲一级二级三级不卡| 亚洲一区二区中文|