定制形状的透明按钮

时间:2013-01-16 16:19:04

标签: java swing jbutton bufferedimage imageicon

我找到了两种不适合我的解决方案。第一个涉及透明度。第二个我更喜欢,因为它看起来更干净。目标是使用具有透明度的图像创建自定义形状的按钮。我想忽略透明部分,只在我点击图像的非透明部分时才采取行动。

第一个代码来自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);

以下是我尝试使用的代码,基于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

1 个答案:

答案 0 :(得分:4)

您需要覆盖contains(int,int)的{​​{1}}方法,才能使用第二种方法。现在困难的部分是弄清楚你是否在图像的相关部分。 在这种情况下,我假设完全透明的像素不相关,白色像素也不相关。由您决定选择不同的实现:

JButton