parsecer
parsecer

Reputation: 5106

Round JButton with icon; gets clicked when not directly pointer at; setting cursor to HAND_CURSOR works on area outside the icon

So, I have JFrame with JPanel on it. JPanel has two JToggleButtons. Each button is displayed as an icon of a round button. When the cursor hovers above a button it is supposed to turn into a hand.

public class UserInterface extends JFrame  {
        int width;
        int height;

        JPanel panel;
        public static void main(String[] args)  {
                run();
        }
        public UserInterface()  {
                setup();
        }

        private void setup()  {
            width=800;
            height=600;

            panel=new UserInterfacePanel();
            add(panel);

            setSize(width, height);
            setLocationRelativeTo(null);
            setDefaultCloseOperation(EXIT_ON_CLOSE);
        }

        public static void run()  {
                UserInterface gui=new UserInterface();
                gui.setVisible(true);
        }
}   


class UserInterfacePanel extends JPanel {
            private JToggleButton startButton;
            private JToggleButton stopButton;

            public static void main(String[] args)  {

            }

            public UserInterfacePanel()  {
                setup();
            }

            private void setup()  {
                setLayout(new GridLayout(1,2));

                setupButtons();
                setupButtonsActions();
                add(startButton);
                add(stopButton);
            }

            private void setupButtons()  {

                    ImageIcon iconStartButton = new ImageIcon("C:\\Users\\parsecer\\Desktop\\imgs\\greenReleased.png");
                    ImageIcon iconStopButton=new ImageIcon("C:\\Users\\parsecer\\Desktop\\imgs\\redReleased.png");

                    startButton=new JToggleButton(iconStartButton);
                    stopButton=new JToggleButton(iconStopButton);

                    startButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
                    stopButton.setCursor(new Cursor(Cursor.HAND_CURSOR));

                    startButton.setHorizontalAlignment(JButton.CENTER);
                    stopButton.setHorizontalAlignment(JButton.CENTER);
                    startButton.setAlignmentX(CENTER_ALIGNMENT);
                    stopButton.setAlignmentX(CENTER_ALIGNMENT);
                    startButton.setAlignmentY(CENTER_ALIGNMENT);
                    stopButton.setAlignmentY(CENTER_ALIGNMENT);

                    setupButtonIcon(startButton);
                    setupButtonIcon(stopButton);

                    ImageIcon iconStartButtonPressed=new ImageIcon("C:\\Users\\parsecer\\Desktop\\imgs\\greenPressed.png");
                    startButton.setDisabledIcon(iconStartButton);
                    startButton.setPressedIcon(iconStartButtonPressed);
                    startButton.setSelectedIcon(iconStartButtonPressed);

                    ImageIcon iconStopButtonPressed=new ImageIcon("C:\\Users\\parsecer\\Desktop\\imgs\\redPressed.png");
                    stopButton.setDisabledIcon(iconStopButton);
                    stopButton.setPressedIcon(iconStopButtonPressed);
                    stopButton.setSelectedIcon(iconStopButtonPressed);

            }


             private void setupButtonIcon(JToggleButton button)  {
                   button.setBorder(BorderFactory.createEmptyBorder());
                   button.setBorderPainted(false);
                   button.setContentAreaFilled(false);
                   button.setFocusable(false);
                   button.setPreferredSize(new Dimension(80, 80));
                   button.setFocusPainted(false);
                   button.setOpaque(false);
            }
        }

The problem is, the cursor changes into a hand way beyond the icon itself. The same goes for clicking the button - the button get pressed wherever I click vertically - given it's in the same column as the button or when I get relatively close to it horizontally.

I suppose the first problem might be linked to button image, but the background is deleted. Can the second be linked to the GridLayout?

Upvotes: 0

Views: 81

Answers (1)

hairsplitter
hairsplitter

Reputation: 89

I would do something like this: Define the shape of your buttons, presumably a circle/ellipse. In your click- and motionlisteners check if the event occured inside of that shape. If so, do your thing.

Put into code it would go (for the motionlistener) like this:

Cursor handCursor = new Cursor(Cursor.HAND_CURSOR);
Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
// create your shape here
Shape shape = new Ellipse2D.Float(0, 0, 30, 30);
MouseMotionAdapter motionListener = new MouseMotionAdapter() {
        @Override
        public void mouseMoved(MouseEvent e) {
            super.mouseMoved(e); 
            JToggleButton src = (JToggleButton) e.getSource();
            if (shape.contains(e.getPoint())) {
                src.setCursor(handCursor);
            } else {
                src.setCursor(normalCursor);
            }
        }
    };
startButton.addMouseMotionListener(motionListener);
stopButton.addMouseMotionListener(motionListener);

Upvotes: 1

Related Questions