--- a/api.io/apichanges.xml +++ a/api.io/apichanges.xml @@ -107,6 +107,52 @@ + + + Add features for dealing with Intent based hyperlinks + + + + + +

+ As there are now two types of hyperlinks, which may be handled + differently in some situations, we need some way to get info about + the type and internals of hyperlinks. +

+

+ Added new enum HyperlinkType + and two new methods to class Hyperlinks: +

+ +
+ +
+ + + Support hyperlinks based on Intents + + + + + +

+ Besides hyperlinks based on Runnables, support also hyperlinks + that are defined by an Intent instance. +

+

+ Added new static methods to Hyperlink class: +

+ +
+ +
Introduce new I/O API --- a/api.io/manifest.mf +++ a/api.io/manifest.mf @@ -2,5 +2,5 @@ AutoUpdate-Show-In-Client: true OpenIDE-Module: org.netbeans.api.io OpenIDE-Module-Localizing-Bundle: org/netbeans/api/io/Bundle.properties -OpenIDE-Module-Specification-Version: 1.0 +OpenIDE-Module-Specification-Version: 1.1 OpenIDE-Module-Recommends: org.netbeans.spi.io.InputOutputProvider --- a/api.io/nbproject/project.xml +++ a/api.io/nbproject/project.xml @@ -15,6 +15,14 @@ + org.netbeans.api.intent + + + + 1.0 + + + org.openide.util --- a/api.io/src/org/netbeans/api/io/Hyperlink.java +++ a/api.io/src/org/netbeans/api/io/Hyperlink.java @@ -42,6 +42,7 @@ package org.netbeans.api.io; import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.intent.Intent; import org.netbeans.modules.io.HyperlinkAccessor; import org.openide.util.Parameters; @@ -103,10 +104,43 @@ @NonNull public static Hyperlink from(@NonNull Runnable runnable, boolean important) { - Parameters.notNull("runnable", runnable); + Parameters.notNull("runnable", runnable); //NOI18N return new OnClickHyperlink(runnable, important); } + /** + * Create a new hyperlink for specified {@link Intent}, which will be + * executed when the line is clicked. + * + * @param intent The intent to execute on click. + * @return The new hyperlink. + */ + public static Hyperlink from(@NonNull Intent intent) { + return from(intent, false); + } + + /** + * Create a new hyperlink for specified {@link Intent}, which will be + * executed when the line is clicked. + * + *
+ *

+ * Important hyperlinks can be printed in different color, or can have some + * special behavior, e.g. automatic scrolling can be switched off to keep + * the important hyperlink visible. + *

+ *
+ * + * @param intent The intent to execute on click. + * @param important True if the hyperlink should be handled as an important + * one, false if it is a standard one. + * @return The new hyperlink. + */ + public static Hyperlink from(@NonNull Intent intent, boolean important) { + Parameters.notNull("intent", intent); //NOI18N + return new IntentHyperlink(intent, important); + } + @SuppressWarnings("PackageVisibleInnerClass") static class OnClickHyperlink extends Hyperlink { @@ -121,4 +155,19 @@ return runnable; } } + + @SuppressWarnings("PackageVisibleInnerClass") + static class IntentHyperlink extends Hyperlink { + + private final Intent intent; + + public IntentHyperlink(Intent intent, boolean important) { + super(important); + this.intent = intent; + } + + public Intent getIntent() { + return intent; + } + } } --- a/api.io/src/org/netbeans/api/io/HyperlinkAccessorImpl.java +++ a/api.io/src/org/netbeans/api/io/HyperlinkAccessorImpl.java @@ -41,8 +41,9 @@ */ package org.netbeans.api.io; +import org.netbeans.api.intent.Intent; import org.netbeans.modules.io.HyperlinkAccessor; -import org.netbeans.modules.io.HyperlinkType; +import org.netbeans.spi.io.support.HyperlinkType; /** * Implementation of accessor that enables retrieving information about @@ -56,6 +57,8 @@ public HyperlinkType getType(Hyperlink hyperlink) { if (hyperlink instanceof Hyperlink.OnClickHyperlink) { return HyperlinkType.FROM_RUNNABLE; + } else if (hyperlink instanceof Hyperlink.IntentHyperlink) { + return HyperlinkType.FROM_INTENT; } else { throw new IllegalArgumentException("Unknown hyperlink."); //NOI18N } @@ -71,7 +74,18 @@ if (hyperlink instanceof Hyperlink.OnClickHyperlink) { return ((Hyperlink.OnClickHyperlink) hyperlink).getRunnable(); } else { - throw new IllegalArgumentException("Not an ON_CLICK link.");//NOI18N + throw new IllegalArgumentException( + "Not an FROM_RUNNABLE link."); //NOI18N + } + } + + @Override + public Intent getIntent(Hyperlink hyperlink) { + if (hyperlink instanceof Hyperlink.IntentHyperlink) { + return ((Hyperlink.IntentHyperlink) hyperlink).getIntent(); + } else { + throw new IllegalArgumentException( + "Not a FROM_INTENT link"); //NOI18N } } } --- a/api.io/src/org/netbeans/modules/io/HyperlinkAccessor.java +++ a/api.io/src/org/netbeans/modules/io/HyperlinkAccessor.java @@ -41,6 +41,8 @@ */ package org.netbeans.modules.io; +import org.netbeans.api.intent.Intent; +import org.netbeans.spi.io.support.HyperlinkType; import org.netbeans.api.io.Hyperlink; /** @@ -82,4 +84,6 @@ public abstract boolean isImportant(Hyperlink hyperlink); public abstract Runnable getRunnable(Hyperlink hyperlink); + + public abstract Intent getIntent(Hyperlink hyperlink); } --- a/api.io/src/org/netbeans/modules/io/HyperlinkType.java +++ a/api.io/src/org/netbeans/modules/io/HyperlinkType.java @@ -39,24 +39,28 @@ * * Portions Copyrighted 2014 Sun Microsystems, Inc. */ -package org.netbeans.modules.io; +package org.netbeans.spi.io.support; -import org.netbeans.spi.io.support.Hyperlinks; +import org.netbeans.api.intent.Intent; +import org.netbeans.api.io.Hyperlink; /** * Type of the hyperlink. *

* Note: New items may be added in the future. *

- *

- * Note: When more hyperlink types are added, this enum can be moved to package - * org.netbeans.spi.io.support, and getType(), getRunnable() (for correct type) - * methods can be added to {@link Hyperlinks} class. So that implementation can - * work with specific hyperlink types differently. See bug 247404. - *

* * @author jhavlin */ public enum HyperlinkType { - FROM_RUNNABLE + /** + * Hyperlink created using {@link Hyperlink#from(java.lang.Runnable)} or + * {@link Hyperlink#from(java.lang.Runnable, boolean)}. + */ + FROM_RUNNABLE, + /** + * Hyperlink created using {@link Hyperlink#from(Intent)} or + * {@link Hyperlink#from(Intent, boolean)}. + */ + FROM_INTENT } --- a/api.io/src/org/netbeans/spi/io/support/Hyperlinks.java +++ a/api.io/src/org/netbeans/spi/io/support/Hyperlinks.java @@ -41,8 +41,8 @@ */ package org.netbeans.spi.io.support; -import org.netbeans.modules.io.HyperlinkType; import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.intent.Intent; import org.netbeans.api.io.Hyperlink; import org.netbeans.modules.io.HyperlinkAccessor; @@ -63,7 +63,7 @@ * @return The type of the hyperlink. */ @NonNull - static HyperlinkType getType(@NonNull Hyperlink hyperlink) { + public static HyperlinkType getType(@NonNull Hyperlink hyperlink) { return HyperlinkAccessor.getDefault().getType(hyperlink); } @@ -105,6 +105,23 @@ } /** + * Get intent associated with a hyperlink of type + * {@link HyperlinkType#FROM_INTENT}. + * + * @param hyperlink The hyperlink to get intent from. + * + * @return An intent. + * @throws IllegalArgumentException if type of the hyperlink is not + * {@link HyperlinkType#FROM_INTENT}. + * @see #getType(org.netbeans.api.io.Hyperlink) + * @see HyperlinkType + */ + @NonNull + public static Intent getIntent(@NonNull Hyperlink hyperlink) { + return HyperlinkAccessor.getDefault().getIntent(hyperlink); + } + + /** * Invoke appropriate action for the hyperlink. * * @param hyperlink Hyperlink to invoke. @@ -114,6 +131,9 @@ case FROM_RUNNABLE: getRunnable(hyperlink).run(); break; + case FROM_INTENT: + getIntent(hyperlink).execute(null); + break; default: break; } --- a/api.io/test/unit/src/org/netbeans/spi/io/support/HyperlinksTest.java +++ a/api.io/test/unit/src/org/netbeans/spi/io/support/HyperlinksTest.java @@ -41,10 +41,12 @@ */ package org.netbeans.spi.io.support; +import java.net.URI; +import java.net.URISyntaxException; import static org.junit.Assert.*; import org.junit.Test; +import org.netbeans.api.intent.Intent; import org.netbeans.api.io.Hyperlink; -import org.netbeans.modules.io.HyperlinkType; /** * @@ -79,4 +81,12 @@ }, true); assertTrue(Hyperlinks.isImportant(h)); } + + @Test + public void testIntentHyperlink() throws URISyntaxException { + Intent i = new Intent(Intent.ACTION_EDIT, new URI("scheme://abc")); + Hyperlink h = Hyperlink.from(i); + assertEquals(HyperlinkType.FROM_INTENT, Hyperlinks.getType(h)); + assertEquals(i, Hyperlinks.getIntent(h)); + } }