3

I'm doing a project where i need some custom swing components. So far I have made a new button with a series of images (the Java Metal look doesn't fit with my UI at all). Ive implemented MouseListener on this new component and this is where my problem arises. My widget changes image on hover, click etc except my MouseListener picks up mouse entry into a the entire GridLayout container instead of into the image. So I have an image of about 200*100 and the surrounding container is about 400*200 and the mouseEntered method is fired when it enters that GridLayout section (even blank space parts of it) instead of over the image. How can I make it so that it is only fired when I hover over the image? Ive tried setting size and bounds and other attributes to no avail.

EDIT: Here's a demonstration of my issue. As you can see (sort of, colors are very similar) the bottom right button is highlighted just by entering its section of the GridlLayout. I only want it highlighted when I'm over the image actual, not the GridLayout section.

alt text

I Won't add the MouseListener methods because they just involve switching the displayed image.

public customWidget()
{
    this.setLayout(new FlowLayout());
    try {
        imageDef=ImageIO.read(new File("/home/x101/Desktop/buttonDef.png"));
        imageClick=ImageIO.read(new File("/home/x101/Desktop/buttonClick.png"));
        imageHover=ImageIO.read(new File("/home/x101/Desktop/buttonHover.png"));
        current=imageDef;
    } catch (IOException e) 
    {

        e.printStackTrace();
    }
    this.addMouseListener(this);
}

protected void paintComponent(Graphics g)
{
    super.paintComponents(g);
    g.drawImage(current, 0, 0, current.getWidth(), current.getHeight(), null);

}

EDIT: added code section

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Alex
  • 650
  • 9
  • 23
  • please post a self-contained code sample...makes it easier to see what you are trying to do...and easier to find the problem... – Steve McLeod Nov 13 '10 at 00:16
  • What is the superclass of 'customWidget'? Also, where does your 'GridLayout container' get set up? – robert_x44 Nov 13 '10 at 00:36
  • customWidget extends JComponent. The GridLayout is being set up in the test program im using to test the widget. Will put up an image to demonstrate. – Alex Nov 13 '10 at 00:43

3 Answers3

8

As an alternative, consider the The Button API, which includes the method setRolloverIcon() "to make the button display the specified icon when the cursor passes over it."

Addendum: For example,

import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ButtonIconTest {

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }

    private static void createAndShowGui() {
        String base = "http://download.oracle.com/"
            + "javase/tutorial/uiswing/examples/components/"
            + "RadioButtonDemoProject/src/components/images/";
        ImageIcon dog = null;
        ImageIcon pig = null;
        try {
            dog = new ImageIcon(new URL(base + "Dog.gif"));
            pig = new ImageIcon(new URL(base + "Pig.gif"));
        } catch (MalformedURLException ex) {
            ex.printStackTrace(System.err);
            return;
        }
        JFrame frame = new JFrame("Rollover Test");
        JPanel panel = new JPanel();
        panel.add(new JLabel(dog));
        panel.add(new JLabel(pig));

        JButton button = new JButton(dog);
        button.setRolloverIcon(pig);
        panel.add(button);

        frame.add(panel);

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
3

I assume your image contains ONLY 4 'customWidget' objects (in a 2x2 grid).

Your code is working as I would expect. Your MouseListener methods are responding to MouseEvents for 'customWidget' (not the image drawn in 'customWidget'), which is sized to take up 1/4 of the image, so they will respond when it enters the enlarged area. The error is actually in your Test program, because you are allowing the custom button widget to be larger than the image.

If you want a Test program that provides an image similar to yours, you should create a larger grid (say 4x4), and then only place your buttons in every other grid node. Place an empty component into the gaps.

robert_x44
  • 9,224
  • 1
  • 32
  • 37
  • You are exactly on my train of thought. is there a layout manager that would make it easy to set a section on the screen, say a bar of height 110, instead of all the proportional stuff that gridlayout and flowlayout do? – Alex Nov 13 '10 at 01:09
  • `BoxLayout` includes such invisible, filler components: http://download.oracle.com/javase/tutorial/uiswing/layout/box.html#filler – trashgod Nov 13 '10 at 01:21
  • Also, if you can use trashgod's method, I would HIGHLY recommend using the standard approach. :) – robert_x44 Nov 13 '10 at 01:24
  • [MiGLayout](http://www.miglayout.com/) can do everything (and no, that is no joke, so far I haven't come up with something that MiGLayout can't do. And my requirements are sometimes very fancy...)! – brimborium Jan 16 '13 at 17:10
0

Although I won't answer to your particular question, I hope this helps:

If the components just look wrong maybe you should reuse Swing components and just write a custom Look&Feel or theme.

It would certainly help ensuring the look of the application is consistent and at least you are using the right tool for the task you want to accomplish.

As a sidenote, be aware that Java comes with multiple Look&feels, including Look&Feels made to mimic the native OS theme.

See: http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html

luiscubal
  • 24,773
  • 9
  • 57
  • 83
  • Thats im aware of look and feel but its a team project and im working to someone else's design and theyve made it all shiney with glass look button ect. So this is the road ive decided to take. cheers anyway! – Alex Nov 13 '10 at 00:35