?
Solved

How to add pop-up menu for JEditorPane?

Posted on 2001-06-29
12
Medium Priority
?
1,086 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

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 800 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
 

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 to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

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

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…
In this post we will learn different types of Android Layout and some basics of an Android App.
Video by: Michael
Viewers learn about how to reduce the potential repetitiveness of coding in main by developing methods to perform specific tasks for their program. Additionally, objects are introduced for the purpose of learning how to call methods in Java. Define …
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
Suggested Courses
Course of the Month13 days, 16 hours left to enroll

809 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