Bug 566162 - Add WidgetFactory for Link
Change-Id: I70f6b965a2bf2f626bd7caf48129c0061678668d
Signed-off-by: Lars Vogel <Lars.Vogel@vogella.com>
diff --git a/bundles/org.eclipse.jface/src/org/eclipse/jface/widgets/LinkFactory.java b/bundles/org.eclipse.jface/src/org/eclipse/jface/widgets/LinkFactory.java
new file mode 100644
index 0000000..d1b7bc9
--- /dev/null
+++ b/bundles/org.eclipse.jface/src/org/eclipse/jface/widgets/LinkFactory.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+* Copyright (c) 2020 vogella GmbH and others.
+*
+* This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License 2.0
+* which accompanies this distribution, and is available at
+* https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* Contributors:
+* Lars Vogel - initial version
+******************************************************************************/
+package org.eclipse.jface.widgets;
+
+import java.util.function.Consumer;
+
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Link;
+
+/**
+ * This class provides a convenient shorthand for creating and initializing
+ * {@link Link}. This offers several benefits over creating Link objects via the
+ * new operator:
+ *
+ * <ul>
+ * <li>The same factory can be used many times to create several Link
+ * instances</li>
+ * <li>The setters all return "this", allowing them to be chained</li>
+ * <li>This class accepts a Lambda for {@link SelectionEvent} (see
+ * {@link #onSelect})</li>
+ * </ul>
+ *
+ * Example usage:
+ *
+ * <pre>
+ * Link link = LinkFactory.newLink(SWT.NONE) //
+ * .text("Click me!") //
+ * .onSelect(event -> clicked(event)) //
+ * .layoutData(gridData) //
+ * .create(parent);
+ * </pre>
+ * <p>
+ * The above example creates a link with a text, registers a SelectionListener
+ * and finally creates the link in "parent".
+ * </p>
+ *
+ * <pre>
+ * GridDataFactory gridDataFactory = GridDataFactory.swtDefaults();
+ * LinkFactory linkFactory = LinkFactory.newLink(SWT.PUSH).onSelect(event -> clicked(event))
+ * .layout(gridDataFactory::create);
+ * linkFactory.text("Link 1").create(parent);
+ * linkFactory.text("Link 2").create(parent);
+ * linkFactory.text("Link 3").create(parent);
+ * </pre>
+ * <p>
+ * The above example creates three objects using the same instance of the
+ * factory. Note the layout method. A Supplier is used to create unique GridData
+ * for every single link.
+ * </p>
+ *
+ * @since 3.21
+ *
+ */
+public final class LinkFactory extends AbstractControlFactory<LinkFactory, Link> {
+
+ private LinkFactory(int style) {
+ super(LinkFactory.class, (Composite parent) -> new Link(parent, style));
+ }
+
+ /**
+ * Creates a new factory with the given style. Refer to
+ * {@link Link#Link(Composite, int)} for possible styles.
+ *
+ * @param style
+ * @return a new LinkFactory instance
+ */
+ public static LinkFactory newLink(int style) {
+ return new LinkFactory(style);
+ }
+
+ /**
+ * Sets the receiver's text.
+ * <p>
+ * This method sets the label. The label may include the mnemonic character but
+ * must not contain line delimiters.
+ * </p>
+ * <p>
+ * Mnemonics are indicated by an '&' that causes the next character to be
+ * the mnemonic. When the user presses a key sequence that matches the mnemonic,
+ * a selection event occurs. On most platforms, the mnemonic appears underlined
+ * but may be emphasized in a platform specific manner. The mnemonic indicator
+ * character '&' can be escaped by doubling it in the string, causing a
+ * single '&' to be displayed.
+ * </p>
+ *
+ * @param text the text
+ * @return this
+ *
+ * @see Link#setText(String)
+ */
+ public LinkFactory text(String text) {
+ addProperty(l -> l.setText(text));
+ return this;
+ }
+
+ /**
+ * Creates a {@link SelectionListener} and registers it for the widgetSelected
+ * event. If the receiver is selected by the user the given consumer is invoked.
+ * The {@link SelectionEvent} is passed to the consumer.
+ *
+ * @param consumer the consumer whose accept method is called
+ * @return this
+ *
+ * @see Link#addSelectionListener(SelectionListener)
+ * @see SelectionListener#widgetSelectedAdapter(Consumer)
+ */
+ public LinkFactory onSelect(Consumer<SelectionEvent> consumer) {
+ addProperty(c -> c.addSelectionListener(SelectionListener.widgetSelectedAdapter(consumer)));
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/widgets/AllWidgetTests.java b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/widgets/AllWidgetTests.java
index 90e3300..ead93ff 100644
--- a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/widgets/AllWidgetTests.java
+++ b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/widgets/AllWidgetTests.java
@@ -20,6 +20,7 @@
TestUnitControlFactory.class, //
TestUnitItemFactory.class, //
TestUnitLabelFactory.class, //
+ TestUnitLinkFactory.class, //
TestUnitSashFactory.class, //
TestUnitSashFormFactory.class, //
TestUnitShellFactory.class, //
diff --git a/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/widgets/TestUnitLinkFactory.java b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/widgets/TestUnitLinkFactory.java
new file mode 100644
index 0000000..f5fb765
--- /dev/null
+++ b/tests/org.eclipse.jface.tests/src/org/eclipse/jface/tests/widgets/TestUnitLinkFactory.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+* Copyright (c) 2020 vogella GmbH and others.
+*
+* This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License 2.0
+* which accompanies this distribution, and is available at
+* https://www.eclipse.org/legal/epl-2.0/
+*
+* SPDX-License-Identifier: EPL-2.0
+*
+* Contributors:
+* Lars Vogel - initial version
+******************************************************************************/
+package org.eclipse.jface.tests.widgets;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.eclipse.jface.widgets.LinkFactory;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Link;
+import org.junit.Test;
+
+public class TestUnitLinkFactory extends AbstractFactoryTest {
+
+ @Test
+ public void createsLink() {
+ Link link = LinkFactory.newLink(SWT.NONE).create(shell);
+
+ assertEquals(shell, link.getParent());
+ assertEquals(SWT.NONE, link.getStyle() & SWT.NONE);
+ }
+
+ @Test
+ public void createLinksWithAllProperties() {
+ final SelectionEvent[] raisedEvents = new SelectionEvent[1];
+ Link link = LinkFactory.newLink(SWT.NONE).text("Test Link").onSelect(e -> raisedEvents[0] = e).create(shell);
+
+ link.notifyListeners(SWT.Selection, new Event());
+
+ assertEquals("Test Link", link.getText());
+
+ assertEquals(1, link.getListeners(SWT.Selection).length);
+ assertNotNull(raisedEvents[0]);
+ }
+}
\ No newline at end of file