Solved

"Hover Style" for JTextPane

Posted on 2001-07-03
1
769 Views
Last Modified: 2012-06-27
I am programming on a reporting system which shows text,
pictures and information (very much like an HTML page).
For this I use the JTextPane, the DefaultStyleDocument
and the StyleConstants, and this works very well. Now,
I would like to add another style: one which shows a
small tool-tip or pop-up whenever the mouse hovers for
a defined amount of time (say 100 ms.) I would like to
specify the text (or even a whole component) and the
delay.

How to define a style and how to implement the tool-tip?
0
Comment
Question by:chrisflch
1 Comment
 
LVL 3

Accepted Solution

by:
dnoelpp earned 200 total points
ID: 6251642
I just am writing a similar application. I am afraid I didn't find a simple solution.


Summary:

Use the MouseMotionListener and translate the Point to the Position using AccessibleText.getIndexAtPoint(). Using StyledDocument.getCharacterElement(offset).getAttributes() detect the hover style and then show the pop-up. I still am working on how to do the pop-up, so I am sorry I can't give you hints on how to do the delay. I would use a Timer and recheck the current position of the mouse later.


Detailed steps:

#1 -- I created a custom JComponent which has a JTextPane inside (if you prefer just extend JTextPane, this doesn't matter).

#2 -- I wrote a MouseMotionListener which catches the mouse movements. I then translated the coordinates to the offset into the text. This was difficult, but then I discovered in the AccessibleText the function getIndexAtPoint() which does exactly what I needed. See code:

public int getOffsetAtPoint(Point p) {
    return textPane.getAccessibleContext().getAccessibleText().getIndexAtPoint(p);
}

#3 -- I designed a HoverListener interface and wrote addHoverListener and removeHoverListener methods to access them. A HoverListener is a low-level event very similar to the MouseMotionListener, but gives a Position object which is the position of the mouse into the text. See code:

public class HoverEvent extends EventObject {
    private Position position;
       
    public HoverEvent(Position position) {
        super(SimpleTextPane.this);
        this.position = position;
    }
    public Position getPosition() {
        return position;
    }
}
   
public static interface HoverListener extends EventListener {
    public void hover(HoverEvent e);
}

protected void addHoverListener(HoverListener listener) {
    listeners.add(listener);
}
   
protected boolean removeHoverListener(HoverListener listener) {
    return listeners.remove(listener);
}
   
private void fireHover(Position position) {
    int len = listeners.size();
    for (int i = 0; i < len; i++) {
        ((HoverListener)listeners.get(i)).hover(new HoverEvent(position));
    }
}

#4 -- In the mouse motion event handler I called fireHover() with the position gathered in step 2.

#5 -- I designed a Hover style. See code:

private static class HoverStyle {
    int hoverTime = -1;
    JComponent hoverComponent = null;
    public HoverStyle(int time, String text) {
        this(time, new JLabel(text));
    }
    public HoverStyle(int time, JComponent component) {
        if (time >= 0) {
            hoverTime = time;
            hoverComponent = component;
        }
    }
    public String toString() {
        return "HoverStyle[time=" + hoverTime + ",component="
            + (hoverComponent == null
                ? "<null>"
                : hoverComponent.getClass().getName()) + "]";
    }
}

#6 -- Since the HoverStyle is a private nested class, I provided accessor methods to set a hover style like this:

public void setHoverOff() {
    currentStyle.removeAttribute(HOVER_STYLE_NAME);
}
   
public void setHover(int time, String text) {
    currentStyle.addAttribute(
        HOVER_STYLE_NAME, new HoverStyle(time, text));
}
   
public void setHover(int time, JComponent component) {
    currentStyle.addAttribute(
        HOVER_STYLE_NAME, new HoverStyle(time, component));
}

currentStyle is a Style object. Text added to the JTextPane will have the style of currentStyle. HOVER_STYLE_NAME is just a string "hover" which gives the attribute name of the hover style.

#7 -- Make your class (from step 1) listening to the hover event yourself and detect any hover styles at the Position and put a pop-up. Like this with an anonymous inner class:

addHoverListener(new HoverListener() {
    public void hover(HoverEvent e) {
        int offset = e.getPosition().getOffset();
            AttributeSet attr = textPane.getStyledDocument()
                .getCharacterElement(offset).getAttributes();

            Object attribute = attr.getAttribute("hover");
            if (attribute == null) return;
            System.out.println("hover");
            JComponent hover = ((HoverStyle)attribute).hoverComponent;
            // here show the JComponent hover and set its location... NOT YET IMPLEMENTED.
            // hover.setVisible(true);
        }
    });
}

#8 -- NOT YET IMPLEMENTED: Make the pop up show at the appropriate place with specified delay.

That's it!
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

An old method to applying the Singleton pattern in your Java code is to check if a static instance, defined in the same class that needs to be instantiated once and only once, is null and then create a new instance; otherwise, the pre-existing insta…
Introduction This article is the last of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers our test design approach and then goes through a simple test case example, how …
Viewers will learn about if statements in Java and their use The if statement: The condition required to create an if statement: Variations of if statements: An example using if statements:
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now