Skip to main content

Does JLabel has a html text preferred size problem?

10 replies [Last post]
i30817
Offline
Joined: 2006-05-02
Points: 0

Specifically with a \ in the html sometimes i see the line after missing, if the first line was long enough to overflow (only sometimes? unexpected?) being word breaked. So the line after that poor \n dissapears. I will try to make a test case, but you know how it is with test cases for platform graphics bugs. I'm posting this in the hope someone has a clue (subclassing the JTooltipUI is not acceptable).

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
i30817
Offline
Joined: 2006-05-02
Points: 0

The "fix" actually doesn't work. Anyone can figure out what is the problem?

walterln
Offline
Joined: 2007-04-17
Points: 0

I cannot reproduce it if I take out the random (which might be the problem) from your test case.

[code]import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class TestHTMLToolTip {
private static final String smallTip = "

small tip

0.00%

";
private static final String largeTip = "

larrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrgeeeeeeee BUGGG

0.00%

";

private static class OverrideButton extends JButton {
private boolean large;

public OverrideButton(String text) {
super(text);

ToolTipManager.sharedInstance().registerComponent(this);
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
large = !large;
}
});
}

@Override
public String getToolTipText() {
if(large) {
return largeTip;
}
else {
return smallTip;
}
}

@Override
public JToolTip createToolTip() {
JToolTip tip = new JToolTip() {
@Override
public String getTipText() {
return OverrideButton.this.getToolTipText();
}
};

return tip;
}
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
final JButton button = new JButton("Press to change to large tooltip");
final JButton override = new OverrideButton("Press to change to large tooltip");

button.setToolTipText(smallTip);
button.addActionListener(new ActionListener() {
private boolean large;
public void actionPerformed(ActionEvent e) {
if(large) {
button.setToolTipText(smallTip);

}
else {
button.setToolTipText(largeTip);
}
large = !large;
}
});

JPanel panel = new JPanel();
panel.add(button);
panel.add(override);

JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
[/code]

i30817
Offline
Joined: 2006-05-02
Points: 0

The main reason i used random was to change the tooltip rapidly.

There might be a race condition on changing the expected tooltip on tooltip text request and not before requesting painting of the tooltip.

Even with the original testcase the error appears to be that the preferred size is cached on the first invocation (on that specific place) and never changed. If the preffered size is the one of the larger tooltip, all is well, though i would prefer the correct size otherwise...) I'm going to play with your example.-

i30817
Offline
Joined: 2006-05-02
Points: 0

An aside - i'm not being able to reproduce this with the original test case in a recent ubuntu installation with jdk 7 however it still occasionally happens in windows on java 6, Probably the culprit is the JTooltipUI on windows?

So i can't see your testcase now. Later today when i have access to a windows machine.

i30817
Offline
Joined: 2006-05-02
Points: 0

Yep managed to reproduce with your test on first try after displaying once the small tooltip, changing to large tooltip and wait to display that. Are you not on windows? I couldn't reproduce either on ubuntu.

i30817
Offline
Joined: 2006-05-02
Points: 0

Even with your test case it doesn't happen always :( .

Eventually though - without having to retry.
Strange bug. It can't be a thread race since both the code, TooltipManager and TooltipUI operate on the EDT. It almost seems like there is a [i]real[/i] source of randomness somewhere that causes this to appear only sometimes.

Edit: here are some images showing the defect:
Normal image in your testcase:
http://img510.imageshack.us/img510/1903/normalz.png
Abnormal image:
http://img94.imageshack.us/img94/2682/bugged.png
Message was edited by: i30817

leo_test
Offline
Joined: 2004-04-27
Points: 0

Hm' I don't get really where resp. what the problem is. I guess it is the Tooltip which is not completely displayed, ie. after some line-break the 0.0% is not displayed. Right?

I do not get how the Tooltips match the subject of this thread ==> ???

And testing on XP, Java 1.6.0.18, I get all the times the 0.0% displayed - and width adapts automatically to the content. But as mentioned, I am not really sure, what resp. where the problem is.

i30817
Offline
Joined: 2006-05-02
Points: 0

It's more like the old tooltip size is not updated when the displayed string changes. Possibly because what's wrong is not the tooltip itself, but the window where the tooltip is put (possibly something to do with a non-heavyweight/heavywheight tooltip change).

My understanding of the TooltipManager code is that tooltips serve as a half-assed string renderers, that get mapped into either native awt windows (if intersect with the outside of the owner window, for shadows, or lightweight windows, if inside, that appear to be just components that have the content pane as parent. Possibly there is a bug in the recycling of the H.W. windows in xp.

I'm going to test this hyphotesis tomorrow by disabling heavyweight tooltips on the TooltipManager class with a mouselistener in my component.

And i know it happens. Just look at the images.
The subject is what i thought at first.

i30817
Offline
Joined: 2006-05-02
Points: 0

Haven't been able to reproduce this on jdk 6 update 20. I don't think it is fixed of course, since the cause wasn't found and it is a heisenbug. I suspect the heavy weight windows as i said.

How annoying.

i30817
Offline
Joined: 2006-05-02
Points: 0

Ok i think i reproduced it. If you look at the code bellow you will see that i change the tooltip text of the same tooltip. This appears to have a cached preferred size problem when larger text replaces smaller text.

(you have to go in and out of the button to change the tooltip enough times so that a small text tooltip is replaced by a large text tooltip).

[code]
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package util.swing.components;

import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JToolTip;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

/**
*
* @author fc30817
*/
public class JTooltipTest implements Runnable {

public JTooltipTest() {
}

@BeforeClass
public static void setUpClass() throws Exception {
}

@AfterClass
public static void tearDownClass() throws Exception {
}

@Before
public void setUp() {
}

@After
public void tearDown() {
}

/**
* Test of retryImage method, of class ImageList.
*/
@Test
public void testJtooltip() throws InterruptedException, InvocationTargetException {
EventQueue.invokeLater(this);
Thread.sleep(25000);
}

@Override
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

JComponent withLabel = new JButton("dummy") {

@Override
public JToolTip createToolTip() {
return new TooltipWithFontBug();
}
};

withLabel.setToolTipText("not null");
f.add(withLabel);
f.pack();
f.setVisible(true);
}

class TooltipWithFontBug extends JToolTip {

List random;
Random r;

public TooltipWithFontBug() {
super();
random = Arrays.asList(
"small 1",
"small 2",
"small 3",
"larrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrgeeeeeeee BUGGG",
"larrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrgeeeeeeee BUGGG",
"larrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrgeeeeeeee BUGGG");
r = new Random();
}

@Override
public String getTipText() {
//suffers from the contructor calls uninicialized object problem.
if (random != null) {
String s = (String) random.get(r.nextInt(random.size()));
// setToolTipText(s);
return "

" + s + "

0.00%

";
}
return "";
}
}
}
[/code]

Any better way to fix this ... maybe calling validate after setting the new text?
Any snoracle engineer wants to open a bug?

Edit: It doesn't always reproduce, try with more than one run. I think that the first displayed tooltip must be one of the small ones.

Message was edited by: i30817

Deleted misleading info at the top

Message was edited by: i30817