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/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..0506fcc --- /dev/null +++ b/src/main/java/org/scijava/ui/swing/widget/SwingURIWidget.java @@ -0,0 +1,174 @@ +/* + * #%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.URIWidget; +import org.scijava.widget.WidgetModel; + +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; +import java.awt.event.ActionListener; +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * Swing implementation of URI selector widget. + * + * @author Christian Tischer + * @author Jan Eglinger + */ +@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/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); + } +}