Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

How to add pop-up menu for JEditorPane?

Posted on 2001-06-29
12
Medium Priority
?
1,073 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

INTRODUCTION Working with files is a moderately common task in Java.  For most projects hard coding the file names, using parameters in configuration files, or using command-line arguments is sufficient.   However, when your application has vi…
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
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.
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.
Suggested Courses

636 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