JToolTip Demo

What Is It

This demo presents an alternative tooltip implementation for Swing apps.

This new model includes these changes:

This demo relates to tooltips, which are still managed by the ToolTipManager. See the JPopover demo for an alternative to tooltips.

How To Use It

Use this code to globally install these new tooltips for the current session:

static {
    QPopupFactory f = new QPopupFactory(PopupFactory.getSharedInstance());
    f.setToolTipCallout(true);
    PopupFactory.setSharedInstance(qPopupFactory);
}

If callouts are turned on, then by default the QPopupFactory decides where to position the tooltip/callout. You can override this for specific components by calling:

myComponent.putClientProperty(QPopup.PROPERTY_CALLOUT_TYPE,
    CalloutType.TOP_LEFT);

How It Works

Surprisingly the new tooltips presented here don't involve changing/extending the JToolTip or the ToolTipUI at all. We just need a new javax.swing.PopupFactory, and that manages the tooltip (popup) placement for us.

The popups are now QPopups, which include extra logic for the features stated above.

The ToolTipManager is still responsible for triggering the popups, including their timing.

Discussion

Tooltips often bug me a little. I don't quite understand the rules that control when (or where) they appear. And in Swing's defense: this isn't just a Swing problem. When I open Apple's Mail or Preview apps: those tooltips also feel a little erratic.

This new model helps stabilize their placement. Not only are they more predictable now, but they also don't partially obscure the component they're describing.

The callout triangles are a nice flourish, but maybe not strictly necessary. Really they exist more for the JPopover class; and once they existed it seemed simple enough to add them here for tooltips too.

The decision to embed tooltip in a JLayeredPane came mostly because of complaints about Apple's VoiceOver. Depending on the window type: VoiceOver will either announce "Java has new window" or "system dialog" every time a tooltip is shown in a separate window. However it does not read the tooltip itself. So embedding the tooltip inside the main window avoids that chatter. This will work great for sovereign windows that take up 50-100% of your monitor, but it's not a realistic solution for smaller transient windows. (This model is also largely inspired by many websites that manage their own tooltips.) If we can't comfortably fit the tooltip in the JLayeredPane: we revert back to the traditional default helper windows as necessary.

Accessibility

Everyone agrees tooltips should appear on mouseover. I've heard it argued also that tooltips should appear when a component receives the keyboard focus. Google's UI guidelines (see below) do this in webpages. I'd argue this is not necessary (or even good) for all desktop applications, but I'll quickly yield that argument to someone who actually provides a use case for that need.

In my experience: this same text presented in a tooltip is usually embedded in the AccessibleContext's description of the component. So if a visually impaired user isn't reading our tooltips: that's OK, because their assistive technologies are able to read the component's description. So they have two ways of accessing the same basic info.

Showing a tooltip when component receives the focus may be hard to do in Swing. The ToolTipManager was recently (in 2022) declared final, so I think (?) modifying its behavior may be tricky. It might be necessary to replace that model entirely.

Onboarding

One UX pattern that I've seen evolve over the last 20-ish years is using tooltips as an onboarding tool. The request usually resembles: "When users upgrade to version X of our software, can we show a special tooltip the first time they launch pointing to this new button?"

This is also hard to do within Swing's traditional ToolTipManager. Plus you'll probably need a helper class to keep track of what tooltip to show for a component. (That is: a JComponent only ever has one notion of what its official tooltip is. But now you might have the "traditional" tooltip, the "onboarding" tooltip, and maybe other context-sensitive tooltips.)

Also it can be tricky trying to decide how long to show on-boarding tooltips. If they go away as soon as you mouse over anything else with a tooltip: they may nearly instantly disappear. But if you use a timer: do you risk having multiple tooltips up at the same time? That could get weird, too.

Further Reading

We all have a good general understanding of what a tooltip is. But if we're going to a deep dive into the mechanics of a tooltip, then let's see what big UI actors have to say about them.

Microsoft

According to Microsoft:

A tooltip is a small pop-up window that labels the unlabeled control being pointed to, such as unlabeled toolbar controls or command buttons.

Because tooltips have proved so useful, a related control called infotips exists, which provides more descriptive text than is possible with tooltips.

An infotip is a small pop-up window that concisely describes the object being pointed to, such as descriptions of toolbar controls, icons, graphics, links, Windows Explorer objects, Start menu items, and taskbar buttons. Infotips are a form of progressive disclosure controls, eliminating the need always to have descriptive text on screen.

Tips help users understand unknown or unfamiliar objects that aren't described directly in the user interface (UI). They are displayed automatically when users hover the pointer over an object, and removed when users click the control or move the mouse, or when the tip times out.

Developers: There is no infotip control; infotips are implemented with the tooltip control. The distinction is in usage, not implementation.

This is pretty consistent/compatible with Swing's existing JToolTip model.

Microsoft also pushed the concept of a "screentip" for a while:

ScreenTips are small windows that display descriptive text when you rest the pointer on a command or control.

Enhanced ScreenTips are larger windows that display more descriptive text than a ScreenTip and can have a link to a Help article.

The "enhanced screentip" is a subtly different construct: it can include a link. That means you need to be able to click inside it. That means if you move the mouse away from the trigger component then the enhanced screentip has to stay visible (so you can click the link inside it). This is an important distinction.

Also it raises accessibility concerns: can you tab inside the enhanced screentip?

There's also a balloon:

A balloon is a small pop-up window that informs users of a non-critical problem or special condition in a control.

Balloons have an icon, a title, and body text, all of which are optional. Unlike tooltips and infotips, balloons also have a tail that identifies their source. Usually the source is a control if so, it is referred to as the owner control.

While balloons inform users of non-critical problems, they don't prevent problems although the owner control might. Any unhandled problems must be handled by the owner user interface (UI) when users attempt to commit to the action.

Balloons are usually used with text boxes, or controls that use text boxes for changing values, such as combo boxes, list views, and tree views. Other kinds of controls are sufficiently well constrained, and don't need the additional feedback balloons afford. Furthermore, if there is a problem with other types of controls, it often involves inconsistency between multiple controls a situation for which balloons aren't suitable. Only text-entry controls are both unconstrained and a common source of single-point errors.

(So what I call the "callout" they call the "tail". And what I call the "trigger" they call the "owner".)

These aren't usually interactable, but their dynamic nature raises questions about how to accessibly embed the information. (For example: if your myAxContext.getAccessibleDescription() is generally equivalent to the tooltip, then what is the AccessibleContext equivalent to a warning balloon?)

Google Material

Google says

Tooltips display informative text when users hover over, focus on, or tap an element.

A tooltip is displayed upon tapping and holding a screen element or component (on mobile) or hovering over it (desktop). Continuously display the tooltip as long as the user long-presses or hovers over the element.

If you set aside the "infotip", "screentip", etc.: the core defition of a "tooltip" here is very similar to Microsoft's definition.

One important distinction though is focus. When I tab through my Google drive webpage: tooltips appear for icon buttons. Off the top of my head I'm not sure how to achieve this in Swing, unless you create an alternative to the ToolTipManager.

Apple

Apple says:

A help tag (also called a tooltip) displays a small, transient view that briefly describes how to use a component in the interface. In apps that run on a Mac — including iPhone and iPad apps — help tags can appear after the pointer hovers briefly over an element.

Focus only on the control that’s directly beneath the pointer. When people want to know how to use a specific control, they don’t want to learn how to use nearby controls or how to perform a larger task.

Describe the action or task the control initiates. It often works well to begin the description with a verb — for example, “Restore default settings” or “Add or remove a language from the list.”

Be brief. As much as possible, limit tag content to a maximum of 60 to 75 characters (note that localization often changes the length of text). To make a description brief and direct, consider using a sentence fragment and omitting articles. If you need a lot of text to describe a control, consider simplifying your interface design.

In general, avoid naming or referring to the component. A help tag appears directly over the control, which usually provides sufficient context. Avoid defining a tag that does nothing but repeat the control’s title or label.

Consider offering context-sensitive help tags. For example, you could provide different text for a control’s different states.

There's not much new here, except perhaps some guidance on how to phrase the tooltip. This model also never includes anything you can click, and it doesn't involve keyboard focus. They do mention context-sensitivity, though. Again: that might require some extra consideration when it comes to AccessibleContexts.

But they offer something else, too: popovers.

A popover is a transient view that appears above other content onscreen when people click or tap a control or interactive area.

Use a popover to expose a small amount of information or functionality. Because a popover disappears after people interact with it, limit the amount of functionality in the popover to a few related tasks. For example, a calendar event popover makes it easy for people to change the date or time of an event, or to move it to another calendar. The popover disappears after the change, letting people continue reviewing the events on their calendar.

Consider using popovers when you want more room for content. Views like sidebars and panels take up a lot of space. If you need content only temporarily, displaying it in a popover can help streamline your interface.

Position popovers appropriately onscreen. Make sure a popover’s arrow points as directly as possible to the element that revealed it. Ideally, a popover doesn’t cover the element that revealed it or any essential content people may need to see while using it.

Interestingly they urge us not to ever call a popover a "popover":

Avoid using the word popover in help documentation. Instead, refer to a specific task or selection. For example, instead of “Select the Show button at the bottom of the popover,” you might write “Select the Show button.”

Like the "enhanced screentips": these contain components you can click. I assume in at least some cases you can always tab through the popover's UI too. I would usually describe these as "floating helper windows" that are anchored to part of a bigger window.