All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jdesktop.swingx.hyperlink.HyperlinkAction Maven / Gradle / Ivy

The newest version!
/*
 * $Id$
 *
 * Copyright 2009 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */
package org.jdesktop.swingx.hyperlink;

import java.awt.Desktop;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Desktop.Action;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.URI;
import java.util.logging.Logger;

/**
 * A implementation wrapping Desktop actions BROWSE and MAIL, that is
 * URI-related. 
 * 
 * @author Jeanette Winzenburg
 */
public class HyperlinkAction extends AbstractHyperlinkAction {
    @SuppressWarnings("unused")
    private static final Logger LOG = Logger.getLogger(HyperlinkAction.class
            .getName());
    
    private Action desktopAction;
    private URIVisitor visitor;
    
    /**
     * Factory method to create and return a HyperlinkAction for the given uri. Tries
     * to guess the appropriate type from the uri. If uri is not null and has a
     * scheme of mailto, create one of type Mail. In all other cases, creates one
     * for BROWSE.
     * 
     * @param uri to uri to create a HyperlinkAction for, maybe null.
     * @return a HyperlinkAction for the given URI.
     * @throws HeadlessException if {@link
     * GraphicsEnvironment#isHeadless()} returns {@code true}
     * @throws UnsupportedOperationException if the current platform doesn't support
     *   Desktop
     */
    public static HyperlinkAction createHyperlinkAction(URI uri) {
        Action type = isMailURI(uri) ? Action.MAIL : Action.BROWSE;
        return createHyperlinkAction(uri, type);
    }
    
    /**
     * Creates and returns a HyperlinkAction with the given target and action type.
     * @param uri the target uri, maybe null.
     * @param desktopAction the type of desktop action this class should perform, must be
     *    BROWSE or MAIL
     * @return a HyperlinkAction
     * @throws HeadlessException if {@link
     * GraphicsEnvironment#isHeadless()} returns {@code true}
     * @throws UnsupportedOperationException if the current platform doesn't support
     *   Desktop
     * @throws IllegalArgumentException if unsupported action type 
     */
    public static HyperlinkAction createHyperlinkAction(URI uri, Action type) {
        return new HyperlinkAction(uri, type);
    }

    /**
     * @param uri
     * @return
     */
    private static boolean isMailURI(URI uri) {
        return uri != null && "mailto".equalsIgnoreCase(uri.getScheme());
    }

    /** 
     * Instantiates a HyperlinkAction with action type BROWSE.
     * 
     * @throws HeadlessException if {@link
     * GraphicsEnvironment#isHeadless()} returns {@code true}
     * @throws UnsupportedOperationException if the current platform doesn't support
     *   Desktop
     * @throws IllegalArgumentException if unsupported action type 
     */
    public HyperlinkAction() {
        this(Action.BROWSE);
    }
    
    /**
     * Instantiates a HyperlinkAction with the given action type.
     * 
     * @param desktopAction the type of desktop action this class should perform, must be
     *    BROWSE or MAIL
     * @throws HeadlessException if {@link
     * GraphicsEnvironment#isHeadless()} returns {@code true}
     * @throws UnsupportedOperationException if the current platform doesn't support
     *   Desktop
     * @throws IllegalArgumentException if unsupported action type 
     */ 
    public HyperlinkAction(Action desktopAction) {
        this(null, desktopAction);
    }

    /**
     * 
     * @param uri the target uri, maybe null.
     * @param desktopAction the type of desktop action this class should perform, must be
     *    BROWSE or MAIL
     * @throws HeadlessException if {@link
     * GraphicsEnvironment#isHeadless()} returns {@code true}
     * @throws UnsupportedOperationException if the current platform doesn't support
     *   Desktop
     * @throws IllegalArgumentException if unsupported action type 
     */
    public HyperlinkAction(URI uri, Action desktopAction) {
        super();
        if (!Desktop.isDesktopSupported()) {
            throw new UnsupportedOperationException("Desktop API is not " +
                                                    "supported on the current platform");
        }
        if (desktopAction != Desktop.Action.BROWSE && desktopAction != Desktop.Action.MAIL) {
           throw new IllegalArgumentException("Illegal action type: " + desktopAction + 
                   ". Must be BROWSE or MAIL");
        }
        this.desktopAction = desktopAction;
        getURIVisitor();
        setTarget(uri);
    }
    
    /**
     * {@inheritDoc} 

* * Implemented to perform the appropriate Desktop action if supported on the current * target. Sets the visited property to true if the desktop action doesn't throw * an exception or to false if it did. * * Does nothing if the action isn't supported. */ @Override public void actionPerformed(ActionEvent e) { if (!getURIVisitor().isEnabled(getTarget())) return; try { getURIVisitor().visit(getTarget()); setVisited(true); } catch (IOException e1) { setVisited(false); LOG.fine("cant visit Desktop " + e); } } /** * @return */ public Action getDesktopAction() { return desktopAction; } @Override protected void installTarget() { // doohh ... this is called from super's constructor before we are // fully initialized if (visitor == null) return; super.installTarget(); updateEnabled(); } /** * */ private void updateEnabled() { setEnabled(getURIVisitor().isEnabled(getTarget())); } /** * @return */ private URIVisitor getURIVisitor() { if (visitor == null) { visitor = createURIVisitor(); } return visitor; } /** * @return */ private URIVisitor createURIVisitor() { return getDesktopAction() == Action.BROWSE ? new BrowseVisitor() : new MailVisitor(); } /** * Thin wrapper around Desktop functionality to allow uniform handling of * different actions in HyperlinkAction. * */ private abstract class URIVisitor { protected boolean desktopSupported = Desktop.isDesktopSupported(); /** * Returns a boolean indicating whether the action is supported on the * given URI. This implementation returns true if both the Desktop is * generally supported and isActionSupported(). * * PENDING JW: hmm ... which class exactly has to check for valid combination * of Action and URI? * * @param uri * @return * * @see #isActionSupported() */ public boolean isEnabled(URI uri) { return desktopSupported && isActionSupported(); } /** * Visits the given URI via Desktop functionality. Must not be called if not * enabled. * * @param uri the URI to visit * @throws IOException if the Desktop method throws IOException. * */ public abstract void visit(URI uri) throws IOException; /** * Returns a boolean indicating if the action is supported by the current * Desktop. * * @return true if the Action is supported by the current desktop, false * otherwise. */ protected abstract boolean isActionSupported(); } private class BrowseVisitor extends URIVisitor { /** * {@inheritDoc}

* * Implemented to message the browse method of Desktop. */ @Override public void visit(URI uri) throws IOException { Desktop.getDesktop().browse(uri); } /** * {@inheritDoc}

* * Implemented to query the Desktop for support of BROWSE action. */ @Override protected boolean isActionSupported() { return Desktop.getDesktop().isSupported(Desktop.Action.BROWSE); } /** * {@inheritDoc}

* * Implemented to guard against null URI in addition to super. */ @Override public boolean isEnabled(URI uri) { return uri != null && super.isEnabled(uri); } } private class MailVisitor extends URIVisitor { /** * {@inheritDoc}

* * Implemented to message the mail function of Desktop. */ @Override public void visit(URI uri) throws IOException { if (uri == null) { Desktop.getDesktop().mail(); } else { Desktop.getDesktop().mail(uri); } } /** * {@inheritDoc}

* * Implemented to query the Desktop for support of MAIL action. */ @Override protected boolean isActionSupported() { return Desktop.getDesktop().isSupported(Desktop.Action.MAIL); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy