1

So I have tried to turn my JLabel with an Image to a clickable button. But I ran into some problems.

Here's what I used:

Icon image = new ImageIcon("Image Path");
JLabel button = new JLabel(image);
button.setBounds(250, 100, 128, 64); //used a 500x200 window
frame.add(button);

button.addMouseListener(new MouseAdapter() {
      @Override
      public void mouseClicked(MouseEvent e) {
        System.out.print("Hello");
      }
    });

So when I run the code I can click anywhere and I always get the Hello message. But I only want the message to be printed out only when I click the image and not anywhere else.

How can I do this?

Thanks!

**Edit: Heres what I really mean:

enter image description here

As you can see, there should be a blue box saying Hello. and when I click it, I do get the message Hello but when I click outside the blue box(the white spots) I still get the message. Is there a way that I can disable that? So that when I only click the blue spot I get the message?**

Taslim Oseni
  • 6,086
  • 10
  • 44
  • 69
  • 5
    Curious...Why not just use a JButton? – DevilsHnd - 退職した Apr 11 '20 at 23:22
  • 1
    *But I only want the message to be printed out only when I click the image and not anywhere else.* - I have no idea what that means. If you are suggesting the label size is greater than the icon size, then your problem is the layout manager you are using. I see no reason for attempting to use a JLabel instead of a JButton. – camickr Apr 11 '20 at 23:40
  • 1
    *"I have tried to turn my JLabel with an Image to a clickable button."* It's easier to turn a button into something that *looks* like a label. [This code](https://stackoverflow.com/a/10862262/418556), for example, is made up of 5 labels (which don't act like buttons) and 4 buttons (which look like labels). Can you tell the difference between them? @camickr *"the label size is greater than the icon size"* A quick way to check. Add a visible border to the component. I generally use a red `LineBorder`. – Andrew Thompson Apr 11 '20 at 23:44
  • 2
    General tips: 1) For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). E.G. [This answer](https://stackoverflow.com/a/10862262/418556) hot links to an image embedded in [this question](https://stackoverflow.com/q/10861852/418556). 3) Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, .. – Andrew Thompson Apr 11 '20 at 23:47
  • 1
    .. they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). – Andrew Thompson Apr 11 '20 at 23:47
  • It's most likely because your JLabel is the same size as your JFrame. Use a Layout Manager to place your JLabel. For the heck of it try: `frame.getContentPane().setLayout(new FlowLayout());`. – DevilsHnd - 退職した Apr 11 '20 at 23:55
  • @Nightmarish Life, inspect the MouseEvent variable e, if it is fired by your component which is the JLabel button. –  Apr 12 '20 at 13:10

2 Answers2

1

You could just define a Rectangle, in whichs range a click on the JLabel should print your text. You can get the coordinates of your click relative to the JLabel with getX and getY. To check if the click is inside the rectangle you can use the method contains. See JLabel and Rectangle. A working example:

package labelbutton;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.*;

public class LabelButton {

    private static final Rectangle CLICK_FIELD = new Rectangle(140, 140, 200, 200);

    public static void main(String[] args) throws MalformedURLException {
        JFrame jf = new JFrame();
        jf.add(createLabelButton());
        jf.setVisible(true);
        jf.pack();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private static JLabel createLabelButton() throws MalformedURLException {
        Icon image = new ImageIcon(new URL("https://images.assetsdelivery.com/compings_v2/4zevar/4zevar1509/4zevar150900035.jpg"));
        JLabel button = new JLabel(image);
        button.setPreferredSize(new Dimension(500, 500));
        button.setBorder(BorderFactory.createLineBorder(Color.RED, 3));

        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(CLICK_FIELD.contains(e.getX(), e.getY())) {
                    System.out.println("Hello");
                }
            }
        });

        return button;
    }
}
Moritz Schmidt
  • 2,635
  • 3
  • 27
  • 51
0

You can also add the JLabel into a JPanel with GridBagLayout and then add the panel to the frame. This way, the JPanel is going to occupy the extra space, while the JLabel is going to always be centered in it.

Here's a working example:

import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main {
    public static void main(final String[] args) {
        SwingUtilities.invokeLater(() -> {

            final JLabel button = new JLabel("Hello");

            button.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(final MouseEvent mevt) {
                    System.out.println("Hello label/button!");
                }
            });

            button.setBorder(BorderFactory.createLineBorder(Color.CYAN.darker()));

            final JPanel panel = new JPanel(new GridBagLayout());

            panel.add(button);

            final JFrame frame = new JFrame("Label button");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(panel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
gthanop
  • 3,035
  • 2
  • 10
  • 27