2013-01-16 5 views
2

나에게 맞는 두 가지 솔루션이 있습니다. 첫 번째는 투명성을 다룹니다. 두 번째는 내가보기에 깨끗해 보이기 때문에 선호합니다. 목표는 투명성이있는 이미지를 사용하여 사용자 정의 모양의 단추를 만드는 것입니다. 투명 섹션을 무시하고 이미지의 불투명 한 부분을 클릭 할 때만 조치를 취하고 싶습니다.사용자 정의 모양의 투명 버튼

첫 번째 코드는 여기에서 http://java.macteki.com/2012/07/custom-shape-buttons.html입니다. 그런데 아래 코드에서 0x00ffffff의 요점은 무엇입니까?

//********** BEGIN OF IMAGE BUTTON CODE **************** 
     // The following is the actual code to create a image button 
     // you may use any transparent image file, just change "a.png" below 
     final BufferedImage image = ImageIO.read(new File("a.png")); 
     ImageIcon icon = new ImageIcon(image); 

     jLabel1 = new javax.swing.JLabel(icon); 
     jLabel1.addMouseListener(new MouseAdapter() 
     { 
     public void mouseClicked(MouseEvent e) 
     { 
     boolean transparent = (image.getRGB(e.getX(),e.getY()) & 0x00ffffff)!=0; 
    if (!transparent) { 
     // write your button handler here 
     System.out.println("button pressed"); 
     } else { 
     System.out.println("else"); 
     } 
     } 
     } 

    ); 
     //********** END OF IMAGE BUTTON CODE **************** 
     // add the button to the panel so that it becomes visible 

이것은 그의 테스트 이미지와 함께 작동하지만 어떤 광산에서도 작동하지 않습니다. 나는 그를 데려 가서 gimp에서 A의 색깔을 변경하고 a2.png로 내 보낸 다음 작동하지 않습니다. elseif (!transparent)이 트리거하지 않는 모든 영역을 등록합니다.

이 이미지는 작동합니다 This image works 이 이미지는 작동하지 않습니다 내가 선호 This image does not work

두 번째 코드는 여기 Creating a custom button in Java with JButton에서 온다. 이미지는 버튼에 적용되지만 투명 영역을 포함하여 상자의 아무 곳이나 클릭하면 클릭으로 등록됩니다. 비 투명 영역 (이 예에서는 A)을 클릭 할 때만 작동하기를 원합니다. 여기

BufferedImage startButton = ImageIO.read(new File("a2.png"));  
     jButton1 = new javax.swing.JButton(new ImageIcon(startButton)); 
     jButton1.setBorder(BorderFactory.createEmptyBorder()); 
     jButton1.setContentAreaFilled(false); 
     jButton1.setFocusable(false); 

내가 당신이 작동하는 두 번째 방법에 대한 방법을 JButtoncontains(int,int)를 오버라이드 (override) 할 필요가 Guillame

private void initComponents() throws IOException { 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     final BufferedImage image = ImageIO.read(getClass().getResource("/images/a.png")); 
     jButton1 = new JButton(new ImageIcon(image)) { 
      @Override 
      public boolean contains(int x, int y) { 
       Rectangle viewRect = getBounds(); 
       Insets insets = getInsets(); 
       viewRect.x += insets.left; 
       viewRect.y += insets.top; 
       viewRect.width -= insets.left + insets.right; 
       viewRect.height -= insets.top + insets.bottom; 
       Rectangle iconR = new Rectangle(); 
       SwingUtilities.layoutCompoundLabel(this, this.getFontMetrics(this.getFont()), this.getText(), this.getIcon(), 
         this.getVerticalAlignment(), this.getHorizontalAlignment(), this.getVerticalTextPosition(), 
         this.getHorizontalTextPosition(), viewRect, iconR, new Rectangle(), this.getIconTextGap()); 
       if (!iconR.contains(x, y)) { 
        return false; 
       } 
       x -= iconR.x; 
       y -= iconR.y; 
       Color c = new Color(image.getRGB(x, y), true); 
       return c.getAlpha() != 0 && (c.getRed() < 255 || c.getGreen() < 255 || c.getBlue() < 255); 
      } 
     }; 

     jButton1.setContentAreaFilled(false); 
     jButton1.setFocusPainted(false);    
     jButton1.setRolloverEnabled(false);  
     jButton1.setBorderPainted(false); 

     jButton1.addActionListener(new java.awt.event.ActionListener() { 
      public void actionPerformed(java.awt.event.ActionEvent evt) { 
       jButton1ActionPerformed(evt); 
      } 
     }); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addGap(72, 72, 72) 
       .addComponent(jButton1) 
       .addContainerGap(255, Short.MAX_VALUE)) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 
       .addContainerGap(193, Short.MAX_VALUE) 
       .addComponent(jButton1) 
       .addGap(84, 84, 84)) 
     ); 

     pack(); 
    }// </editor-fold>//GEN-END:initComponents 
+0

가능한 중복 http://stackoverflow.com/questions/13825123/event-detection-on-opaque-pixels- : 당신까지 다른 구현을 선택합니다 in-jbutton) –

답변

4

에서의 예에 따라 사용할 노력하고 코드입니다. 이제 어려운 부분은 당신이 이미지의 관련 부분에 있는지 아닌지를 알아내는 것입니다. 이 경우 나는 완전히 투명한 픽셀이 관련이 없으며 흰색 픽셀도 관련이 없다고 가정했습니다.

import java.awt.Color; 
import java.awt.Insets; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.SwingUtilities; 

public class TestTransparentButton { 

    protected void createAndShowGUI() throws MalformedURLException, IOException { 
     JFrame frame = new JFrame("Test button"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     final BufferedImage image = ImageIO.read(new URL("http://i.stack.imgur.com/7D547.png")); 
     final JButton button = new JButton(new ImageIcon(image)) { 
      @Override 
      public boolean contains(int x, int y) { 
       Rectangle viewRect = getBounds(); 
       Insets insets = getInsets(); 
       viewRect.x = insets.left; 
       viewRect.y = insets.top; 
       viewRect.width -= insets.left + insets.right; 
       viewRect.height -= insets.top + insets.bottom; 
       Rectangle iconR = new Rectangle(); 
       SwingUtilities.layoutCompoundLabel(this, this.getFontMetrics(this.getFont()), this.getText(), this.getIcon(), 
         this.getVerticalAlignment(), this.getHorizontalAlignment(), this.getVerticalTextPosition(), 
         this.getHorizontalTextPosition(), viewRect, iconR, new Rectangle(), this.getIconTextGap()); 
       if (!iconR.contains(x, y)) { 
        return false; 
       } 
       x -= iconR.x; 
       y -= iconR.y; 
       Color c = new Color(image.getRGB(x, y), true); 
       return c.getAlpha() != 0 && (c.getRed() < 255 || c.getGreen() < 255 || c.getBlue() < 255); 
      } 
     }; 
     button.setContentAreaFilled(false); 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       JOptionPane.showMessageDialog(button, "You clicked on the button"); 
      } 
     }); 
     frame.add(button); 
     frame.setSize(200, 200); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        new TestTransparentButton().createAndShowGUI(); 
       } catch (MalformedURLException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }); 

    } 

} 
[JButton의 불투명 픽셀의 이벤트 감지 (의
+0

하, 당신은 정말 멋져요! – user1753429

+0

getContentPane()을 사용할 때 이것이 왜 멈추는 지 말해 줄 수 있습니까?. setLayout (null); 및 getContentPane(). add (jButton1); jbutton1은 버튼 – user1753429

+0

@ user1753429를 바꿨습니다. 왜냐하면 당신은'jbutton1'에 경계를 설정하지 않았을 것입니다. 어쨌든 null 레이아웃을 거의 사용하지 않아야하므로 이러한 종류의 문제가 발생하지 않아야합니다. –