Solved

"Hover Style" for JTextPane

Posted on 2001-07-03
1
772 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

After being asked a question last year, I went into one of my moods where I did some research and code just for the fun and learning of it all.  Subsequently, from this journey, I put together this article on "Range Searching Using Visual Basic.NET …
Introduction Java can be integrated with native programs using an interface called JNI(Java Native Interface). Native programs are programs which can directly run on the processor. JNI is simply a naming and calling convention so that the JVM (Java…
Viewers learn about the third conditional statement “else if” and use it in an example program. Then additional information about conditional statements is provided, covering the topic thoroughly. Viewers learn about the third conditional statement …
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.

895 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