<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)

    隨筆檔案

    相冊

    我的兄弟們

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    嗯,BeanSoft的話很有道理,令我敬佩,也許是昨天在下對那個“更好的”三個字感到一時憤慨,所以看到UI就自己擴大了問題,想到迎合LookAndFeel上面去了,在此說句對不起了。你的回帖里面偏重于從整個組件的設計和重用性上,我的文章主要講的是如何將2D繪制和組件的繪制結合起來,看客如果既了解了如何繪制自己想要的組件,又能設計得體,重用性高的話也算是對我拋磚引玉的欣慰了。
    多話不說,接著昨天的,現在我們來試想一下做一個MP3的播放軟件上的幾個播放按鈕,“上一首”是左邊有圓頂角而右邊沒有的方形按鈕,“下一首”是右邊有圓頂角而左邊沒有的方形按鈕,而播放和暫停是一個圓形的按鈕,再放上一個五角星的按鈕來評分,現在我們來繪制他們(當然我們還有一個解決方案為每個Button換成圖片,每個Button得有三張:普通狀態,劃過,按下,不過這不是重點)。還是先放上圖片:


    和代碼:
    /**
     * @(#)RJButton.java  0.1.0  2007-9-11
     
    */
    package ruislan.rswing;

    import java.awt.AlphaComposite;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.GradientPaint;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.RenderingHints;
    import java.awt.Shape;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.geom.Arc2D;
    import java.awt.geom.GeneralPath;
    import java.awt.geom.RoundRectangle2D;

    import javax.swing.JButton;

    /**
     * Custom JButton
     * 
     * 
    @version 0.1.0
     * 
    @author ruislan <a href="mailto:z17520@126.com"/>
     
    */
    public class RButton extends JButton {
        
    private static final long serialVersionUID = 39082560987930759L;
        
    public static final Color BUTTON_COLOR1 = new Color(205255205);
        
    public static final Color BUTTON_COLOR2 = new Color(5115447);
        
    // public static final Color BUTTON_COLOR1 = new Color(125, 161, 237);
        
    // public static final Color BUTTON_COLOR2 = new Color(91, 118, 173);
        public static final Color BUTTON_FOREGROUND_COLOR = Color.WHITE;
        
    private boolean hover;
        
    private int style;
        
    public static final int ROUND_RECT = 0;
        
    public static final int LEFT_ROUND_RECT = 1;
        
    public static final int RIGHT_ROUND_RECT = 2;
        
    public static final int BALL = 3;
        
    public static final int STAR = 4;

        
    public RButton() {
            
    this(ROUND_RECT);
        }

        
    public RButton(int style) {
            
    this.style = style;
            
    if (BALL == style) {
                setPreferredSize(
    new Dimension(4242));
            } 
    else if (STAR == style) {
                setPreferredSize(
    new Dimension(4242));
            }
            setFont(
    new Font("system", Font.PLAIN, 12));
            setBorderPainted(
    false);
            setForeground(BUTTON_COLOR2);
            setFocusPainted(
    false);
            setContentAreaFilled(
    false);
            addMouseListener(
    new MouseAdapter() {
                @Override
                
    public void mouseEntered(MouseEvent e) {
                    setForeground(BUTTON_FOREGROUND_COLOR);
                    hover 
    = true;
                    repaint();
                }

                @Override
                
    public void mouseExited(MouseEvent e) {
                    setForeground(BUTTON_COLOR2);
                    hover 
    = false;
                    repaint();
                }
            });
        }

        @Override
        
    protected void paintComponent(Graphics g) {
            Graphics2D g2d 
    = (Graphics2D) g.create();
            
    int h = getHeight();
            
    int w = getWidth();
            
    float tran = 1F;
            
    if (!hover) {
                tran 
    = 0.3F;
            }

            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            GradientPaint p1;
            GradientPaint p2;
            
    if (getModel().isPressed()) {
                p1 
    = new GradientPaint(00new Color(000), 0, h - 1,
                        
    new Color(100100100));
                p2 
    = new GradientPaint(01new Color(00050), 0, h - 3,
                        
    new Color(255255255100));
            } 
    else {
                p1 
    = new GradientPaint(00new Color(100100100), 0, h - 1,
                        
    new Color(000));
                p2 
    = new GradientPaint(01new Color(255255255100), 0,
                        h 
    - 3new Color(00050));
            }
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                    tran));
            GradientPaint gp 
    = new GradientPaint(0.0F0.0F, BUTTON_COLOR1, 0.0F,
                    h, BUTTON_COLOR2, 
    true);
            g2d.setPaint(gp);
            
    switch (style) {
            
    case ROUND_RECT: {
                RoundRectangle2D.Float r2d 
    = new RoundRectangle2D.Float(00,
                        w 
    - 1, h - 12020);
                Shape clip 
    = g2d.getClip();
                g2d.clip(r2d);
                g2d.fillRect(
    00, w, h);
                g2d.setClip(clip);
                g2d.setPaint(p1);
                g2d.drawRoundRect(
    00, w - 1, h - 12020);
                g2d.setPaint(p2);
                g2d.drawRoundRect(
    11, w - 3, h - 31818);
                
    break;
            }
            
    case LEFT_ROUND_RECT: {
                RoundRectangle2D.Float r2d 
    = new RoundRectangle2D.Float(00,
                        (w 
    - 1+ 20, h - 12020);
                Shape clip 
    = g2d.getClip();
                g2d.clip(r2d);
                g2d.fillRect(
    00, w, h);
                g2d.setClip(clip);
                g2d.setPaint(p1);
                g2d.drawRoundRect(
    00, (w - 1+ 20, h - 12020);
                g2d.setPaint(p2);
                g2d.drawRoundRect(
    11, (w - 3+ 20, h - 31818);
                g2d.setPaint(p1);
                g2d.drawLine(w 
    - 11, w - 1, h);
                g2d.setPaint(p2);
                g2d.drawLine(w 
    - 22, w - 2, h - 1);
                
    break;
            }
            
    case RIGHT_ROUND_RECT: {
                RoundRectangle2D.Float r2d 
    = new RoundRectangle2D.Float(-200,
                        (w 
    - 1+ 20, h - 12020);
                Shape clip 
    = g2d.getClip();
                g2d.clip(r2d);
                g2d.fillRect(
    00, w, h);
                g2d.setClip(clip);
                g2d.setPaint(p1);
                g2d.drawRoundRect(
    -200, (w - 1+ 20, h - 12020);
                g2d.setPaint(p2);
                g2d.drawRoundRect(
    -191, (w - 3+ 20, h - 31818);
                g2d.setPaint(p1);
                g2d.drawLine(
    010, h);
                g2d.setPaint(p2);
                g2d.drawLine(
    121, h - 1);
                
    break;
            }
            
    case BALL: {
                Arc2D.Float a2d 
    = new Arc2D.Float(00, w, h, 0360, Arc2D.CHORD);
                Shape clip 
    = g2d.getClip();
                g2d.clip(a2d);
                g2d.fillRect(
    00, w, h);
                g2d.setClip(clip);
                g2d.setPaint(p1);
                g2d.drawOval(
    00, w - 1, h - 1);
                g2d.setPaint(p2);
                g2d.drawOval(
    11, w - 3, h - 3);
                
    break;
            }
            
    case STAR: {
                
    int x = w / 2;
                
    int y = h / 2;
                
    int r = w / 2;
                
    // 計算五個頂點
                Point[] ps = new Point[5];
                
    for (int i = 0; i <= 4; i++) {
                    ps[i] 
    = new Point((int) (x - r
                            
    * Math.sin((i * 72 + 36* 2 * Math.PI / 360)),
                            (
    int) (y + r
                                    
    * Math.cos((i * 72 + 36* 2 * Math.PI / 360)));
                }
                GeneralPath star 
    = new GeneralPath();
                star.moveTo(ps[
    3].x, ps[3].y);
                star.lineTo(ps[
    0].x, ps[0].y);
                star.lineTo(ps[
    2].x, ps[2].y);
                star.lineTo(ps[
    4].x, ps[4].y);
                star.lineTo(ps[
    1].x, ps[1].y);
                star.lineTo(ps[
    3].x, ps[3].y);
                star.closePath();
                Shape clip 
    = g2d.getClip();
                g2d.clip(star);
                g2d.fillRect(
    00, w, h);
                g2d.setClip(clip);
                g2d.setPaint(p1);
                g2d.draw(star);
                g2d.setPaint(p2);
                g2d.draw(star);
                
    break;
            }
            
    default:
                
    break;
            }
            g2d.dispose();
            
    super.paintComponent(g);
        }
    }

    這個代碼的其他地方我就不多說了,今天主要是講一下如何來clip內容,從而弄出我們想要的按鈕形狀(當然其他組件也可以)
    如圖所示,假設我們的按鈕是黑色的框,我們想要的是紅色的框,那么我們首先繪出我們想要的Shape,然后得到這個按鈕的Shape,然后進行合并剪裁,也就是說將兩個Shape合起來,然后交集部分留下,其余的去除,這樣就得到了我們所想要的圖形(五角星那個圖我們對五角星進行了封閉closePath)。

    圖示:


    我們還可以通過幾個Area進行合并圖形,反剪等等操作來勾勒我們想要的圖形,從而勾畫組件的圖形,如果你有閑情逸致的話,也有美感和足夠的素材的話可以寫一個StarCraft或者War3屏幕下角的操作區喲。

    posted on 2007-09-12 13:36 ruislan 閱讀(2440) 評論(11)  編輯  收藏

    FeedBack:
    # re: JButton大改造之二 - 五芒星之輝 2007-09-12 13:40 darkhe
    再頂。  回復  更多評論
      
    # re: JButton大改造之二 - 五芒星之輝 2007-09-12 15:20 交口稱贊
    不錯,還能寫出空心按鈕。  回復  更多評論
      
    # re: JButton大改造之二 - 五芒星之輝 2007-09-12 16:56 wqq
    版主:
    把測試代碼放出來吧。謝謝。  回復  更多評論
      
    # re: JButton大改造之二 - 五芒星之輝 2007-09-12 19:35 千里冰封
    太牛了,樓主,以后我會經常光顧你的blog
    你SWING研究的不錯哦  回復  更多評論
      
    # re: JButton大改造之二 - 五芒星之輝 2007-09-13 08:46 zht
    現在做Swing的很少了,贊一個
    順便問一下,工作就是做這個?  回復  更多評論
      
    # re: JButton大改造之二 - 五芒星之輝 2007-09-13 09:30 ruislan
    NO、NO、NO,我的工作是JavaEE,天天都伺候著Spring、Hibernate、SpringMVC、DWR……  回復  更多評論
      
    # re: JButton大改造之二 - 五芒星之輝 2007-09-13 09:34 zht
    @ruislan
    呵呵,我現在天天做,感覺越做選擇面越窄。。。  回復  更多評論
      
    # re: JButton大改造之二 - 五芒星之輝 2007-09-13 10:00 ruislan
    一般人天天都做了一個東西,即便是再喜歡久而久之也會產生審美疲勞,唉。
    例如Hibernate吧,第一次接觸它就喜歡上了ORM,那個時候還在上大學,然后天天就搗鼓這個,課也不上,興致高昂得連什么hbm文件,事務之類都是親歷親為,但是自從工作就是跟它打交道的不久之后,就開始用生成工具來生成hbm,然后不久之后開始用AppFuse了,就連hibernate那幾個CRUD操作長什么樣都不知道了。  回復  更多評論
      
    # re: JButton大改造之二 - 五芒星之輝 2007-10-22 16:41 Eastsun
    看了下樓主改造的JButton,效果確實不錯.
    不過還有個小小的缺陷:button顯示的形狀雖然變了,但其接受鼠標事件的范圍還是原來那個矩形框.
    譬如那個五角星button,理想的效果應該是鼠標放到五角星里面,button才會做出各種反應,但樓主的卻不是這樣.
    解決方法也很簡單,復寫父類的boolean contains(int x,int y)方法,在應該起效果的地方返回ture就可以了.  回復  更多評論
      
    # re: JButton大改造之二 - 五芒星之輝 2008-01-19 17:07 hanjs
    問個問題

    frame.setUndecorated(true);

    怎么增加frame的拖動和可變大小?

    我想實現千千靜聽那樣的3個窗口合在一起的  回復  更多評論
      
    # re: JButton大改造之二 - 五芒星之輝 2008-01-27 17:00 hanjs
    按鈕改完可以改變形狀?

    可改panel后,還需要怎么處理frame才能支持呢?

    我現在是改變panel的形狀后,如使用圓角矩形后(加到frame后),可是上面的兩個角顯示不了,下面的角可以顯示,但是圓角外默認是白色,不能實現理想的形狀!  回復  更多評論
      

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


    網站導航:
     
    主站蜘蛛池模板: 7x7x7x免费在线观看| 黄色网站软件app在线观看免费| 麻豆视频免费观看| 久久亚洲AV成人无码| 91免费在线播放| 亚洲一卡2卡4卡5卡6卡在线99| 99热在线精品免费播放6| 99久久亚洲精品无码毛片| 99精品视频免费在线观看| 亚洲成人免费电影| 男男AV纯肉无码免费播放无码| 亚洲一区二区三区乱码在线欧洲| 猫咪社区免费资源在线观看| 亚洲AV无码一区二区乱子仑| 亚洲国产精品一区二区三区久久 | 国产AV无码专区亚洲AV琪琪| 国产jizzjizz免费视频| 一区二区免费电影| 亚洲AV无码久久精品成人| 亚洲精品在线免费观看| 亚洲变态另类一区二区三区| 亚洲国产精品狼友中文久久久 | 日韩精品成人无码专区免费 | 久久精品夜色国产亚洲av| 四虎影视成人永久免费观看视频| 亚洲精品亚洲人成在线观看麻豆 | 美女视频黄.免费网址| 国产亚洲精品高清在线| 久久久久高潮毛片免费全部播放| 亚洲AV成人一区二区三区在线看| 免费jlzzjlzz在线播放视频| 日本高清高色视频免费| 一区二区亚洲精品精华液| 亚洲精品美女久久久久99小说| 久久精品无码精品免费专区| 国产精品亚洲片在线va| 亚洲性日韩精品国产一区二区| 免费A级毛片无码专区| 在线精品自拍亚洲第一区| 亚洲狠狠婷婷综合久久久久| 在线观看AV片永久免费|