2012-12-11 21 views
2

我有一個類延伸JButton,我試圖將.png圖像應用於。 圖像形狀不規則,周圍是透明像素。我已覆蓋JButton中的paintComponent()方法將我的緩衝圖像應用於按鈕。現在,圖像是唯一被繪製的,這是我想要的。JButton中不透明像素的事件檢測

但是,該按鈕仍然在檢測它周圍的矩形中的事件。有沒有辦法將檢測範圍限制爲只包含不透明像素的區域(或者,而不是檢測透明像素上的事件)?

按鈕類的代碼如下。

public class DrawButton extends JButton{ 

    private BufferedImage bi; 

    public DrawButton(BufferedImage bi){ 
     setPreferredSize(new Dimension(bi.getWidth(), bi.getHeight())); 
     this.bi = bi; 
    } 

    @Override 
    protected void paintComponent(Graphics g){ 
     g.drawImage(bi, 0, 0, null); 
     g.dispose(); 
    } 
} 
+0

@大衛在你的答案看着 - 我是否需要先調用'super.paintComponent()'?如果我這樣做,它會保留我不想要的原始按鈕背景。 – user18

回答

8

嗯,我會建議使用MouseAdapter,並覆蓋mouseClicked(..)。在mouseClicked檢查像素是否爲阿爾法在點擊時如果它什麼也不做,如果不做什麼。

  • 總是調用super.paintComponent(..)在被覆蓋的paintComponent方法首先調用,而是因爲,特別是按鈕,這將重繪上JButton實例JButton後臺調用setContentAreaFilled(false)來阻止這一切。你也可能想要setBorderPainted(false)

這裏是一個小例子,我做了(改編自here):

enter image description here

如果在笑臉點擊:

enter image description here

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.RenderingHints; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.image.BufferedImage; 
import java.net.URL; 
import javax.imageio.ImageIO; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.SwingUtilities; 

public class TransparentButton { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       final JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       MyButton button = null; 

       try { 
        button = new MyButton(scaleImage(100, 100, ImageIO.read(new URL("http://2.bp.blogspot.com/-eRryNji1gQU/UCIPw0tY5bI/AAAAAAAASt0/qAvERbom5N4/s1600/original_smiley_face.png")))); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 

       button.addMouseListener(new MouseAdapter() { 
        @Override 
        public void mouseClicked(MouseEvent me) { 
         super.mouseClicked(me); 
         MyButton mb = ((MyButton) me.getSource()); 
         if (!isAlpha(mb.getIconImage(), me.getX(), me.getY())) { 
          JOptionPane.showMessageDialog(frame, "You clicked the smiley"); 
         } 
        } 

        private boolean isAlpha(BufferedImage bufImg, int posX, int posY) { 
         int alpha = (bufImg.getRGB(posX, posY) >> 24) & 0xFF; 
         return alpha == 0; 
        } 
       }); 

       frame.add(button); 

       frame.pack(); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public static BufferedImage scaleImage(int w, int h, Image img) throws Exception { 
     BufferedImage bi; 
     bi = new BufferedImage(w, h, BufferedImage.TRANSLUCENT); 
     Graphics2D g2d = (Graphics2D) bi.createGraphics(); 
     g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)); 
     g2d.drawImage(img, 0, 0, w, h, null); 
     return bi; 
    } 
} 

class MyButton extends JButton { 

    BufferedImage icon; 

    MyButton(BufferedImage bi) { 
     this.icon = ((BufferedImage) bi); 
     setContentAreaFilled(false); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(icon.getWidth(), icon.getHeight()); 
    } 

    public BufferedImage getIconImage() { 
     return icon; 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawImage(icon, 0, 0, this); 
    } 
} 
+0

非常感謝!這工作完美(至少目前看來)!看起來你使用了我看過的其他問題的代碼([link](http://stackoverflow.com/questions/6735891/creating-custom-jbutton-from-images-containing-transparent-pixels)),但是我無法制造它的頭或尾。這個更完整的例子很有意義。 – user18

+0

@ user18 yup,只是調整了示例以遵循最佳實踐並將其實施爲工作SSCCE,以回答您的具體問題。 –

+0

@ user18請看看我的更新關於調用'paintComponent' –