From c63183fc354c324a6d856d6b55e6a324ad51d17e Mon Sep 17 00:00:00 2001 From: Christian Tischer Date: Sat, 26 Oct 2024 12:35:59 +0200 Subject: [PATCH 1/2] WIP implement URI widget --- .../ui/swing/widget/SwingFileWidget.java | 2 +- .../ui/swing/widget/SwingURIWidget.java | 169 ++++++++++++++++++ .../scijava/ui/swing/widget/URIWidget.java | 65 +++++++ .../java/org/scijava/ui/swing/URITest.java | 26 +++ .../ui/swing/widget/SwingURIWidgetDemo.java | 57 ++++++ 5 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/scijava/ui/swing/widget/SwingURIWidget.java create mode 100644 src/main/java/org/scijava/ui/swing/widget/URIWidget.java create mode 100644 src/test/java/org/scijava/ui/swing/URITest.java create mode 100644 src/test/java/org/scijava/ui/swing/widget/SwingURIWidgetDemo.java diff --git a/src/main/java/org/scijava/ui/swing/widget/SwingFileWidget.java b/src/main/java/org/scijava/ui/swing/widget/SwingFileWidget.java index f669e39..9480dfd 100644 --- a/src/main/java/org/scijava/ui/swing/widget/SwingFileWidget.java +++ b/src/main/java/org/scijava/ui/swing/widget/SwingFileWidget.java @@ -321,7 +321,7 @@ public static List filterFiles(final List list, // -- Helper classes -- - private class FileTransferHandler extends TransferHandler { + public static class FileTransferHandler extends TransferHandler { private final String style; diff --git a/src/main/java/org/scijava/ui/swing/widget/SwingURIWidget.java b/src/main/java/org/scijava/ui/swing/widget/SwingURIWidget.java new file mode 100644 index 0000000..9161a73 --- /dev/null +++ b/src/main/java/org/scijava/ui/swing/widget/SwingURIWidget.java @@ -0,0 +1,169 @@ +/* + * #%L + * SciJava UI components for Java Swing. + * %% + * Copyright (C) 2010 - 2023 SciJava developers. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +package org.scijava.ui.swing.widget; + +import org.scijava.plugin.Parameter; +import org.scijava.plugin.Plugin; +import org.scijava.ui.UIService; +import org.scijava.widget.FileWidget; +import org.scijava.widget.InputWidget; +import org.scijava.widget.WidgetModel; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * Swing implementation of file selector widget. + * + * @author Curtis Rueden + */ +@Plugin(type = InputWidget.class) +public class SwingURIWidget extends SwingInputWidget implements + URIWidget, ActionListener, DocumentListener +{ + + @Parameter + private UIService uiService; + + private JTextField uriTextField; + private JButton browse; + + // -- InputWidget methods -- + + @Override + public URI getValue() { + final String text = uriTextField.getText(); + if (text.isEmpty()) { + return null; + } + File file = new File(text); + try + { + if (file.exists() || file.isAbsolute()) { + return file.toURI(); + } + return new URI(text); + } catch ( URISyntaxException e ) + { + return null; + } + } + + // -- WrapperPlugin methods -- + + @Override + public void set(final WidgetModel model) { + super.set(model); + + uriTextField = new JTextField(16); + uriTextField.setDragEnabled(true); + final String style = model.getItem().getWidgetStyle(); + uriTextField.setTransferHandler(new SwingFileWidget.FileTransferHandler(style)); + setToolTip( uriTextField ); + getComponent().add( uriTextField ); + uriTextField.getDocument().addDocumentListener(this); + + getComponent().add(Box.createHorizontalStrut(3)); + + browse = new JButton("Browse"); + setToolTip(browse); + getComponent().add(browse); + browse.addActionListener(this); + + refreshWidget(); + } + + // -- Typed methods -- + + @Override + public boolean supports(final WidgetModel model) { + return super.supports(model) && model.isType(URI.class); + } + + // -- ActionListener methods -- + + @Override + public void actionPerformed(final ActionEvent e) { + File file = new File(uriTextField.getText()); + + if (!file.isDirectory()) { + file = file.getParentFile(); + } + + // display file chooser in appropriate mode + final WidgetModel model = get(); + final String style; + if (model.isStyle(FileWidget.DIRECTORY_STYLE)) { + style = FileWidget.DIRECTORY_STYLE; + } + else if (model.isStyle(FileWidget.SAVE_STYLE)) { + style = FileWidget.SAVE_STYLE; + } + else { + style = FileWidget.OPEN_STYLE; + } + file = uiService.chooseFile(file, style); + if (file == null) return; + + uriTextField.setText(file.getAbsolutePath()); + } + + // -- DocumentListener methods -- + + @Override + public void changedUpdate(final DocumentEvent e) { + updateModel(); + } + + @Override + public void insertUpdate(final DocumentEvent e) { + updateModel(); + } + + @Override + public void removeUpdate(final DocumentEvent e) { + updateModel(); + } + + // -- AbstractUIInputWidget methods --- + + @Override + public void doRefresh() { +// final String text = get().getText(); +// if (text.equals( uriTextField.getText())) return; // no change +// uriTextField.setText(text); + } +} diff --git a/src/main/java/org/scijava/ui/swing/widget/URIWidget.java b/src/main/java/org/scijava/ui/swing/widget/URIWidget.java new file mode 100644 index 0000000..658d8c2 --- /dev/null +++ b/src/main/java/org/scijava/ui/swing/widget/URIWidget.java @@ -0,0 +1,65 @@ +package org.scijava.ui.swing.widget; + +/* + * #%L + * SciJava Common shared library for SciJava software. + * %% + * Copyright (C) 2009 - 2024 SciJava developers. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ + +import org.scijava.widget.InputWidget; + +import java.net.URI; + +/** + * Widget interface for file selectors. + * + * @author Curtis Rueden + */ +public interface URIWidget extends InputWidget +{ + + /** + * Widget style for file opener dialogs. + * + * @see org.scijava.plugin.Parameter#style() + */ + String OPEN_STYLE = "open"; + + /** + * Widget style for file saver dialogs. + * + * @see org.scijava.plugin.Parameter#style() + */ + String SAVE_STYLE = "save"; + + /** + * Widget style for directory chooser dialogs. + * + * @see org.scijava.plugin.Parameter#style() + */ + String DIRECTORY_STYLE = "directory"; + +} diff --git a/src/test/java/org/scijava/ui/swing/URITest.java b/src/test/java/org/scijava/ui/swing/URITest.java new file mode 100644 index 0000000..793c956 --- /dev/null +++ b/src/test/java/org/scijava/ui/swing/URITest.java @@ -0,0 +1,26 @@ +package org.scijava.ui.swing; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +public class URITest +{ + public static void main( String[] args ) throws URISyntaxException, MalformedURLException + { + File f = new File("tischer"); + System.out.println(f.toURI()); + System.out.println( new URI( "file", "/tischer/test.txt" , null).toString() ); + URI uri = new URI( "file:/path/to/local/file.txt" ); + System.out.println( uri.getScheme() ); + URL url = uri.toURL(); + System.out.println(url.getFile()); + if ( uri.getScheme().equals( "file" ) ) + { + File file = new File( uri.toURL().getPath() ); + System.out.println( file.getAbsolutePath() ); + } + } +} diff --git a/src/test/java/org/scijava/ui/swing/widget/SwingURIWidgetDemo.java b/src/test/java/org/scijava/ui/swing/widget/SwingURIWidgetDemo.java new file mode 100644 index 0000000..99c43e8 --- /dev/null +++ b/src/test/java/org/scijava/ui/swing/widget/SwingURIWidgetDemo.java @@ -0,0 +1,57 @@ +/*- + * #%L + * SciJava UI components for Java Swing. + * %% + * Copyright (C) 2010 - 2023 SciJava developers. + * %% + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * #L% + */ +package org.scijava.ui.swing.widget; + +import org.scijava.Context; +import org.scijava.command.Command; +import org.scijava.command.CommandService; +import org.scijava.plugin.Parameter; +import org.scijava.ui.UIService; +import org.scijava.widget.FileListWidget; +import org.scijava.widget.FileWidget; + +import java.net.URI; + +public class SwingURIWidgetDemo implements Command { + + + @Parameter(style = FileListWidget.FILES_AND_DIRECTORIES, persist = false) + private URI uri; + + @Override + public void run() { + System.out.println(uri); + } + + public static void main(final String... args) throws Exception { + Context context = new Context(); + context.service(UIService.class).showUI(); + context.service(CommandService.class).run( SwingURIWidgetDemo.class, true); + } +} From fdcf1e0b9cb3ade2d56ec6f49069a19e6ce2060c Mon Sep 17 00:00:00 2001 From: Christian Tischer Date: Sat, 26 Oct 2024 13:49:36 +0200 Subject: [PATCH 2/2] Add SwingURIWidget --- pom.xml | 1 + .../ui/swing/widget/SwingURIWidget.java | 11 +++- .../scijava/ui/swing/widget/URIWidget.java | 65 ------------------- 3 files changed, 9 insertions(+), 68 deletions(-) delete mode 100644 src/main/java/org/scijava/ui/swing/widget/URIWidget.java diff --git a/pom.xml b/pom.xml index 091e663..c843436 100644 --- a/pom.xml +++ b/pom.xml @@ -112,6 +112,7 @@ 1.3.2 0.1 + 99.0 diff --git a/src/main/java/org/scijava/ui/swing/widget/SwingURIWidget.java b/src/main/java/org/scijava/ui/swing/widget/SwingURIWidget.java index 9161a73..0506fcc 100644 --- a/src/main/java/org/scijava/ui/swing/widget/SwingURIWidget.java +++ b/src/main/java/org/scijava/ui/swing/widget/SwingURIWidget.java @@ -34,9 +34,13 @@ import org.scijava.ui.UIService; import org.scijava.widget.FileWidget; import org.scijava.widget.InputWidget; +import org.scijava.widget.URIWidget; import org.scijava.widget.WidgetModel; -import javax.swing.*; +import javax.swing.Box; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.JTextField; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.event.ActionEvent; @@ -46,9 +50,10 @@ import java.net.URISyntaxException; /** - * Swing implementation of file selector widget. + * Swing implementation of URI selector widget. * - * @author Curtis Rueden + * @author Christian Tischer + * @author Jan Eglinger */ @Plugin(type = InputWidget.class) public class SwingURIWidget extends SwingInputWidget implements diff --git a/src/main/java/org/scijava/ui/swing/widget/URIWidget.java b/src/main/java/org/scijava/ui/swing/widget/URIWidget.java deleted file mode 100644 index 658d8c2..0000000 --- a/src/main/java/org/scijava/ui/swing/widget/URIWidget.java +++ /dev/null @@ -1,65 +0,0 @@ -package org.scijava.ui.swing.widget; - -/* - * #%L - * SciJava Common shared library for SciJava software. - * %% - * Copyright (C) 2009 - 2024 SciJava developers. - * %% - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * #L% - */ - -import org.scijava.widget.InputWidget; - -import java.net.URI; - -/** - * Widget interface for file selectors. - * - * @author Curtis Rueden - */ -public interface URIWidget extends InputWidget -{ - - /** - * Widget style for file opener dialogs. - * - * @see org.scijava.plugin.Parameter#style() - */ - String OPEN_STYLE = "open"; - - /** - * Widget style for file saver dialogs. - * - * @see org.scijava.plugin.Parameter#style() - */ - String SAVE_STYLE = "save"; - - /** - * Widget style for directory chooser dialogs. - * - * @see org.scijava.plugin.Parameter#style() - */ - String DIRECTORY_STYLE = "directory"; - -}