<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之旅也到了一個(gè)階段,已經(jīng)很不錯(cuò)了,現(xiàn)在我們來改造JButton,讓那個(gè)呆板的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 


    注意代碼中的幾個(gè)部分:

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

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

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

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

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

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

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

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

    FeedBack:
    # re: JButton大改造 2007-09-11 13:14 千里冰封
    不錯(cuò)不錯(cuò),寫得很好
    期待樓主更好的作品,有機(jī)會(huì)共同研究一下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的地址呢?
    或者在頁面上加個(gè)鏈接就更好了^_^  回復(fù)  更多評論
      
    # re: JButton大改造 2007-09-11 23:32 BeanSoft
    更好的方法是開發(fā)一個(gè) 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)去找一個(gè)L2fprod呢,JDK里面就有現(xiàn)成的Metal和windows等等LookAndFeel的范例。

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

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

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

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

    Swing 的 MVC 我不想贅述, 我想說的是要改外觀用 ButtonUI 會(huì)更方便一些而已, 不用對原來的界面邏輯代碼做太多改動(dòng). 剛才那個(gè)例子用法很簡單,
    button.setUI(new BlueishButtonUI()); 即可改變單個(gè)按鈕的外觀, 而 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 交口稱贊
    一個(gè)SWT死忠幸福的看著樓上一群人

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

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

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

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

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

    本人開源項(xiàng)目:
    http://looframework.sourceforge.net/

    www.open-open.com

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

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

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


    網(wǎng)站導(dǎo)航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 亚洲成aⅴ人片在线影院八| 亚洲成A∨人片天堂网无码| 女人被男人躁的女爽免费视频 | 丰满少妇作爱视频免费观看| 国产99精品一区二区三区免费 | 久久久久免费精品国产小说| 蜜桃AV无码免费看永久| 成人免费福利电影| 亚洲国产91精品无码专区| 亚洲国产精品无码一线岛国| 亚洲综合久久成人69| 亚洲欧洲日产国码久在线| 一区二区三区在线观看免费| 99在线免费观看视频| 精品国产免费一区二区| 中文字幕亚洲一区| 亚洲国产成a人v在线| 国产亚洲蜜芽精品久久| 久久成人a毛片免费观看网站| 蜜桃视频在线观看免费网址入口| 国产人妖ts在线观看免费视频| 一本色道久久综合亚洲精品| 亚洲伊人久久大香线蕉影院| 真正全免费视频a毛片| 久久99精品国产免费观看| 热99re久久免费视精品频软件| 国产亚洲精品AA片在线观看不加载| 亚洲综合激情九月婷婷| 黄网站色成年片大免费高清| 色欲色香天天天综合网站免费| 午夜视频免费成人| 亚洲AV综合色区无码一区爱AV| 中文字幕精品三区无码亚洲| 成人网站免费大全日韩国产| 无码国产精品久久一区免费| 亚洲毛片不卡av在线播放一区| 亚洲成人福利网站| 国产精品免费久久久久影院| 四虎永久在线精品免费网址 | 亚洲妇熟XXXX妇色黄| 亚洲国产精品自在自线观看|