Mouse over tooltips

What would be the best way to implement mouse over tooltips? I’ve never done something like this, but my first thought was to have a rectangle for each mouse over area and use a mouse listener to determine which rectangle the mouse was in. I have a feeling this isn’t the most efficient or easiest way to do it, but I’m not really sure how else to do it. Maybe use frames? I don’t even know where to start looking on how to make something like this.

Here’s what my UI looks like right now:

I would want to add mouse overs to each of the stats, inventory slots, equipment slots, HP/MP/XP bars. I would want the tooltip to have a border (probably just an image I would supply) and obviously some info on what your mouse is on.

Anyone have some examples of this? Or at least point me in the right direction? Thanks!

Check if the mouse hovers for a certain amount of time and display a rectangle with text in it? How else? :stuck_out_tongue:

The best way to deal with the draw order is to have a component that is on top of everything else, and it checks which component the mouse is hovering over and displays that component’s tooltip text. This is where OOP comes in:


public abstract class UIComponent {
    ....

    public abstract String getTooltipText();
}

All UI components extend that class and have a certain tooltip text set (returns null if no tooltip text to show).

I think I only have one component right now that has everything in it. All of the graphics are handled as one and displayed on one canvas. I don’t really know how to use your suggestion.

This is my first project, so the whole window and display functionality was copied from an example I found so I don’t really understand it fully or know how I would go about changing it. I guess a better question would be for a tutorial on basic UI implementation because it’s sounding like the way I did it isn’t the right way.

First, we have to theck, if the mouse is over the desired location (I made it a box…).



mouseX = mouseXPosition;
mouseY = mouseYPosition;

x = squareXPosition;
y = squareYPosition;

width = squareWidth;
height = squareHeight;

if (x >= mouseX && y >= mouseY && mouseX <= x + width && mouseY <= y + heigth) {

//show the tooltip here...

}


Then do what ra4king said… :slight_smile: EDIT: Also, you can put this code in a, method like checkIfOver(int mouseX, int mouseY);

Ok, that makes more sense. I thought there was a java class that he was talking about that I didn’t know about. I was kind of hoping there was because I wanted some prebuilt class to handle everything :stuck_out_tongue:

This is similar to what I was originally thinking needed to be done, except I was going to use the Rectangle class and use cointains(Point p) method to determine if the mouse is inside any of the areas. Would this run slower than the code you posted Peter?

No, there isnt any prebuilt class in the Java API to handle your problem. But about running slower, well, I think that the code I posted might run a bit faster (of course the code might contain some bugs) :slight_smile:

For java2D and swing/awt, I think you can use FocusListener (not absolutely sure, just popped up in my head)
Or just mouseEntered() and mouseExited() from MouseListener, which detects if the mouse has entered/exited whatever component you add the MouseListener to.

Efficiency? How many thousands of rectangles are you planning to do hit testing on?

So what you’re saying is it doesn’t matter right now?

lol, probably just 30-40 rectangles for the UI. For some reason efficiency is always on my mind when I’m programming. Just trying to build good habits for when I am doing a thousands of rectangles :slight_smile: It never hurts to start good practices early.

If you’re worried about it and plan on having a lot of rectangles all over the place, you implement a parent/child relationship like on most UIs. That way you check the top-level parents FIRST, and only if the mouse is in the parent’s area do you check the children. For example if you have 4 windows, you simply need to check the active window – and check ti make sure the mouse is actually inside the window (as apposed to checking every element on the screen),

No don’t do that. It might make the program slower depending on its data. If it ever gets to the point where the processing time spent on checking tool tips justifies spending time on it to improve it over some other aspect of your program, then you might want to try something else but probably not that method. Sometimes bruteforcing is faster because technology has changed; memory access time hasn’t kept up with processor speeds. (That’s why arrays are better than linked-lists and grids are better than spatial trees.)

If you absolutely had to improve on the efficiency test (for hit testing tons of in-game objects maybe) you would try something different. You would either share the rectangles with the GPU or other threads and attack the problem in parallel. Or you would develop a way to “instantly” determine which rectangle to jump to (similar to a random access collection or hash table). For example, you might look at that 3x4 grid and decide you store its strings in a 12 element array instead of 12 random objects.

int x = (mouseX - left) / cellWidth;
int y = (mouseY - top) / cellHeight;
if(x >= 0 && x < 4 && y >= 0 && y < 3) { toolTipText = texts[y * 4 + x]; }

However, you would only want to invest your personal time in doing this if you had a lot of rectangles. Less than a thousand? Probably not going to make a meaningful dent in your execution time.

And lets not forget, tool tips don’t pop up the instant your put your mouse over them, or else you would see a lot of flickering boxes on your screen while moving your mouse around. It’s not an aspect of a game that needs to be optimized and even if it were slow, then you could span the look up over several game updates if you absolutely had to. (In another low priority thread even.)

Well… I’m glad I only have 40 or so rectangles because I understood very little of what you said :stuck_out_tongue:

My game is going to be a simple one, so hopefully I can slowly work up to that kind of complexity. Some day though :smiley:

Good new is I’ve gotten tooltips working on a couple of elements already. I’ve made it so it picks the background box based on the number of lines in the text, but it still doesn’t look as good as I would like. Would there be a relatively easy way to make the box fit to the tooltip? Right now I just have the tooltip box as a sprite that is pulled like the rest of the graphics in the game and I have one for a tooltip with 1, 2, 3, 4, 5, or 6 lines. It chooses the right one based on the number of \n characters in the string. Is there a better way to do it? One that I’ll hopefully understand?

Why don’t you use the Swing components? They have an inbuilt tooltip functionaly and are highly customizable. I’m always a bit puzzled when I see people spending time to implement functions again that already come with the Java libraries.

That’s what I was asking, if there was anything that did tooltips already in java. Could you give me a real simple tooltip with swing? I don’t know where to start looking and I know there’s a lot of stuff that goes into swing programming. Or if you know of a good tutorial, let me know. Thanks

That would rely on your boxes being Swing components. (Each one of them floating in the middle of the screen.) You might be able to use one for the entire screen and update the text depending on where the mouse is, but you would still need to know which box the mouse is over.