Solved

How to add pop-up menu for JEditorPane?

Posted on 2001-06-29
12
995 Views
Last Modified: 2012-05-04
In Swing, I know that I can use JEditorPane to display a html file. At the same time, some words in the file are allowed to be right-clicked, so that a pop-up menu is displayed for the user to choose.

Now, I decide to add some custom tag to the html file to acheive the above result, so that I can use ElementIterator to get the tag. However, I don't know how to add listener to the words in the html file so that the menu can be displayed.

Moreover, I don't know my above idea is correct or not.

I also want to ask whether there is web site or sample code of this example?

Stephen
0
Comment
Question by:fungho
  • 6
  • 5
12 Comments
 

Expert Comment

by:kamaljeets
ID: 6237925
hi!
 I am unable to understand how will u be able to add listener to text(listeners can only be added to components),so i think u will be adding listener to JEditorPane.


also have a look at class :

java.awt Class MenuComponent.AccessibleAWTMenuComponent


and class :

javax.accessibility.AccessibleContext


hope this will give u some help if not all

Kamal
0
 

Author Comment

by:fungho
ID: 6238837
Thanks! I do not have time to look at these 2 classes, I will look at them tomorrow. Moreover, I want to know that if I add listener to JEditorPane, could I add different listener to different words?

Thanks!
0
 
LVL 7

Expert Comment

by:Igor Bazarny
ID: 6239180
Hi,

I believe you can't add listener to different words. You need to locate word basing on click position, then show appropriate menu. Check out JTextComponent.viewToModel(). StyledDocument.getParagraphElement, StyledDocument.getCharacterElement() might also help.

Regards,
Igor Bazarny,
Brainbench MVP for Java 1
www.brainbench.com
0
 

Author Comment

by:fungho
ID: 6240064
Is it useful if I use HTMLEditorKit?
0
 
LVL 7

Expert Comment

by:Igor Bazarny
ID: 6240230
Maybe, if you can turn your sensitive words into hyperlinks. HTMLEditorKit.LinkController class looks promising. Maybe you will need to subclass event delivered to HyperlinkListener. Source digging is necessary to provide more details. I will try to do that tomorrow.
0
 
LVL 7

Accepted Solution

by:
Igor Bazarny earned 200 total points
ID: 6241353
OK. Here is what I able to produce. It seems that JTextPane is repainted too often--there are painting problems.


import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.text.html.*;


public class HTMLPopupMenu{          
    private static String content = new StringBuffer()
        .append("<html><body>\n")
        .append("<a href=\"popup:It doest't have to be a valid URL\">\n")
        .append("Right click to see popup menu.</a><br>\n")
        .append("<a href=\"http://www.experts-exchange.com/jsp/qShow.jsp?qid=20143329\">\n")
        .append("You still can handle normal URLs.</a><br>\n")
        .append("And you can have mouse-insensitive text\n")
        .append("</body></html>\n")
        .toString();
    public static void main(String[] args) throws IOException{
        System.out.println(content);
        System.setErr(new PrintStream(new FileOutputStream("err.log")));
        JTextPane textPane = new JTextPane();
        textPane.setEditorKit(new Kit());
        textPane.setText(content);
        textPane.addHyperlinkListener(new LinkListener());
        textPane.setEditable(false);
        JFrame frame = new JFrame("HTML Popup Menu");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(textPane);
        frame.pack();
        frame.setSize(300,300);
        frame.setVisible(true);
    }

    private static class Kit extends HTMLEditorKit{
        private HTMLEditorKit.LinkController linkController;

        public void install(JEditorPane c) {
            super.install(c);
            replaceLinkController(c);
        }

        public void deinstall(JEditorPane c){
            c.removeMouseListener(linkController);
            c.removeMouseMotionListener(linkController);
        }

        void replaceLinkController(JEditorPane c){
            {EventListener[] listeners = c.getListeners(MouseListener.class);
            for( int i=0; i<listeners.length; ++i){
                if(listeners[i] instanceof HTMLEditorKit.LinkController){
                    c.removeMouseListener((MouseListener)listeners[i]);
                }
            }}
            {EventListener[] listeners = c.getListeners(MouseMotionListener.class);
            for( int i=0; i<listeners.length; ++i){
                if(listeners[i] instanceof HTMLEditorKit.LinkController){
                    c.removeMouseMotionListener((MouseMotionListener)listeners[i]);
                }
            }}
            linkController = createLinkController();
            c.addMouseListener(linkController);
            c.addMouseMotionListener(linkController);
        }

        HTMLEditorKit.LinkController createLinkController(){
            return new HTMLPopupMenu.LinkController();
        }

    }
 
    private static class LinkController extends HTMLEditorKit.LinkController{
        public void mousePressed(final MouseEvent event){
            super.mousePressed(event);
            SwingUtilities.invokeLater( new Runnable(){
                public void run(){
                    checkPopup(event);
                }
            });
        }
        public void mouseReleased(MouseEvent event){
            checkPopup(event);
            super.mousePressed(event);
        }
        public void mouseClicked(MouseEvent event){
            checkPopup(event);
            if(isHTMLPane(event.getComponent()) && isPopupHref(getHref(event))){
                return;
            }
            super.mouseClicked(event);
        }

        public void mouseMoved(MouseEvent event){
            if(isHTMLPane(event.getComponent()) && isPopupHref(getHref(event))){
                event.consume();
                return;
            }
            super.mouseMoved(event);
        }

        void checkPopup(MouseEvent event){
            if( !isHTMLPopup(event) ){
                return;
            }
            String href = getHref(event);
            if(isPopupHref(href)){
                event.consume();
                showPopup(event,href);
            }
        }
       
        boolean isHTMLPopup(MouseEvent event){
            return event.isPopupTrigger()
                && isHTMLPane(event.getComponent());
        }
                                 
        boolean isHTMLPane(Component component){
            return component instanceof JEditorPane
                && ((JEditorPane)component)
                    .getDocument() instanceof HTMLDocument;
        }

        String getHref(MouseEvent event){
            JEditorPane editor = (JEditorPane)event.getSource();
            HTMLDocument doc = (HTMLDocument)editor.getDocument();

            Point pt = new Point(event.getX(), event.getY());
            Element e = doc.getCharacterElement(editor.viewToModel(pt));
            AttributeSet a = e.getAttributes();
            AttributeSet anchor = (AttributeSet) a.getAttribute(HTML.Tag.A);
            return (anchor == null ? null
                : (String) anchor.getAttribute(HTML.Attribute.HREF) );
        }

        boolean isPopupHref(String href){
            return href != null && href.startsWith("popup:");
        }

        void showPopup(MouseEvent reason, String targetHref){
            JPopupMenu popup = new JPopupMenu();
            popup.add("Item 1");
            popup.add("Item 2");
            popup.show(reason.getComponent(),reason.getX(),reason.getY());
        }
    }

    private static class LinkListener implements HyperlinkListener{
        public void hyperlinkUpdate(HyperlinkEvent e) {
            JEditorPane pane = (JEditorPane) e.getSource();
            try {
                pane.setPage(e.getURL());
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
    }
}                        
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 

Author Comment

by:fungho
ID: 6242951
Thanks! It works!
I want to ask whether I can add scroll bar to the textpane?
0
 

Author Comment

by:fungho
ID: 6243809
I met a serious problem when I try to add the listener to the pop up menu. It said that Popup.LinkController cannot use addMouseListener or addPopupMenuListener... how to solve this?
Then how can I add listener to different element in the pop up menu?
0
 
LVL 7

Expert Comment

by:Igor Bazarny
ID: 6243811
> I want to ask whether I can add scroll bar to the textpane?
Just put it into JScrollPane.

BTW, what java version did you use? My code has rather big painting problem on 1.3.1/Win98.

Regards,
Igor Bazarny.

P.S. BTW, would you mind awarding points?
0
 
LVL 7

Expert Comment

by:Igor Bazarny
ID: 6243862
Well, in place where you create menu you can add listeners to items

JPopupMenu popup = new JPopupMenu();
JMenuItem item = new JMenuItem("Item 1");
item.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent event){
        System.out.println("Popup menu item selected!!!");
    }
});
popup.add(item);
popup.add("Item 2");
popup.show(reason.getComponent(),reason.getX(),reason.getY());
0
 

Author Comment

by:fungho
ID: 6243931
bazarny, don't worry, i must give it to you! thanks for ur answer. I will try to test it later and ensure it is ok! Thanks!
0
 

Author Comment

by:fungho
ID: 6243943
Thanks for the code and the answer! I still have some questions in fact, hope you can help me later... I increase the point to 200 to thanks you!

Stephen
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

For customizing the look of your lightweight component and making it look lucid like it was made of glass. Or: how to make your component more Apple-ish ;) This tip assumes your component to be of rectangular shape and completely opaque. (COD…
Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Viewers learn about the “for” loop and how it works in Java. By comparing it to the while loop learned before, viewers can make the transition easily. You will learn about the formatting of the for loop as we write a program that prints even numbers…
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.

708 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

21 Experts available now in Live!

Get 1:1 Help Now