2

私にはうまくいかない2つの異なる解決策を見つけました。最初のものは透明性を扱います。見た目がすっきりしているので、私が好む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にエクスポートしましたが、機能しません。すべての領域をトリガーとして登録し、トリガーすることはelseありif (!transparent)ません。

この画像は機能します: この画像は機能します この画像は機能しません: この画像は機能しません

私が好む2番目のコードは、ここから来ています。JButtonを使用してJavaでカスタムボタンを作成します。画像はボタンに適用されますが、透明な領域を含むボックス内の任意の場所をクリックすると、クリックとして登録されます。不透明な領域(またはこの例では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);

これがギラームの例に基づいて使用しようとしているコードです

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
4

1 に答える 1

4

contains(int,int)2 番目のメソッドを機能させるには、メソッドをオーバーライドする必要がありますJButton。ここで難しいのは、画像の関連部分にいるかどうかを判断することです。この場合、完全に透明なピクセルは関係なく、白いピクセルも関係ないと仮定しました。別の実装を選択するのはあなた次第です:

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();
                }
            }
        });

    }

}
于 2013-01-16T16:50:26.413 に答える