dynamic tool tip text

J

Jim Janney

In Eclipse when you display a tool tip you get a different message if
the control or shift keys are pressed. I'm trying to do the same
thing in a Swing program. My first try was to subclass JTextField
and override getToolTipText(MouseEvent), something like this:

public class CustomTextField extends JTextField {
// usual constructors

@Override
public String getToolTipText(MouseEvent event) {
String result;
if (event.isControlDown() && getAlternateText() != null) {
result = getAlternateText();
} else {
result = super.getToolTipText(event);
}
return result;
}

public String getAlternateText() {
return "get your alternate text here";
}
}

This works for text fields but it's hard to extend it to other kinds
of components. If you have a non-editable combo box the class that
receives the method call is some subclass of JButton, for example
com.jgoodies.looks.plastic.PlasticComboBoxButton: exactly which
one you get depends on the look and feel.

I'm wondering if this is the wrong approach and I should be doing
something with a MouseListener instead. Has anyone else done anything
like this?
 
K

Knute Johnson

In Eclipse when you display a tool tip you get a different message if
the control or shift keys are pressed. I'm trying to do the same
thing in a Swing program. My first try was to subclass JTextField
and override getToolTipText(MouseEvent), something like this:

public class CustomTextField extends JTextField {
// usual constructors

@Override
public String getToolTipText(MouseEvent event) {
String result;
if (event.isControlDown()&& getAlternateText() != null) {
result = getAlternateText();
} else {
result = super.getToolTipText(event);
}
return result;
}

public String getAlternateText() {
return "get your alternate text here";
}
}

This works for text fields but it's hard to extend it to other kinds
of components. If you have a non-editable combo box the class that
receives the method call is some subclass of JButton, for example
com.jgoodies.looks.plastic.PlasticComboBoxButton: exactly which
one you get depends on the look and feel.

I'm wondering if this is the wrong approach and I should be doing
something with a MouseListener instead. Has anyone else done anything
like this?

I tried it with a MouseListener and it works fine.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JPanel {
private boolean alt;

public test() {
super(new GridBagLayout());

setPreferredSize(new Dimension(400,300));

JButton b = new JButton("Press Me");
b.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");

}
});
add(b);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test t = new test();
f.add(t);
f.pack();
f.setVisible(true);
}
});
}
}
 
J

Jim Janney

Knute Johnson said:
In Eclipse when you display a tool tip you get a different message if
the control or shift keys are pressed. I'm trying to do the same
thing in a Swing program. My first try was to subclass JTextField
and override getToolTipText(MouseEvent), something like this:

public class CustomTextField extends JTextField {
// usual constructors

@Override
public String getToolTipText(MouseEvent event) {
String result;
if (event.isControlDown()&& getAlternateText() != null) {
result = getAlternateText();
} else {
result = super.getToolTipText(event);
}
return result;
}

public String getAlternateText() {
return "get your alternate text here";
}
}

This works for text fields but it's hard to extend it to other kinds
of components. If you have a non-editable combo box the class that
receives the method call is some subclass of JButton, for example
com.jgoodies.looks.plastic.PlasticComboBoxButton: exactly which
one you get depends on the look and feel.

I'm wondering if this is the wrong approach and I should be doing
something with a MouseListener instead. Has anyone else done anything
like this?

I tried it with a MouseListener and it works fine.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JPanel {
private boolean alt;

public test() {
super(new GridBagLayout());

setPreferredSize(new Dimension(400,300));

JButton b = new JButton("Press Me");
b.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");

}
});
add(b);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test t = new test();
f.add(t);
f.pack();
f.setVisible(true);
}
});
}
}

Thanks. That still doesn't work with a JComboBox, but that turns out
to be because nothing works with JComboBoxes, as is copiously
described in bug ID 4144505, where Sun says "yes we know, but we're
not going to fix it."

RANT If they're not going to fix this they should at least document
it. I read through the tutorial on how to use mouse listeners and
nowhere does it say "oh by the way, this doesn't work with combo
boxes, too bad for you." So I waste a day and a half rediscovering
what everyone else has known for ten years.

And yes, there are workarounds, I'm looking at them now. We let our
users change the L&F at runtime, so I need something that works with
that.
 
K

Knute Johnson

Thanks. That still doesn't work with a JComboBox, but that turns out
to be because nothing works with JComboBoxes, as is copiously
described in bug ID 4144505, where Sun says "yes we know, but we're
not going to fix it."

Sure it does.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JPanel {
String[] items = {"One","Two","Three","Four","Five"};

public test() {
super(new GridBagLayout());

setPreferredSize(new Dimension(400,300));

JComboBox b = new JComboBox(items);
b.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");

}
});
add(b);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test t = new test();
f.add(t);
f.pack();
f.setVisible(true);
}
});
}
}
 
K

Knute Johnson

Thanks. That still doesn't work with a JComboBox, but that turns out
to be because nothing works with JComboBoxes, as is copiously
described in bug ID 4144505, where Sun says "yes we know, but we're
not going to fix it."

Sure it does.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JPanel {
String[] items = {"One","Two","Three","Four","Five"};

public test() {
super(new GridBagLayout());

setPreferredSize(new Dimension(400,300));

JComboBox b = new JComboBox(items);
b.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");

}
});
add(b);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test t = new test();
f.add(t);
f.pack();
f.setVisible(true);
}
});
}
}
 
J

Jim Janney

Knute Johnson said:
From: Knute Johnson <[email protected]>
Subject: Re: dynamic tool tip text
Newsgroups: comp.lang.java.programmer
Date: Thu, 18 Mar 2010 10:16:51 -0700
Organization: NewsDemon

Thanks. That still doesn't work with a JComboBox, but that turns out
to be because nothing works with JComboBoxes, as is copiously
described in bug ID 4144505, where Sun says "yes we know, but we're
not going to fix it."

Sure it does.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JPanel {
String[] items = {"One","Two","Three","Four","Five"};

public test() {
super(new GridBagLayout());

setPreferredSize(new Dimension(400,300));

JComboBox b = new JComboBox(items);
b.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");

}
});
add(b);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test t = new test();
f.add(t);
f.pack();
f.setVisible(true);
}
});
}
}

More precisely, it works on the editor but not on the button.

To be somewhat less unfair to Sun, I did find some discussion of this at

http://java.sun.com/docs/books/tutorial/uiswing/components/combobox.html#listeners
 
J

John B. Matthews

Knute Johnson said:
Sure it does.

[compelling example elided]

It works well with Metal, Motif & Nimbus, but not the Mac OS UI
delegate, com.apple.laf.AquaComboBoxUI.
 
K

Knute Johnson

Knute Johnson said:
Sure it does.

[compelling example elided]

It works well with Metal, Motif& Nimbus, but not the Mac OS UI
delegate, com.apple.laf.AquaComboBoxUI.

Is that the default for Mac? Do tool tips work at all on Mac?

Thanks,
 
K

Knute Johnson

Knute Johnson said:
From: Knute Johnson<[email protected]>
Subject: Re: dynamic tool tip text
Newsgroups: comp.lang.java.programmer
Date: Thu, 18 Mar 2010 10:16:51 -0700
Organization: NewsDemon

Thanks. That still doesn't work with a JComboBox, but that turns out
to be because nothing works with JComboBoxes, as is copiously
described in bug ID 4144505, where Sun says "yes we know, but we're
not going to fix it."

Sure it does.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JPanel {
String[] items = {"One","Two","Three","Four","Five"};

public test() {
super(new GridBagLayout());

setPreferredSize(new Dimension(400,300));

JComboBox b = new JComboBox(items);
b.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");

}
});
add(b);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test t = new test();
f.add(t);
f.pack();
f.setVisible(true);
}
});
}
}

More precisely, it works on the editor but not on the button.

To be somewhat less unfair to Sun, I did find some discussion of this at

http://java.sun.com/docs/books/tutorial/uiswing/components/combobox.html#listeners

I tried this on Windows with 1.6.0_18. It works on both the box and the
arrow button. What OS and Java are you running?
 
J

Jim Janney

Knute Johnson said:
Knute Johnson said:
From: Knute Johnson<[email protected]>
Subject: Re: dynamic tool tip text
Newsgroups: comp.lang.java.programmer
Date: Thu, 18 Mar 2010 10:16:51 -0700
Organization: NewsDemon

On 3/18/2010 9:32 AM, Jim Janney wrote:
Thanks. That still doesn't work with a JComboBox, but that turns out
to be because nothing works with JComboBoxes, as is copiously
described in bug ID 4144505, where Sun says "yes we know, but we're
not going to fix it."

Sure it does.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JPanel {
String[] items = {"One","Two","Three","Four","Five"};

public test() {
super(new GridBagLayout());

setPreferredSize(new Dimension(400,300));

JComboBox b = new JComboBox(items);
b.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");

}
});
add(b);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test t = new test();
f.add(t);
f.pack();
f.setVisible(true);
}
});
}
}

More precisely, it works on the editor but not on the button.

To be somewhat less unfair to Sun, I did find some discussion of this at

http://java.sun.com/docs/books/tutorial/uiswing/components/combobox.html#listeners

I tried this on Windows with 1.6.0_18. It works on both the box and
the arrow button. What OS and Java are you running?

Windows, java 1.6.something (I'm at home now, not at work). Try this:
Press the alt key and move the mouse into the box. The tooltip will
show "Alt is pressed". Now move the mouse back into the panel. With
the alt key released, move it into the arrow button. On my system the
tooltip shows "Alt is pressed", because there is no mouse listener on
on the arrow button. If you run this in a debugger you can also try
setting a breakpoint in the mouseEntered method.
 
J

John B. Matthews

Knute Johnson said:
Knute Johnson said:
On 3/18/2010 9:32 AM, Jim Janney wrote:
Thanks. That still doesn't work with a JComboBox, but that turns
out to be because nothing works with JComboBoxes, as is copiously
described in bug ID 4144505, where Sun says "yes we know, but
we're not going to fix it."
...
We let our users change the L&F at runtime, so I need something
that works with that.

Sure it does.

[compelling example elided]

It works well with Metal, Motif& Nimbus, but not the Mac OS UI
delegate, com.apple.laf.AquaComboBoxUI.

Is that the default for Mac?

com.apple.laf.AquaComboBoxUI is the UI delegate for JComboBox in
com.apple.laf.AquaLookAndFeel, the default Mac system L&F.
Do tool tips work at all on Mac?

Yes. In fact, setting the L&F to any other available value allows your
example to run correctly on Mac OS X.
 
J

Jim Janney

Jim Janney said:
Knute Johnson said:
From: Knute Johnson<[email protected]>
Subject: Re: dynamic tool tip text
Newsgroups: comp.lang.java.programmer
Date: Thu, 18 Mar 2010 10:16:51 -0700
Organization: NewsDemon

On 3/18/2010 9:32 AM, Jim Janney wrote:
Thanks. That still doesn't work with a JComboBox, but that turns out
to be because nothing works with JComboBoxes, as is copiously
described in bug ID 4144505, where Sun says "yes we know, but we're
not going to fix it."

Sure it does.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JPanel {
String[] items = {"One","Two","Three","Four","Five"};

public test() {
super(new GridBagLayout());

setPreferredSize(new Dimension(400,300));

JComboBox b = new JComboBox(items);
b.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");

}
});
add(b);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test t = new test();
f.add(t);
f.pack();
f.setVisible(true);
}
});
}
}

More precisely, it works on the editor but not on the button.

To be somewhat less unfair to Sun, I did find some discussion of this at

http://java.sun.com/docs/books/tutorial/uiswing/components/combobox.html#listeners

I tried this on Windows with 1.6.0_18. It works on both the box and
the arrow button. What OS and Java are you running?

Windows, java 1.6.something (I'm at home now, not at work). Try this:
Press the alt key and move the mouse into the box. The tooltip will
show "Alt is pressed". Now move the mouse back into the panel. With
the alt key released, move it into the arrow button. On my system the
tooltip shows "Alt is pressed", because there is no mouse listener on
on the arrow button. If you run this in a debugger you can also try
setting a breakpoint in the mouseEntered method.

The following code makes it work correctly in the L&Fs I've tried it with

JComboBox b = new JComboBox(items);
final MouseListener tooltipListener = new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");
}
};
b.addMouseListener(tooltipListener);
for (Component c : b.getComponents()) {
if (c instanceof JComponent) {
c.addMouseListener(tooltipListener);
}
}
b.addContainerListener(new ContainerAdapter() {
@Override
public void componentAdded(ContainerEvent event) {
if (event.getChild() instanceof JComponent) {
event.getChild().addMouseListener(tooltipListener);
}
}
});
add(b);


The ContainerListener is only needed if you change the L&F
dynamically: it adds the tooltip listener to the new UI components.
 
K

Knute Johnson

Knute Johnson said:
From: Knute Johnson<[email protected]>
Subject: Re: dynamic tool tip text
Newsgroups: comp.lang.java.programmer
Date: Thu, 18 Mar 2010 10:16:51 -0700
Organization: NewsDemon

On 3/18/2010 9:32 AM, Jim Janney wrote:
Thanks. That still doesn't work with a JComboBox, but that turns out
to be because nothing works with JComboBoxes, as is copiously
described in bug ID 4144505, where Sun says "yes we know, but we're
not going to fix it."

Sure it does.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class test extends JPanel {
String[] items = {"One","Two","Three","Four","Five"};

public test() {
super(new GridBagLayout());

setPreferredSize(new Dimension(400,300));

JComboBox b = new JComboBox(items);
b.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");

}
});
add(b);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
test t = new test();
f.add(t);
f.pack();
f.setVisible(true);
}
});
}
}

More precisely, it works on the editor but not on the button.

To be somewhat less unfair to Sun, I did find some discussion of this at

http://java.sun.com/docs/books/tutorial/uiswing/components/combobox.html#listeners

I tried this on Windows with 1.6.0_18. It works on both the box and
the arrow button. What OS and Java are you running?

Windows, java 1.6.something (I'm at home now, not at work). Try this:
Press the alt key and move the mouse into the box. The tooltip will
show "Alt is pressed". Now move the mouse back into the panel. With
the alt key released, move it into the arrow button. On my system the
tooltip shows "Alt is pressed", because there is no mouse listener on
on the arrow button. If you run this in a debugger you can also try
setting a breakpoint in the mouseEntered method.

Even weirder (or is that more weirdly) if you start the program and
mouse the mouse over the button, no tool tip. Move the mouse over the
label part, move it off and then back over the button part it shows a
tool tip. I think you are correct, it is generally hosed.
 
K

Knute Johnson

Knute Johnson said:
On 3/18/2010 9:32 AM, Jim Janney wrote:
Thanks. That still doesn't work with a JComboBox, but that turns
out to be because nothing works with JComboBoxes, as is copiously
described in bug ID 4144505, where Sun says "yes we know, but
we're not going to fix it."
...
We let our users change the L&F at runtime, so I need something
that works with that.

Sure it does.

[compelling example elided]

It works well with Metal, Motif& Nimbus, but not the Mac OS UI
delegate, com.apple.laf.AquaComboBoxUI.

Is that the default for Mac?

com.apple.laf.AquaComboBoxUI is the UI delegate for JComboBox in
com.apple.laf.AquaLookAndFeel, the default Mac system L&F.
Do tool tips work at all on Mac?

Yes. In fact, setting the L&F to any other available value allows your
example to run correctly on Mac OS X.

Thanks John.
 
J

John B. Matthews

Jim Janney said:
The following code makes it work correctly in the L&Fs I've tried it with

JComboBox b = new JComboBox(items);
final MouseListener tooltipListener = new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent me) {
JComponent c = (JComponent)me.getSource();
if (me.isAltDown())
c.setToolTipText("ALT is pressed");
else
c.setToolTipText("ALT isn't pressed!");
}
};
b.addMouseListener(tooltipListener);
for (Component c : b.getComponents()) {
if (c instanceof JComponent) {
c.addMouseListener(tooltipListener);
}
}
b.addContainerListener(new ContainerAdapter() {
@Override
public void componentAdded(ContainerEvent event) {
if (event.getChild() instanceof JComponent) {
event.getChild().addMouseListener(tooltipListener);
}
}
});
add(b);


The ContainerListener is only needed if you change the L&F
dynamically: it adds the tooltip listener to the new UI components.

Thank you for this followup; it works correctly on Mac OS X with all
supplied L&Fs.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top