Solved

"Hover Style" for JTextPane

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

Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

Question has a verified solution.

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

Suggested Solutions

Are you developing a Java application and want to create Excel Spreadsheets? You have come to the right place, this article will describe how you can create Excel Spreadsheets from a Java Application. For the purposes of this article, I will be u…
Introduction This article is the second of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article covers the basic installation and configuration of the test automation tools used by…
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…

773 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