Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9090753
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T22:26:56+00:00 2026-06-16T22:26:56+00:00

Event detection on opaque pixels in JButton Using the code example found in my

  • 0

Event detection on opaque pixels in JButton

Using the code example found in my question above, I have created several buttons with irregular edges that interlock, and am using a null layout in order to position the buttons properly. The issue I am encountering is that, although the mouse clicks are not being detected on transparent pixels in the bufferedimage, the button is still taking the shape of a rectangle. This means that buttons that are added to the panel later block portions of buttons they are adjacent to.

My question is: is there a way to force the mouse event to propagate down the entire physical arrangement of JButtons until it comes to one with opaque pixels, or is another solution required? I’ve looked at solutions involving Shape, but they seem very expensive, which is why I’m wondering about another way.

I’m not too attached to using JButtons, if the solution requires me to leave them, but I would like to find an inexpensive solution, if one exists.

import java.awt.Dimension;
import java.awt.Graphics;
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 JButtonExample {

    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 button1 = null, button2 = null;

                try {
                    button1 = new MyButton(ImageIO.read(new URL("https://dl.dropbox.com/s/dxbao8q0xeuzhgz/button1.png")));
                } catch (Exception ex) {
                    ex.printStackTrace();
                }

                button1.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 button 1");
                    }

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

                button1.setBounds(10, 10, 72, 77);

                try {
                    button2 = new MyButton(ImageIO.read(new URL("https://dl.dropbox.com/s/v16kyha0ojx1gza/button2.png")));
                } catch (Exception ex) {
                    ex.printStackTrace();
                }

                button2.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 button 2");
                    }

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

                button2.setBounds(65, 0, 122, 69);

                frame.getContentPane().setLayout(null);

                frame.add(button1);
                frame.add(button2);

                frame.setSize(210, 130);
                frame.setVisible(true);
            }
        });
    }
}

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, null);
        g.dispose();
    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T22:26:58+00:00Added an answer on June 16, 2026 at 10:26 pm

    Alright, I’ve worked out a solution that does what I want it to do with enough accuracy for my usage case. While some of the particulars might be a little hackish, I think I’ve got it doing what I want now. Code to create Area is adapted from here.

    For simplicity and ease of use in other areas of my larger program, I preserved each button as an independent JButton. When a mouse click is detected on any button, it calculates the position of the click as it appears on the parent panel, then passes that position as a Point to the parent. The parent then runs through the array of buttons until it finds a button that contains the point, and fires the appropriate method. If the click is not within the area contained by any button, there is no effect. If the original mouse click does not occur on the square area bounding a JButton, no processing occurs.

    Although the calculations required to produce an Area are relatively expensive compared to the rest of the program, I can deal with this by creating all the Area objects on startup, since it is a very rare case that the program will be started and every area will not be used.

    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.Point;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.geom.Area;
    import java.awt.geom.GeneralPath;
    import java.awt.image.BufferedImage;
    import java.net.URL;
    
    import javax.imageio.ImageIO;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.SwingUtilities;
    
    
    public class Example {
    
        private static int[][] pos = {{10, 10, 72, 77}, {65, 0, 122, 69}};
    
        public static MyButton[] buttons;
    
        private static URL[] src = new URL[2]; 
    
        private static MapPanel pane;
    
        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);
    
                    try{
                        src[0] = new URL("https://dl.dropbox.com/s/dxbao8q0xeuzhgz/button1.png");
                        src[1] = new URL("https://dl.dropbox.com/s/v16kyha0ojx1gza/button2.png");
                    } catch (Exception e){
                        e.printStackTrace();
                        System.exit(0);
                    }
    
                    pane = new MapPanel();
                    pane.setLayout(null);
    
                    buttons = new MyButton[2];
    
                    for(int i = 0 ; i < buttons.length ; i++){
                        final int j = i;
                        try{
                            buttons[j] = new MyButton((ImageIO.read(src[j])), j, pos[j][0], pos [j][1]);
                        } catch (Exception e){
                            e.printStackTrace();
                            System.exit(0);
                        }
                        buttons[j].addMouseListener(new MouseAdapter(){
                            @Override
                            public void mouseClicked(MouseEvent me){
                                Point p = new Point(me.getX() + buttons[j].getX(), me.getY() + buttons[j].getY());
                                pane.check(p);
                            }
                        });
                        buttons[j].setBounds(pos[j][0], pos[j][1], pos[j][2], pos[j][3]);
                        pane.add(buttons[j]);
                    }
    
                    frame.setContentPane(pane);
    
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setSize(210, 130);
                    frame.setVisible(true);
                }
            });
        }
    }
    
    class MapPanel extends JLabel{
    
        public MapPanel(){
            super();
            this.setOpaque(true);
        }
    
        public void check(Point p){
        for(int i = 0 ; i < Example.buttons.length ; i++){
        if(Example.buttons[i].contains(p)){
                Example.buttons[i].clickDetected();
                break;
            }
            }
        }
    }
    
    class MyButton extends JButton {
    
        private BufferedImage icon;
        private int x, y, index;
        private Area area;
    
        MyButton(BufferedImage bi, int index, int x, int y) {
            this.icon = ((BufferedImage) bi);
            this.x = x;
            this.y = y;
            this.index = index;
            setContentAreaFilled(false);
            createArea();
        }
    
        @Override
        public Dimension getPreferredSize() {
            if(icon != null){
                return new Dimension(icon.getWidth(), icon.getHeight());
            } else {
                return super.getPreferredSize();
                }
        }
    
        public BufferedImage getIconImage() {
            return icon;
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(icon, 0, 0, null);
            g.dispose();
        }
    
        private void createArea(){      
            GeneralPath gp = new GeneralPath();
            boolean cont = false;
    
            for(int xx = 0 ; xx < icon.getWidth() ; xx++){
                for(int yy = 0 ; yy < icon.getHeight() ; yy++){
                    if(getAlpha(xx, yy) != 0){
                        if(cont){
                            gp.lineTo(xx, yy);
                            gp.lineTo(xx, yy+1);
                            gp.lineTo(xx+1, yy+1);
                            gp.lineTo(xx+1, yy);
                            gp.lineTo(xx, yy);
                        } else{
                            gp.moveTo(xx, yy);
                        }
                        cont = true;
                    } else {
                        cont = false;
                    }
                }
                cont = false;
            }
    
            gp.closePath();
    
            area = new Area(gp);        
        }
    
        @Override
        public boolean contains(Point p){
            if(area.contains(new Point((int)(p.getX() - this.x), (int) (p.getY() - this.y)))){
                return true;
            }
            return false;
        }
    
        private int getAlpha(int posx, int posy){
            return(icon.getRGB(posx, posy) >> 24) & 0x000000FF;
        }
    
        public void clickDetected(){
            JOptionPane.showMessageDialog(null, "You clicked button " + Integer.toString(this.index + 1) + ".");
        }
    }
    

    I would also greatly appreciate if anyone could point out anything in this code (or outside of it) that is an issue. I assume that how the GeneralPath creates the area is by creating a 1px square on top of every pixel that meets the criteria (in this case, non-transparent pixels), and then creating an area object from the area contained by the path. Please correct me if I am wrong.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have problems with flag detection in PHP. <?php class event { const click
I would like to perform a key event detection in textbox. The keys should
I'm trying to get familiar with the whole keyboard event detection thing. Here's my
assumption: Event\Service\EventService is my personal object that works with Event\Entity\Event entities This code works
Some event handlers for the WinForm DataGridView have DataGridViewCellEventArgs as a parameter and a
What event is fired when Google Maps repaint itself? For example when you zoom
Is there any good reference to Algorithms that people use for rare event detection
Possible Duplicate: Event listener in Java without app having focus? (Global keypress detection) I
If I have these rules: width:50px; height:100px; -moz-transform: rotate(0deg) and then an event changes
i have questions regarding the shake detection that posted here before, here is a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.