From 3932c1eaedc1f57a44b60782820338b8c667227a Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Mon, 6 Feb 2017 13:19:47 -0600 Subject: [PATCH 001/184] Bump to next development cycle Signed-off-by: Jenkins --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 024bc97..ed88f8f 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.2.1-SNAPSHOT + 1.3.1-SNAPSHOT http://github.com/scijava/ui-behaviour 2015 From 2192271c3c02b3968ca256e641babccb145d2255 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 28 Feb 2017 08:18:56 -0600 Subject: [PATCH 002/184] Switch from Jenkins to Travis CI --- .travis.yml | 12 ++++++++++++ .travis/build.sh | 7 +++++++ .travis/notify.sh | 2 ++ .travis/settings.xml | 14 ++++++++++++++ pom.xml | 4 ++-- 5 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 .travis.yml create mode 100755 .travis/build.sh create mode 100755 .travis/notify.sh create mode 100644 .travis/settings.xml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..d1e3845 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,12 @@ +language: java +jdk: oraclejdk8 +branches: + only: master +install: true +script: ".travis/build.sh" +after_success: ".travis/notify.sh Travis-Success" +after_failure: ".travis/notify.sh Travis-Failure" +env: + global: + - secure: YRNfBvbeO4779HH3rkuat08sFAhGIFJUNil9iSLO3KuiiS+o940jPQoJUXw2N+U9EtZtl78EeKOLRP9/98Lyt7H8Lh1ml5ELw5eA0cr+PUENoKi2Wygm7OG96bLGydhRGj/thX1gKA8DyveOpNNuSnINTq/zTvqo5dYNTRhmQ9uRAWJ7Iag6UWjXVNQabIf0qrGQ+DHnVtdMq3t8XPdeckaum22Xl1sPem+iPIj0E2jftwDGfEJ4y+7m881+0lUDDsqzZ6ag+YGKrEYg2VeoHJU62/XKbGBgSHfGZb0b88ps0PN8wCv3VYcrNx3hCi2G8awYjg6s+LOs/IOaKX0UsTFf5oexAmxlgT8TMtxtMEG03o/4W/AuppNz5H9kiusvWdBKv2ZfLUTgh2lW4fxpJweBCYVw7bM2na9SOO9bXvjxBHFjmv3f6CxhBzQ9qsjZInbSo3F3KUI0dNmf9VYqG0YP9zcL75E7L1GgrGvbboACpiZfq6e6RIhST0JBkOaPs0nBc4jrdd1Xf6I2F5ppxl0ODBmbmtUsccb7UMFQlXLIKtK0hLnT46JXcSzDwYob7+WnGvnuyyCc4RvMnO8Va8wp3ykdp+xKwD0RXV4LDqiFuRPFccO9KH4Q1memzOHE2hn5nCWK3JUcv2H0PdUmax87s7ehCMAC8d1VJBBxXkU= + - secure: C/hGRQ4Fkhy1TB8bYlNXuHu1f8YDp8r+5lQCj8IHiErPih/ac1t8qatgg6K9rBN8G+gyOAoc3yUtxI8I2FV3lgpaRYZRTCTss7II0W39zYLr+nYZsitzgpB0dXg1O8kRVTk7h6eHufmGfui9XLXsZY9Ovg+gYwX0eVyrgYSQlU7WPy+HuvwtwEryKxFTIW7WXe/oKtV6kWLtwISd/kADrhEeUbwi02xS6udBFDLPQwBzFBu7AKc8WiEhpGXEooywewi/0S85f1KnBh43i6/erKw3ltKfgRspwpYyJTnpJphicUvD7CIGMlCcjfm6oOH8TOfSLnEGNu9mrXRchB8izXzHcgQv2DTlpkv5S9RCQnHp4vut39beLjXQu1fMufvz1aSe4hdpSzNwwTn0mNnROm7kicF2CkdoGnXX438k+54C9XQo/VqkD3rno5V/rplZcClss5F2AmA23K4Tl0p6UECO//jdXWcEUiZrXvMrIf7qljvHXmbzrmZEe98oYg0vDPfVoRHn96VE9X3iyzTYDqkkvATvifFqyvbUvBcSUlDa/M6w3cP9IAYEgzbD8+Tq0FPEGIajGhE+Fht7+QVzRaoif++/5l0LxFXDiJIPdGp5GgrnkF+ueSL4ALNxv8EfIxOY6p0u0woYFsN2TObLRaRxNO2Y7XtyetEv3shAUiM= diff --git a/.travis/build.sh b/.travis/build.sh new file mode 100755 index 0000000..4c2f8d2 --- /dev/null +++ b/.travis/build.sh @@ -0,0 +1,7 @@ +#!/bin/sh +dir="$(dirname "$0")" +test "$TRAVIS_SECURE_ENV_VARS" = true \ + -a "$TRAVIS_PULL_REQUEST" = false \ + -a "$TRAVIS_BRANCH" = master && + mvn -Pdeploy-to-imagej deploy --settings "$dir/settings.xml" || + mvn install diff --git a/.travis/notify.sh b/.travis/notify.sh new file mode 100755 index 0000000..b3b239e --- /dev/null +++ b/.travis/notify.sh @@ -0,0 +1,2 @@ +#!/bin/sh +curl -fs "https://jenkins.imagej.net/job/$1/buildWithParameters?token=$TOKEN_NAME&repo=$TRAVIS_REPO_SLUG&commit=$TRAVIS_COMMIT&pr=$TRAVIS_PULL_REQUEST" diff --git a/.travis/settings.xml b/.travis/settings.xml new file mode 100644 index 0000000..71a5630 --- /dev/null +++ b/.travis/settings.xml @@ -0,0 +1,14 @@ + + + + imagej.releases + travis + ${env.MAVEN_PASS} + + + imagej.snapshots + travis + ${env.MAVEN_PASS} + + + diff --git a/pom.xml b/pom.xml index ed88f8f..923b2d4 100644 --- a/pom.xml +++ b/pom.xml @@ -80,8 +80,8 @@ https://github.com/scijava/ui-behaviour - Jenkins - http://jenkins.imagej.net/job/ui-behaviour / + Travis CI + https://travis-ci.org/scijava/ui-behaviour From 65049d4bb224cbe22c42f13d3e989bf8e345a299 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 28 Feb 2017 09:07:39 -0600 Subject: [PATCH 003/184] POM: tidy up Accomplished using: mvn tidy:pom --- pom.xml | 73 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/pom.xml b/pom.xml index 923b2d4..0467c5c 100644 --- a/pom.xml +++ b/pom.xml @@ -10,32 +10,18 @@ ui-behaviour 1.3.1-SNAPSHOT - http://github.com/scijava/ui-behaviour - 2015 Configurable Keys configurable key and mouse event handling - - - 1.8 - - - - - net.sf.trove4j - trove4j - 3.0.3 - - - com.google.code.gson - gson - - - org.yaml - snakeyaml - 1.13 - - + http://github.com/scijava/ui-behaviour + 2015 + + + BSD 2-Clause License + http://opensource.org/licenses/BSD-2-Clause + repo + + @@ -66,13 +52,6 @@ - - - imagej.public - http://maven.imagej.net/content/groups/public - - - scm:git:git://github.com/scijava/ui-behaviour scm:git:git@github.com:scijava/ui-behaviour @@ -84,11 +63,31 @@ https://travis-ci.org/scijava/ui-behaviour - - - BSD 2-Clause License - http://opensource.org/licenses/BSD-2-Clause - repo - - + + 1.8 + + + + + imagej.public + http://maven.imagej.net/content/groups/public + + + + + + net.sf.trove4j + trove4j + 3.0.3 + + + com.google.code.gson + gson + + + org.yaml + snakeyaml + 1.13 + + From 35670a81ed38f30fb73b08c8bb53095bda48e1af Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 28 Feb 2017 09:08:18 -0600 Subject: [PATCH 004/184] POM: update developers and contributors See: http://imagej.net/Team --- pom.xml | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 0467c5c..6d6ec83 100644 --- a/pom.xml +++ b/pom.xml @@ -27,30 +27,43 @@ tpietzsch Tobias Pietzsch - pietzsch@mpi-cbg.de - - MPI-CBG - http://www.mpi-cbg.de/ + https://imagej.net/User:Pietzsch - architect + founder + lead developer + debugger + reviewer + support + maintainer - +1 tinevez Jean-Yves Tinevez - jean-yves.tinevez@pasteur.fr - http://www.pasteur.fr/ip/easysite/pasteur/fr/recherche/plates-formes-technologiques/imagopole/plates-formes-imagopole/la-plate-forme-d-imagerie-dynamique/equipe-pfid/equipe-pfid-jyt - Institut Pasteur - http://www.pasteur.fr/ + https://imagej.net/User:JeanYvesTinevez - architect developer + debugger + reviewer + + + + ctrueden + Curtis Rueden + https://imagej.net/User:Rueden + + maintainer - +1 + + + Ulrik Günther + https://imagej.net/User:Skalarproduktraum + skalarproduktraum + + scm:git:git://github.com/scijava/ui-behaviour From 0e12ebae2bc0eb5463792e18f614c7a90e254ade Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 28 Feb 2017 09:10:04 -0600 Subject: [PATCH 005/184] Update pom-scijava parent to 14.0.0 --- pom.xml | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 6d6ec83..ce33f1b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,20 +5,24 @@ org.scijava pom-scijava - 9.2.0 + 14.0.0 ui-behaviour 1.3.1-SNAPSHOT - Configurable Keys - configurable key and mouse event handling + UI Behaviour + Configurable key and mouse event handling http://github.com/scijava/ui-behaviour 2015 + + SciJava + http://www.scijava.org/ + - BSD 2-Clause License - http://opensource.org/licenses/BSD-2-Clause + Simplified BSD License + https://opensource.org/licenses/BSD-2-Clause repo @@ -65,19 +69,36 @@ + + + SciJava + https://groups.google.com/group/scijava + https://groups.google.com/group/scijava + scijava@googlegroups.com + https://groups.google.com/group/scijava + + + scm:git:git://github.com/scijava/ui-behaviour scm:git:git@github.com:scijava/ui-behaviour HEAD https://github.com/scijava/ui-behaviour + + GitHub Issues + https://github.com/scijava/ui-behaviour/issues + Travis CI https://travis-ci.org/scijava/ui-behaviour - 1.8 + org.scijava.ui.behaviour + bsd_2 + Max Planck Institute of Molecular Cell Biology +and Genetics. From 0af134aa0a3d253f8e99fdbc832743f4310ba6e6 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 28 Feb 2017 09:12:14 -0600 Subject: [PATCH 006/184] Add license blurbs and project license Accomplished using: mvn license:update-file-header license:update-project-license --- LICENSE.txt | 25 +++++++++++++++ .../org/scijava/ui/behaviour/Behaviour.java | 29 +++++++++++++++++ .../scijava/ui/behaviour/BehaviourMap.java | 29 +++++++++++++++++ .../scijava/ui/behaviour/ClickBehaviour.java | 29 +++++++++++++++++ .../scijava/ui/behaviour/DragBehaviour.java | 29 +++++++++++++++++ .../behaviour/GlobalKeyEventDispatcher.java | 29 +++++++++++++++++ .../scijava/ui/behaviour/InputTrigger.java | 29 +++++++++++++++++ .../ui/behaviour/InputTriggerAdder.java | 29 +++++++++++++++++ .../scijava/ui/behaviour/InputTriggerMap.java | 29 +++++++++++++++++ .../ui/behaviour/KeyPressedManager.java | 29 +++++++++++++++++ .../scijava/ui/behaviour/KeyStrokeAdder.java | 29 +++++++++++++++++ .../ui/behaviour/MouseAndKeyHandler.java | 29 +++++++++++++++++ .../scijava/ui/behaviour/ScrollBehaviour.java | 29 +++++++++++++++++ .../ui/behaviour/io/InputTriggerConfig.java | 29 +++++++++++++++++ .../behaviour/io/InputTriggerDescription.java | 31 ++++++++++++++++++- .../io/InputTriggerDescriptionsBuilder.java | 29 +++++++++++++++++ .../ui/behaviour/io/json/JsonConfigIO.java | 29 +++++++++++++++++ .../ui/behaviour/io/yaml/YamlConfigIO.java | 29 +++++++++++++++++ .../behaviour/util/AbstractNamedAction.java | 29 +++++++++++++++++ .../util/AbstractNamedBehaviour.java | 29 +++++++++++++++++ .../scijava/ui/behaviour/util/Actions.java | 29 +++++++++++++++++ .../scijava/ui/behaviour/util/Behaviours.java | 29 +++++++++++++++++ .../behaviour/util/InputActionBindings.java | 29 +++++++++++++++++ .../ui/behaviour/util/RunnableAction.java | 29 +++++++++++++++++ .../util/TriggerBehaviourBindings.java | 29 +++++++++++++++++ .../ui/behaviour/EventsInteractiveTest.java | 29 +++++++++++++++++ .../ui/behaviour/MultiWindowExample.java | 29 +++++++++++++++++ .../scijava/ui/behaviour/UsageExample.java | 29 +++++++++++++++++ .../io/json/JsonInteractiveTest.java | 29 +++++++++++++++++ .../io/yaml/YamlInteractiveTest.java | 29 +++++++++++++++++ 30 files changed, 867 insertions(+), 1 deletion(-) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..91e2bac --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,25 @@ +Copyright (c) 2015 - 2017, Max Planck Institute of Molecular Cell Biology +and Genetics. +All rights reserved. + +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 HOLDER 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. diff --git a/src/main/java/org/scijava/ui/behaviour/Behaviour.java b/src/main/java/org/scijava/ui/behaviour/Behaviour.java index 639eb4f..ee7556f 100644 --- a/src/main/java/org/scijava/ui/behaviour/Behaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/Behaviour.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; public interface Behaviour diff --git a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java index 4f60fcc..74f9514 100644 --- a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java +++ b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.util.HashMap; diff --git a/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java b/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java index d310db4..e6fea17 100644 --- a/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; public interface ClickBehaviour extends Behaviour diff --git a/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java b/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java index 6beb315..bb5ac30 100644 --- a/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.awt.event.MouseListener; diff --git a/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java b/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java index 84e2d12..9c1d3b4 100644 --- a/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java +++ b/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.awt.Component; diff --git a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java index 0019cb6..af8ae81 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.awt.AWTKeyStroke; diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java index 1ac0b56..3e5ab18 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; public interface InputTriggerAdder diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java index 4d4a88e..9013d35 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.util.HashMap; diff --git a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java index 1a37d39..e74c66b 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.awt.event.KeyListener; diff --git a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java index 634e5b5..5584050 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import javax.swing.InputMap; diff --git a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java index 430706a..f963564 100644 --- a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.awt.Component; diff --git a/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java b/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java index 7f7f314..7487c83 100644 --- a/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; public interface ScrollBehaviour extends Behaviour diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index c551e57..02174ea 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io; import java.util.Arrays; diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java index eeb4d38..933f804 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io; import javax.swing.Action; @@ -92,4 +121,4 @@ public void setContexts( final String[] contexts ) else this.contexts = contexts; } -} \ No newline at end of file +} diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java index 004d0f0..789b88e 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io; import java.util.ArrayList; diff --git a/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java index a82cff4..aebfa68 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.json; import java.io.FileReader; diff --git a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java index a27400a..7c5edfa 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.yaml; import java.io.FileReader; diff --git a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java index c70afed..25bad9f 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import javax.swing.AbstractAction; diff --git a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java index cc904ea..7d728da 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import org.scijava.ui.behaviour.Behaviour; diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index 5322444..4b3fee1 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import javax.swing.ActionMap; diff --git a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java index 1c191ac..5ad0ee8 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import org.scijava.ui.behaviour.Behaviour; diff --git a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java index 8fa4727..597712c 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import java.util.ArrayList; diff --git a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java index eaa3b41..0acf65c 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import java.awt.event.ActionEvent; diff --git a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java index ce1ae78..d0cb7c4 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import java.util.ArrayList; diff --git a/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java index ea0c2d5..578cf70 100644 --- a/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.awt.Dimension; diff --git a/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java b/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java index 8e0cb68..26eb424 100644 --- a/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java +++ b/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.awt.Dimension; diff --git a/src/test/java/org/scijava/ui/behaviour/UsageExample.java b/src/test/java/org/scijava/ui/behaviour/UsageExample.java index a68db3c..910f337 100644 --- a/src/test/java/org/scijava/ui/behaviour/UsageExample.java +++ b/src/test/java/org/scijava/ui/behaviour/UsageExample.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.awt.Dimension; diff --git a/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java index 27115f9..f5c39aa 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.json; import java.io.BufferedReader; diff --git a/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java index 8c5ffe6..7e8ff81 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.yaml; import java.io.BufferedReader; From 18e0292c1c279ab1e0a192cd6a811b753f3cde8c Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Wed, 26 Apr 2017 15:40:07 -0500 Subject: [PATCH 007/184] Fix the Travis configuration Without this, failed builds of master trigger another "mvn install". See: https://gist.github.com/ctrueden/ae0f024a0cdf2cb53c915d75b0759553 --- .travis/build.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.travis/build.sh b/.travis/build.sh index 4c2f8d2..8cddb5f 100755 --- a/.travis/build.sh +++ b/.travis/build.sh @@ -1,7 +1,10 @@ #!/bin/sh dir="$(dirname "$0")" -test "$TRAVIS_SECURE_ENV_VARS" = true \ +if [ "$TRAVIS_SECURE_ENV_VARS" = true \ -a "$TRAVIS_PULL_REQUEST" = false \ - -a "$TRAVIS_BRANCH" = master && - mvn -Pdeploy-to-imagej deploy --settings "$dir/settings.xml" || + -a "$TRAVIS_BRANCH" = master ] +then + mvn -Pdeploy-to-imagej deploy --settings "$dir/settings.xml" +else mvn install +fi From 5672cfb800302b89ffeeab772528aa52bf2c29b0 Mon Sep 17 00:00:00 2001 From: Alison Walter Date: Thu, 27 Apr 2017 13:26:35 -0500 Subject: [PATCH 008/184] Fix javadoc errors --- src/main/java/org/scijava/ui/behaviour/util/Actions.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index 4b3fee1..8d2d97d 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -142,8 +142,8 @@ public void install( } /** - * Create and install a new {@link Action} with the specified {@code name} that - * calls the specified {@link Runnable} when triggered. + * Create and install a new {@link javax.swing.Action} with the specified + * {@code name} that calls the specified {@link Runnable} when triggered. * * @param runnable * action to install. From 360aeab4475b732c8852ad3d5d3d37311032d4ee Mon Sep 17 00:00:00 2001 From: Stephan Saalfeld Date: Thu, 22 Jun 2017 00:15:26 -0400 Subject: [PATCH 009/184] use HTTPS url for imagej maven repository --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ce33f1b..6c5fe7a 100644 --- a/pom.xml +++ b/pom.xml @@ -104,7 +104,7 @@ and Genetics. imagej.public - http://maven.imagej.net/content/groups/public + https://maven.imagej.net/content/groups/public From ddc9d0ffe0d038438d0bc1f5db5b775655c84f42 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 5 Oct 2017 16:40:19 -0500 Subject: [PATCH 010/184] Update Travis configuration This will hopefully reduce the need for future en masse updates. --- .travis.yml | 6 +++--- .travis/build.sh | 11 ++--------- .travis/notify.sh | 2 -- 3 files changed, 5 insertions(+), 14 deletions(-) delete mode 100755 .travis/notify.sh diff --git a/.travis.yml b/.travis.yml index d1e3845..5b37890 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,11 @@ language: java jdk: oraclejdk8 branches: - only: master + only: + - master + - "/.*-[0-9]+\\..*/" install: true script: ".travis/build.sh" -after_success: ".travis/notify.sh Travis-Success" -after_failure: ".travis/notify.sh Travis-Failure" env: global: - secure: YRNfBvbeO4779HH3rkuat08sFAhGIFJUNil9iSLO3KuiiS+o940jPQoJUXw2N+U9EtZtl78EeKOLRP9/98Lyt7H8Lh1ml5ELw5eA0cr+PUENoKi2Wygm7OG96bLGydhRGj/thX1gKA8DyveOpNNuSnINTq/zTvqo5dYNTRhmQ9uRAWJ7Iag6UWjXVNQabIf0qrGQ+DHnVtdMq3t8XPdeckaum22Xl1sPem+iPIj0E2jftwDGfEJ4y+7m881+0lUDDsqzZ6ag+YGKrEYg2VeoHJU62/XKbGBgSHfGZb0b88ps0PN8wCv3VYcrNx3hCi2G8awYjg6s+LOs/IOaKX0UsTFf5oexAmxlgT8TMtxtMEG03o/4W/AuppNz5H9kiusvWdBKv2ZfLUTgh2lW4fxpJweBCYVw7bM2na9SOO9bXvjxBHFjmv3f6CxhBzQ9qsjZInbSo3F3KUI0dNmf9VYqG0YP9zcL75E7L1GgrGvbboACpiZfq6e6RIhST0JBkOaPs0nBc4jrdd1Xf6I2F5ppxl0ODBmbmtUsccb7UMFQlXLIKtK0hLnT46JXcSzDwYob7+WnGvnuyyCc4RvMnO8Va8wp3ykdp+xKwD0RXV4LDqiFuRPFccO9KH4Q1memzOHE2hn5nCWK3JUcv2H0PdUmax87s7ehCMAC8d1VJBBxXkU= diff --git a/.travis/build.sh b/.travis/build.sh index 8cddb5f..e939b6c 100755 --- a/.travis/build.sh +++ b/.travis/build.sh @@ -1,10 +1,3 @@ #!/bin/sh -dir="$(dirname "$0")" -if [ "$TRAVIS_SECURE_ENV_VARS" = true \ - -a "$TRAVIS_PULL_REQUEST" = false \ - -a "$TRAVIS_BRANCH" = master ] -then - mvn -Pdeploy-to-imagej deploy --settings "$dir/settings.xml" -else - mvn install -fi +curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/master/travis-build.sh +sh travis-build.sh diff --git a/.travis/notify.sh b/.travis/notify.sh deleted file mode 100755 index b3b239e..0000000 --- a/.travis/notify.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -curl -fs "https://jenkins.imagej.net/job/$1/buildWithParameters?token=$TOKEN_NAME&repo=$TRAVIS_REPO_SLUG&commit=$TRAVIS_COMMIT&pr=$TRAVIS_PULL_REQUEST" From ad019b33c84b29eaa1ee971a4da75edf5af8d505 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 5 Oct 2017 16:40:19 -0500 Subject: [PATCH 011/184] POM: update pom-scijava parent to 17.1.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6c5fe7a..755f39b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.scijava pom-scijava - 14.0.0 + 17.1.1 ui-behaviour From e2a250dc201f76f33f63fa207cbbaf4cd91810ad Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 5 Oct 2017 16:40:19 -0500 Subject: [PATCH 012/184] POM: deploy releases to the ImageJ repository --- pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pom.xml b/pom.xml index 755f39b..d3a0ef5 100644 --- a/pom.xml +++ b/pom.xml @@ -99,6 +99,9 @@ bsd_2 Max Planck Institute of Molecular Cell Biology and Genetics. + + + deploy-to-imagej From 84432bb2794a4177265c6d35d1dcb00b2f71f5da Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 17 Oct 2017 16:14:22 +0200 Subject: [PATCH 013/184] Update comment. --- src/test/java/org/scijava/ui/behaviour/UsageExample.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/org/scijava/ui/behaviour/UsageExample.java b/src/test/java/org/scijava/ui/behaviour/UsageExample.java index 910f337..7104cbb 100644 --- a/src/test/java/org/scijava/ui/behaviour/UsageExample.java +++ b/src/test/java/org/scijava/ui/behaviour/UsageExample.java @@ -165,8 +165,9 @@ public static void main( final String[] args ) adder.put( "click1", "button3", "B | all" ); /* - * See bdv.viewer.TriggerBehaviourBindings for chaining InputMaps and BehaviourMaps. - * (might move here in the future) + * See org.scijava.ui.behaviour.util.InputActionBindings and + * org.scijava.ui.behaviour.util.TriggerBehaviourBindings for chaining + * InputMaps and BehaviourMaps. */ } } From 776e9f16be2a567e747da1ae306e8abbe8211cb6 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 17 Oct 2017 16:24:06 +0200 Subject: [PATCH 014/184] fix javadoc --- .../scijava/ui/behaviour/util/TriggerBehaviourBindings.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java index d0cb7c4..1a7d7cc 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java @@ -57,12 +57,12 @@ public final class TriggerBehaviourBindings { /** - * the root of the {@link InputMap} chain. + * the root of the {@link InputTriggerMap} chain. */ private final InputTriggerMap theInputTriggerMap; /** - * the root of the {@link ActionMap} chain. + * the root of the {@link BehaviourMap} chain. */ private final BehaviourMap theBehaviourMap; @@ -91,7 +91,7 @@ public void addBehaviourMap( final String id, final BehaviourMap behaviourMap ) } /** - * Remove the {@link ActionMap} with the given id from the list. + * Remove the {@link BehaviourMap} with the given id from the list. */ public void removeBehaviourMap( final String id ) { From c990b3ec5aa127345e4254476a2a9ca8381353fc Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 17 Oct 2017 20:01:51 +0200 Subject: [PATCH 015/184] bugfix --- .../java/org/scijava/ui/behaviour/io/InputTriggerConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 02174ea..5089417 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -279,7 +279,7 @@ public int hashCode() @Override public boolean equals( final Object obj ) { - if ( obj == null && !( obj instanceof Input ) ) + if ( obj == null || !( obj instanceof Input ) ) return false; final Input i = ( Input ) obj; return i.trigger.equals( trigger ) && i.behaviour.equals( behaviour ) && i.contexts.equals( contexts ); From 95819b44133b8b9be25438175f5b40c243b60f09 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 17 Oct 2017 20:04:30 +0200 Subject: [PATCH 016/184] simplify --- .../ui/behaviour/io/InputTriggerConfig.java | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 5089417..7e6367f 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -72,12 +72,7 @@ public InputTriggerConfig( final Collection< InputTriggerDescription > keyMappin final InputTrigger trigger = InputTrigger.getFromString( triggerStr ); final Input input = new Input( trigger, behaviour, contexts ); - Set< Input > inputs = actionToInputsMap.get( input.behaviour ); - if ( inputs == null ) - { - inputs = new HashSet<>(); - actionToInputsMap.put( input.behaviour, inputs ); - } + Set< Input > inputs = actionToInputsMap.computeIfAbsent( input.behaviour, k -> new HashSet<>() ); inputs.add( input ); } } @@ -317,12 +312,7 @@ void addMap( final InputTriggerMap map, final String context ) for ( final String behaviourName : behaviours ) { - Set< Input > inputs = actionToInputsMap.get( behaviourName ); - if ( inputs == null ) - { - inputs = new HashSet<>(); - actionToInputsMap.put( behaviourName, inputs ); - } + Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new HashSet<>() ); boolean added = false; for ( final Input input : inputs ) @@ -358,12 +348,7 @@ void addMap( final InputMap map, final String context ) final InputTrigger trigger = InputTrigger.getFromString( key.toString() ); final String behaviourName = map.get( key ).toString(); - Set< Input > inputs = actionToInputsMap.get( behaviourName ); - if ( inputs == null ) - { - inputs = new HashSet<>(); - actionToInputsMap.put( behaviourName, inputs ); - } + Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new HashSet<>() ); boolean added = false; for ( final Input input : inputs ) From e7d62d4a48225fd5da4adaddd08767c04ea8bed5 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Fri, 20 Oct 2017 21:19:00 +0200 Subject: [PATCH 017/184] Read-only views of InputMap etc with their own parent The idea is that you can have multiple "copies" of the same InputMap and re-use it across multiple KeyBindings/InputTriggerBindings --- .../ui/behaviour/util/WrappedActionMap.java | 77 ++++++++++++ .../behaviour/util/WrappedBehaviourMap.java | 96 ++++++++++++++ .../ui/behaviour/util/WrappedInputMap.java | 77 ++++++++++++ .../util/WrappedInputTriggerMap.java | 117 ++++++++++++++++++ 4 files changed, 367 insertions(+) create mode 100644 src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java create mode 100644 src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java create mode 100644 src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java create mode 100644 src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java new file mode 100644 index 0000000..0af31d4 --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java @@ -0,0 +1,77 @@ +package org.scijava.ui.behaviour.util; + +import javax.swing.Action; +import javax.swing.ActionMap; + +/** + * A view of the specified {@link ActionMap} that can have its own parent. The + * wrapped {@code ActionMap} should not have a parent!? + */ +public class WrappedActionMap extends ActionMap +{ + private static final long serialVersionUID = 1L; + + private final ActionMap actionMap; + + private ActionMap parent; + + public WrappedActionMap( final ActionMap inputMap ) + { + this.actionMap = inputMap; + } + + @Override + public void setParent( final ActionMap map ) + { + parent = map; + } + + @Override + public ActionMap getParent() + { + return parent; + } + + @Override + public void put( final Object key, final Action action ) + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public Action get( final Object key ) + { + final Action value = actionMap.get( key ); + if ( value == null ) + { + final ActionMap parent = getParent(); + if ( parent != null ) + return parent.get( key ); + } + return value; + } + + @Override + public void remove( final Object key ) + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public void clear() + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public Object[] keys() + { + return actionMap.keys(); + } + + @Override + public int size() + { + return actionMap.size(); + } +} diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java new file mode 100644 index 0000000..87dfa50 --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java @@ -0,0 +1,96 @@ +package org.scijava.ui.behaviour.util; + +import java.util.HashMap; +import java.util.Map; + +import org.scijava.ui.behaviour.Behaviour; +import org.scijava.ui.behaviour.BehaviourMap; + +/** + * A view of the specified {@link BehaviourMap} that can have its own parent. + * The wrapped {@code BehaviourMap} should not have a parent!? + */ +public class WrappedBehaviourMap extends BehaviourMap +{ + private final BehaviourMap behaviourMap; + + private BehaviourMap parent; + + private int expectedParentModCount; + + public WrappedBehaviourMap( final BehaviourMap behaviourMap ) + { + this.behaviourMap = behaviourMap; + parent = null; + expectedParentModCount = 0; + } + + @Override + public void setParent( final BehaviourMap map ) + { + parent = map; + if ( map != null ) + expectedParentModCount = parent.modCount(); + } + + @Override + public BehaviourMap getParent() + { + return parent; + } + + @Override + public synchronized void put( final String key, final Behaviour behaviour ) + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public synchronized Behaviour get( final String key ) + { + final Behaviour behaviour = behaviourMap.get( key ); + if ( behaviour == null && parent != null ) + return parent.get( key ); + else + return behaviour; + } + + @Override + public synchronized void remove( final String key ) + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public synchronized void clear() + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public synchronized Map< String, Behaviour > getAllBindings() + { + final Map< String, Behaviour > allBindings = ( parent == null ) ? new HashMap<>() : parent.getAllBindings(); + + for ( final Map.Entry< String, Behaviour > entry : behaviourMap.getAllBindings().entrySet() ) + allBindings.put( entry.getKey(), entry.getValue() ); + + return allBindings; + } + + @Override + public int modCount() + { + if ( parent != null ) + { + final int m = parent.modCount(); + if ( m != expectedParentModCount ) + { + expectedParentModCount = m; + behaviourMap.remove( null ); // hack to bump + // behaviourMap.modCount + } + } + return behaviourMap.modCount(); + } +} diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java new file mode 100644 index 0000000..417c62b --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java @@ -0,0 +1,77 @@ +package org.scijava.ui.behaviour.util; + +import javax.swing.InputMap; +import javax.swing.KeyStroke; + +/** + * A view of the specified {@link InputMap} that can have its own parent. The + * wrapped {@code InputMap} should not have a parent!? + */ +public class WrappedInputMap extends InputMap +{ + private static final long serialVersionUID = 1L; + + private final InputMap inputMap; + + private InputMap parent; + + public WrappedInputMap( final InputMap inputMap ) + { + this.inputMap = inputMap; + } + + @Override + public void setParent( final InputMap map ) + { + parent = map; + } + + @Override + public InputMap getParent() + { + return parent; + } + + @Override + public void put( final KeyStroke keyStroke, final Object actionMapKey ) + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public Object get( final KeyStroke keyStroke ) + { + final Object value = inputMap.get( keyStroke ); + if ( value == null ) + { + final InputMap parent = getParent(); + if ( parent != null ) + return parent.get( keyStroke ); + } + return value; + } + + @Override + public void remove( final KeyStroke key ) + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public void clear() + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public KeyStroke[] keys() + { + return inputMap.keys(); + } + + @Override + public int size() + { + return inputMap.size(); + } +} diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java new file mode 100644 index 0000000..ae4caac --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java @@ -0,0 +1,117 @@ +package org.scijava.ui.behaviour.util; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.scijava.ui.behaviour.InputTrigger; +import org.scijava.ui.behaviour.InputTriggerMap; + +/** + * A view of the specified {@link InputTriggerMap} that can have its own parent. + * The wrapped {@code InputTriggerMap} should not have a parent!? + */ +public class WrappedInputTriggerMap extends InputTriggerMap +{ + private final InputTriggerMap inputTriggerMap; + + private InputTriggerMap parent; + + private int expectedParentModCount; + + public WrappedInputTriggerMap( final InputTriggerMap inputTriggerMap ) + { + this.inputTriggerMap = inputTriggerMap; + parent = null; + expectedParentModCount = 0; + } + + @Override + public void setParent( final InputTriggerMap map ) + { + parent = map; + if ( map != null ) + expectedParentModCount = parent.modCount(); + } + + @Override + public InputTriggerMap getParent() + { + return parent; + } + + @Override + public synchronized void put( final InputTrigger inputTrigger, final String behaviourKey ) + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public synchronized Set< String > get( final InputTrigger inputTrigger ) + { + Set< String > keys = null; + if ( parent != null ) + keys = parent.get( inputTrigger ); + else + keys = new HashSet<>(); + keys.addAll( inputTriggerMap.get( inputTrigger ) ); + return keys; + } + + @Override + public synchronized void remove( final InputTrigger inputTrigger, final String behaviourKey ) + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public synchronized void removeAll( final InputTrigger inputTrigger ) + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public synchronized void clear() + { + throw new UnsupportedOperationException( getClass().getSimpleName() + " cannot be modified." ); + } + + @Override + public synchronized Map< InputTrigger, Set< String > > getAllBindings() + { + final Map< InputTrigger, Set< String > > allBindings; + if ( parent != null ) + allBindings = parent.getAllBindings(); + else + allBindings = new HashMap<>(); + + for ( final Map.Entry< InputTrigger, Set< String > > entry : inputTriggerMap.getAllBindings().entrySet() ) + { + final InputTrigger inputTrigger = entry.getKey(); + if ( entry.getValue() == null || entry.getValue().isEmpty() ) + continue; + + final Set< String > behaviourKeys = allBindings.computeIfAbsent( inputTrigger, k -> new HashSet<>() ); + behaviourKeys.addAll( entry.getValue() ); + } + + return allBindings; + } + + @Override + public int modCount() + { + if ( parent != null ) + { + final int m = parent.modCount(); + if ( m != expectedParentModCount ) + { + expectedParentModCount = m; + inputTriggerMap.remove( null, null ); // hack to bump + // inputTriggerMap.modCount + } + } + return inputTriggerMap.modCount(); + } +} From 7ba652307e2db1750b2b701e112b38c271d0ce4a Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 24 Oct 2017 13:37:26 +0200 Subject: [PATCH 018/184] fix typo --- .../java/org/scijava/ui/behaviour/io/InputTriggerConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 7e6367f..f334c78 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -356,7 +356,7 @@ void addMap( final InputMap map, final String context ) if ( input.trigger.equals( trigger ) ) { /* - * the trigger -> behavioiur binding already exists. + * the trigger -> behaviour binding already exists. * just add the new context */ input.contexts.add( context ); From 30643ecc5ae485602858da1e62dc814930a6f130 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 24 Oct 2017 13:40:13 +0200 Subject: [PATCH 019/184] InputTriggerConfig methods to add individual trigger->behaviour bindings --- .../ui/behaviour/io/InputTriggerConfig.java | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index f334c78..9b15b25 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -84,7 +84,6 @@ public InputTriggerAdder inputTriggerAdder( final InputTriggerMap map, final Str return new InputTriggerAdderImp( map, this, contexts ); } - @Override public KeyStrokeAdder keyStrokeAdder( final InputMap map, final String ... contexts ) { @@ -299,6 +298,39 @@ Set< InputTrigger > getInputs( final String behaviourName, final Set< String > c return triggers; } + void add( final String trigger, final String behaviourName, final String context ) + { + add( InputTrigger.getFromString( trigger ), behaviourName, context ); + } + + void add( final InputTrigger trigger, final String behaviourName, final String context ) + { + add( trigger, behaviourName, Collections.singleton( context ) ); + } + + synchronized void add( final InputTrigger trigger, final String behaviourName, final Set< String > contexts ) + { + Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new HashSet<>() ); + for ( final Input input : inputs ) + { + if ( input.trigger.equals( trigger ) ) + { + /* + * the trigger -> behaviour binding already exists. + * just add the new context + */ + input.contexts.addAll( contexts ); + return; + } + } + + /* + * the trigger -> behaviour binding does not exist. + * add it + */ + inputs.add( new Input( trigger, behaviourName, contexts ) ); + } + /* * creating InputTriggerConfig from InputTriggerMaps and InputMaps */ From 78ac96be5d78806d98b602dbbdb73d70fdf90d4a Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 24 Oct 2017 13:54:15 +0200 Subject: [PATCH 020/184] Add provided default triggers to InputTriggerConfig if they are used --- .../ui/behaviour/io/InputTriggerConfig.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 9b15b25..479efd4 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -7,13 +7,13 @@ * %% * 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 @@ -36,10 +36,8 @@ import java.util.HashSet; import java.util.Map.Entry; import java.util.Set; - import javax.swing.InputMap; import javax.swing.KeyStroke; - import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.InputTriggerAdder; import org.scijava.ui.behaviour.InputTriggerMap; @@ -133,11 +131,17 @@ public void put( final String behaviourName, final InputTrigger ... defaultTrigg } else if ( defaultTriggers.length > 0 ) { - if ( defaultTriggers[ 0 ].equals( InputTrigger.NOT_MAPPED )) + if ( defaultTriggers[ 0 ].equals( InputTrigger.NOT_MAPPED ) ) + { + config.add( InputTrigger.NOT_MAPPED, behaviourName, contexts ); return; + } for ( final InputTrigger trigger : defaultTriggers ) + { + config.add( trigger, behaviourName, contexts ); map.put( trigger, behaviourName ); + } } else { @@ -213,7 +217,10 @@ public void put( final String actionName, final KeyStroke... defaultKeyStrokes ) if ( defaultKeyStrokes.length > 0 ) { for ( final KeyStroke keyStroke : defaultKeyStrokes ) + { + config.add( InputTrigger.getFromString( keyStroke.toString() ), actionName, contexts ); map.put( keyStroke, actionName ); + } } else { From 2a50a9e34b00f9d8dc2c882a35e3d3bd615ba2a5 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 24 Oct 2017 14:03:35 +0200 Subject: [PATCH 021/184] Construct InputTriggerDescriptionsBuilder from existing InputTriggerConfig --- .../behaviour/io/InputTriggerDescriptionsBuilder.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java index 789b88e..edcfb6f 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java @@ -7,13 +7,13 @@ * %% * 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 @@ -53,7 +53,12 @@ public class InputTriggerDescriptionsBuilder public InputTriggerDescriptionsBuilder() { - config = new InputTriggerConfig(); + this( new InputTriggerConfig() ); + } + + public InputTriggerDescriptionsBuilder( final InputTriggerConfig config ) + { + this.config = config; } public List< InputTriggerDescription > getDescriptions() From 5f81493640f4ff011b469b156434e605a55f0629 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 24 Oct 2017 15:26:29 +0200 Subject: [PATCH 022/184] Add method to update Actions and Behaviours with changed keyconfig --- .../scijava/ui/behaviour/BehaviourMap.java | 7 ++++++ .../scijava/ui/behaviour/util/Actions.java | 23 +++++++++++++++++-- .../scijava/ui/behaviour/util/Behaviours.java | 23 +++++++++++++++++-- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java index 74f9514..9a3c2c8 100644 --- a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java +++ b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java @@ -30,9 +30,11 @@ package org.scijava.ui.behaviour; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import javax.swing.ActionMap; /** @@ -156,6 +158,11 @@ public synchronized Map< String, Behaviour > getAllBindings() return allBindings; } + public synchronized Set< String > keys() + { + return new HashSet<>( behaviours.keySet() ); + } + public int modCount() { if ( parent != null ) diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index 8d2d97d..216cab1 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -51,9 +51,11 @@ public class Actions private final ActionMap actionMap; - protected final KeyStrokeAdder.Factory keyConfig; + private final String[] keyConfigContexts; - protected final KeyStrokeAdder keyStrokeAdder; + protected KeyStrokeAdder.Factory keyConfig; + + protected KeyStrokeAdder keyStrokeAdder; /** * Construct with new, empty {@link InputMap} and {@link ActionMap}. Actions @@ -103,6 +105,7 @@ public Actions( this.actionMap = actionMap; this.inputMap = inputMap; this.keyConfig = keyConfig; + this.keyConfigContexts = keyConfigContexts; keyStrokeAdder = keyConfig.keyStrokeAdder( inputMap, keyConfigContexts ); } @@ -174,4 +177,20 @@ public void namedAction( final AbstractNamedAction action, final String... defau keyStrokeAdder.put( action.name(), defaultKeyStrokes ); action.put( actionMap ); } + + /** + * Clears the {@link InputMap} and re-adds all ({@code String}) action keys + * from {@link ActionMap} using the provided {@code keyConfig}. + * + * @param keyConfig + * the new keyConfig + */ + public void updateKeyConfig( final KeyStrokeAdder.Factory keyConfig ) + { + this.keyConfig = keyConfig; + keyStrokeAdder = keyConfig.keyStrokeAdder( inputMap, keyConfigContexts ); + inputMap.clear(); + for ( final Object o : actionMap.keys() ) + keyStrokeAdder.put( ( String ) o ); + } } diff --git a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java index 5ad0ee8..2b32d2e 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java @@ -51,9 +51,11 @@ public class Behaviours private final BehaviourMap behaviourMap; - protected final InputTriggerAdder.Factory keyConfig; + private final String[] keyConfigContexts; - protected final InputTriggerAdder inputTriggerAdder; + protected InputTriggerAdder.Factory keyConfig; + + protected InputTriggerAdder inputTriggerAdder; /** * Construct with new, empty {@link InputTriggerMap} and @@ -103,6 +105,7 @@ public Behaviours( this.inputTriggerMap = inputTriggerMap; this.behaviourMap = behaviourMap; this.keyConfig = keyConfig; + this.keyConfigContexts = keyConfigContexts; inputTriggerAdder = keyConfig.inputTriggerAdder( inputTriggerMap, keyConfigContexts ); } @@ -153,4 +156,20 @@ public void namedBehaviour( final AbstractNamedBehaviour behaviour, final String inputTriggerAdder.put( behaviour.name(), defaultTriggers ); behaviour.put( behaviourMap ); } + + /** + * Clears the {@link InputTriggerMap} and re-adds all behaviour keys from + * {@link BehaviourMap} using the provided {@code keyConfig}. + * + * @param keyConfig + * the new keyConfig + */ + public void updateKeyConfig( final InputTriggerAdder.Factory keyConfig ) + { + this.keyConfig = keyConfig; + inputTriggerAdder = keyConfig.inputTriggerAdder( inputTriggerMap, keyConfigContexts ); + inputTriggerMap.clear(); + for ( final String behaviourName : behaviourMap.keys() ) + inputTriggerAdder.put( behaviourName ); + } } From e3d15e516af923f0e11393f55b8e2b5da086423a Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 1 Nov 2017 10:42:38 +0100 Subject: [PATCH 023/184] Use LinkedHashMap/Set in InputTriggerConfig to maintain insertion order of mappings --- .../ui/behaviour/io/InputTriggerConfig.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 479efd4..789c111 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -32,8 +32,9 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.Map.Entry; import java.util.Set; import javax.swing.InputMap; @@ -45,16 +46,16 @@ public class InputTriggerConfig implements InputTriggerAdder.Factory, KeyStrokeAdder.Factory { - final HashMap< String, Set< Input > > actionToInputsMap; + final LinkedHashMap< String, Set< Input > > actionToInputsMap; public InputTriggerConfig() { - actionToInputsMap = new HashMap<>(); + actionToInputsMap = new LinkedHashMap<>(); } public InputTriggerConfig( final Collection< InputTriggerDescription > keyMappings ) throws IllegalArgumentException { - actionToInputsMap = new HashMap<>(); + actionToInputsMap = new LinkedHashMap<>(); if ( keyMappings == null ) return; @@ -70,7 +71,7 @@ public InputTriggerConfig( final Collection< InputTriggerDescription > keyMappin final InputTrigger trigger = InputTrigger.getFromString( triggerStr ); final Input input = new Input( trigger, behaviour, contexts ); - Set< Input > inputs = actionToInputsMap.computeIfAbsent( input.behaviour, k -> new HashSet<>() ); + Set< Input > inputs = actionToInputsMap.computeIfAbsent( input.behaviour, k -> new LinkedHashSet<>() ); inputs.add( input ); } } @@ -292,10 +293,10 @@ InputTriggerDescription getDescription() } } - Set< InputTrigger > getInputs( final String behaviourName, final Set< String > contexts ) + public Set< InputTrigger > getInputs( final String behaviourName, final Set< String > contexts ) { final Set< Input > inputs = actionToInputsMap.get( behaviourName ); - final Set< InputTrigger > triggers = new HashSet<>(); + final Set< InputTrigger > triggers = new LinkedHashSet<>(); if ( inputs != null ) { for ( final Input input : inputs ) @@ -317,7 +318,7 @@ void add( final InputTrigger trigger, final String behaviourName, final String c synchronized void add( final InputTrigger trigger, final String behaviourName, final Set< String > contexts ) { - Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new HashSet<>() ); + Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); for ( final Input input : inputs ) { if ( input.trigger.equals( trigger ) ) @@ -351,7 +352,7 @@ void addMap( final InputTriggerMap map, final String context ) for ( final String behaviourName : behaviours ) { - Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new HashSet<>() ); + Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); boolean added = false; for ( final Input input : inputs ) @@ -387,7 +388,7 @@ void addMap( final InputMap map, final String context ) final InputTrigger trigger = InputTrigger.getFromString( key.toString() ); final String behaviourName = map.get( key ).toString(); - Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new HashSet<>() ); + Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); boolean added = false; for ( final Input input : inputs ) From 0b312aca2e080fe53ab870060c9deb2fa2e63a36 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 1 Nov 2017 10:58:02 +0100 Subject: [PATCH 024/184] Bump to next development cycle Signed-off-by: Tobias Pietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d3a0ef5..022894f 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.3.1-SNAPSHOT + 1.4.1-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 5185f7525ce41227d5aa913ca3842e31f3e43651 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Mon, 23 Oct 2017 18:05:33 +0200 Subject: [PATCH 025/184] WIP: Visual editor based on JTable and co. --- .../ui/behaviour/io/VisualEditorPanel.java | 420 ++++++++++++++++++ 1 file changed, 420 insertions(+) create mode 100644 src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java new file mode 100644 index 0000000..9bde5cd --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -0,0 +1,420 @@ +package org.scijava.ui.behaviour.io; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.FlowLayout; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +import javax.swing.ScrollPaneConstants; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.AbstractTableModel; + +import org.scijava.ui.behaviour.InputTrigger; +import org.scijava.ui.behaviour.io.InputTriggerConfig.Input; +import org.scijava.ui.behaviour.io.yaml.YamlConfigIO; + +public class VisualEditorPanel extends JPanel +{ + private static final long serialVersionUID = 1L; + + private JTextField textFieldFilter; + + private JTextField textFieldBinding; + + private InputTriggerConfig config; + + private Set< String > actions; + + private Set< String > contexts; + + private final MyTableModel tableModel; + + /** + * Create the panel. + */ + public VisualEditorPanel( final InputTriggerConfig config, final Set< String > actions, final Set< String > contexts ) + { + this.config = config; + this.actions = actions; + this.contexts = contexts; + + /* + * GUI + */ + + setLayout( new BorderLayout( 0, 0 ) ); + + textFieldFilter = new JTextField(); + add( textFieldFilter, BorderLayout.NORTH ); + textFieldFilter.setColumns( 10 ); + + final JPanel panelEditor = new JPanel(); + add( panelEditor, BorderLayout.SOUTH ); + panelEditor.setLayout( new BorderLayout( 0, 0 ) ); + + final JPanel panelCommandButtons = new JPanel(); + panelEditor.add( panelCommandButtons, BorderLayout.NORTH ); + panelCommandButtons.setLayout( new BoxLayout( panelCommandButtons, BoxLayout.X_AXIS ) ); + + final JButton btnCopyCommand = new JButton( "Copy binding" ); + panelCommandButtons.add( btnCopyCommand ); + + final JButton btnUnbindAction = new JButton( "Unbind action" ); + panelCommandButtons.add( btnUnbindAction ); + + final JButton btnDeleteAction = new JButton( "Delete binding" ); + panelCommandButtons.add( btnDeleteAction ); + + final Component horizontalGlue = Box.createHorizontalGlue(); + panelCommandButtons.add( horizontalGlue ); + + final JButton btnExportCsv = new JButton( "Export CSV" ); + panelCommandButtons.add( btnExportCsv ); + + final JPanel panelCommandEditor = new JPanel(); + panelEditor.add( panelCommandEditor, BorderLayout.CENTER ); + final GridBagLayout gbl_panelCommandEditor = new GridBagLayout(); + gbl_panelCommandEditor.columnWidths = new int[] { 30, 100, 30, 0, 0 }; + gbl_panelCommandEditor.rowHeights = new int[] { 20, 20, 20 }; + gbl_panelCommandEditor.columnWeights = new double[] { 0.0, 1.0, 0.0, 1.0, 0.0 }; + gbl_panelCommandEditor.rowWeights = new double[] { 0.0, 0.0, 0.0 }; + panelCommandEditor.setLayout( gbl_panelCommandEditor ); + + final JLabel lblName = new JLabel( "Name:" ); + final GridBagConstraints gbc_lblName = new GridBagConstraints(); + gbc_lblName.insets = new Insets( 0, 0, 5, 5 ); + gbc_lblName.anchor = GridBagConstraints.WEST; + gbc_lblName.gridx = 0; + gbc_lblName.gridy = 0; + panelCommandEditor.add( lblName, gbc_lblName ); + + final JLabel labelActionName = new JLabel( "<>" ); + final GridBagConstraints gbc_labelActionName = new GridBagConstraints(); + gbc_labelActionName.insets = new Insets( 0, 0, 5, 5 ); + gbc_labelActionName.gridx = 1; + gbc_labelActionName.gridy = 0; + panelCommandEditor.add( labelActionName, gbc_labelActionName ); + + final JLabel lblBinding = new JLabel( "Binding:" ); + final GridBagConstraints gbc_lblBinding = new GridBagConstraints(); + gbc_lblBinding.anchor = GridBagConstraints.WEST; + gbc_lblBinding.insets = new Insets( 0, 0, 5, 5 ); + gbc_lblBinding.gridx = 2; + gbc_lblBinding.gridy = 0; + panelCommandEditor.add( lblBinding, gbc_lblBinding ); + + textFieldBinding = new JTextField(); + final GridBagConstraints gbc_textFieldBinding = new GridBagConstraints(); + gbc_textFieldBinding.insets = new Insets( 0, 0, 5, 5 ); + gbc_textFieldBinding.fill = GridBagConstraints.HORIZONTAL; + gbc_textFieldBinding.gridx = 3; + gbc_textFieldBinding.gridy = 0; + panelCommandEditor.add( textFieldBinding, gbc_textFieldBinding ); + textFieldBinding.setColumns( 10 ); + + final JButton buttonSpecialChar = new JButton( "<" ); + final GridBagConstraints gbc_buttonSpecialChar = new GridBagConstraints(); + gbc_buttonSpecialChar.insets = new Insets( 0, 0, 5, 0 ); + gbc_buttonSpecialChar.gridx = 4; + gbc_buttonSpecialChar.gridy = 0; + panelCommandEditor.add( buttonSpecialChar, gbc_buttonSpecialChar ); + + final JLabel lblDescription = new JLabel( "Description:" ); + final GridBagConstraints gbc_lblDescription = new GridBagConstraints(); + gbc_lblDescription.insets = new Insets( 0, 0, 5, 5 ); + gbc_lblDescription.anchor = GridBagConstraints.WEST; + gbc_lblDescription.gridx = 0; + gbc_lblDescription.gridy = 1; + panelCommandEditor.add( lblDescription, gbc_lblDescription ); + + final JLabel labelActionDescription = new JLabel( "<>" ); + final GridBagConstraints gbc_labelActionDescription = new GridBagConstraints(); + gbc_labelActionDescription.gridheight = 2; + gbc_labelActionDescription.insets = new Insets( 0, 0, 0, 5 ); + gbc_labelActionDescription.gridx = 1; + gbc_labelActionDescription.gridy = 1; + panelCommandEditor.add( labelActionDescription, gbc_labelActionDescription ); + + final JLabel lblContext = new JLabel( "Context:" ); + final GridBagConstraints gbc_lblContext = new GridBagConstraints(); + gbc_lblContext.anchor = GridBagConstraints.WEST; + gbc_lblContext.insets = new Insets( 0, 0, 5, 5 ); + gbc_lblContext.gridx = 2; + gbc_lblContext.gridy = 1; + panelCommandEditor.add( lblContext, gbc_lblContext ); + + final JTextField txtfieldContext = new JTextField(); + final GridBagConstraints gbc_comboBoxContext = new GridBagConstraints(); + gbc_comboBoxContext.gridwidth = 2; + gbc_comboBoxContext.insets = new Insets( 0, 0, 5, 0 ); + gbc_comboBoxContext.fill = GridBagConstraints.HORIZONTAL; + gbc_comboBoxContext.gridx = 3; + gbc_comboBoxContext.gridy = 1; + panelCommandEditor.add( txtfieldContext, gbc_comboBoxContext ); + + final JLabel lblConflicts = new JLabel( "Conflicts:" ); + final GridBagConstraints gbc_lblConflicts = new GridBagConstraints(); + gbc_lblConflicts.insets = new Insets( 0, 0, 0, 5 ); + gbc_lblConflicts.anchor = GridBagConstraints.WEST; + gbc_lblConflicts.gridx = 2; + gbc_lblConflicts.gridy = 2; + panelCommandEditor.add( lblConflicts, gbc_lblConflicts ); + + final JLabel lblConflict = new JLabel( "TODO" ); + final GridBagConstraints gbc_lblConflict = new GridBagConstraints(); + gbc_lblConflict.gridwidth = 2; + gbc_lblConflict.gridx = 3; + gbc_lblConflict.gridy = 2; + panelCommandEditor.add( lblConflict, gbc_lblConflict ); + + final JPanel panelButtons = new JPanel(); + panelEditor.add( panelButtons, BorderLayout.SOUTH ); + final FlowLayout flowLayout = ( FlowLayout ) panelButtons.getLayout(); + flowLayout.setAlignment( FlowLayout.TRAILING ); + + final JButton btnRestore = new JButton( "Restore" ); + panelButtons.add( btnRestore ); + + final JButton btnApply = new JButton( "Apply" ); + panelButtons.add( btnApply ); + + final JScrollPane scrollPane = new JScrollPane(); + scrollPane.setVerticalScrollBarPolicy( ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS ); + scrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER ); + add( scrollPane, BorderLayout.CENTER ); + + tableModel = new MyTableModel( config.actionToInputsMap ); + final JTable tableBindings = new JTable( tableModel ); + tableBindings.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); + tableBindings.setFillsViewportHeight( true ); + tableBindings.setAutoResizeMode( JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS ); + tableBindings.getSelectionModel().addListSelectionListener( new ListSelectionListener() + { + @Override + public void valueChanged( final ListSelectionEvent e ) + { + if ( e.getValueIsAdjusting() ) + return; + + final int row = tableBindings.getSelectedRow(); + if ( row < 0 ) + return; + + final String action = tableModel.actions.get( row ); + final InputTrigger trigger = tableModel.bindings.get( row ); + final List< String > contexts = new ArrayList<>( tableModel.contexts.get( row ) ); + contexts.sort( null ); + + labelActionName.setText( action ); + labelActionDescription.setText( "TODO" ); + textFieldBinding.setText( trigger.toString() ); + if ( contexts.isEmpty() ) + { + lblContext.setText( "" ); + } + else + { + final StringBuilder str = new StringBuilder(); + str.append( contexts.get( 0 ) ); + for ( int i = 1; i < contexts.size(); i++ ) + str.append( ", " + contexts.get( i ) ); + txtfieldContext.setText( str.toString() ); + } + + } + } ); + scrollPane.setViewportView( tableBindings ); + + } + + /* + * INNER CLASSES + */ + + private static class MyTableModel extends AbstractTableModel + { + + private static final long serialVersionUID = 1L; + + private static final String[] TABLE_HEADERS = new String[] { "Action", "Binding", "Contexts" }; + + private final List< String > actions; + + private final List< InputTrigger > bindings; + + private final List< Set< String > > contexts; + + public MyTableModel( final Map< String, Set< Input > > actionToInputsMap ) + { + this.actions = new ArrayList<>(); + this.bindings = new ArrayList<>(); + this.contexts = new ArrayList<>(); + + final List< String > sortedActions = new ArrayList<>( actionToInputsMap.keySet() ); + sortedActions.sort( null ); + final InputComparator inputComparator = new InputComparator(); + for ( final String action : sortedActions ) + { + final List< Input > sortedInputs = new ArrayList<>( actionToInputsMap.get( action ) ); + sortedInputs.sort( inputComparator ); + for ( final Input input : sortedInputs ) + { + actions.add( action ); + bindings.add( input.trigger ); + contexts.add( input.contexts ); + } + } + } + + @Override + public int getRowCount() + { + return actions.size(); + } + + @Override + public int getColumnCount() + { + return 3; + } + + @Override + public Object getValueAt( final int rowIndex, final int columnIndex ) + { + switch ( columnIndex ) + { + case 0: + return actions.get( rowIndex ); + case 1: + return bindings.get( rowIndex ); + case 2: + return contexts.get( rowIndex ); + default: + throw new NoSuchElementException( "Cannot access column " + columnIndex + " in this model." ); + } + } + + @Override + public String getColumnName( final int column ) + { + return TABLE_HEADERS[ column ]; + } + } + + private static final class InputComparator implements Comparator< Input > + { + + @Override + public int compare( final Input o1, final Input o2 ) + { + return o1.trigger.toString().compareTo( o2.trigger.toString() ); + } + + } + + /* + * DEMO METHODS. + */ + + private static InputTriggerConfig getDemoConfig() + { + final StringReader reader = new StringReader( "---\n" + + "- !mapping" + "\n" + + " action: fluke" + "\n" + + " contexts: [all]" + "\n" + + " triggers: [F]" + "\n" + + "- !mapping" + "\n" + + " action: drag1" + "\n" + + " contexts: [all]" + "\n" + + " triggers: [button1, G]" + "\n" + + "- !mapping" + "\n" + + " action: scroll1" + "\n" + + " contexts: [all]" + "\n" + + " triggers: [scroll]" + "\n" + + "- !mapping" + "\n" + + " action: scroll1" + "\n" + + " contexts: [trackscheme, mamut]" + "\n" + + " triggers: [shift D]" + "\n" + + "" ); + final List< InputTriggerDescription > triggers = YamlConfigIO.read( reader ); + final InputTriggerConfig config = new InputTriggerConfig( triggers ); + return config; + } + + private static Set< String > getDemoActions() + { + final Set< String > actions = new HashSet<>(); + actions.add( "drag1" ); + actions.add( "scroll1" ); + actions.add( "destroy the world" ); + actions.add( "awake the dragons" ); + actions.add( "make some coffee" ); + return actions; + } + + private static Set< String > getDemoContexts() + { + final Set< String > contexts = new HashSet<>(); + contexts.add( "all" ); + contexts.add( "mamut" ); + contexts.add( "trackscheme" ); + return contexts; + } + + /** + * Launch the application. + * + * @throws UnsupportedLookAndFeelException + * @throws IllegalAccessException + * @throws InstantiationException + * @throws ClassNotFoundException + */ + public static void main( final String[] args ) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException + { + UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() ); + EventQueue.invokeLater( new Runnable() + { + @Override + public void run() + { + try + { + final JFrame frame = new JFrame( "Behaviour Key bindings editor" ); + final VisualEditorPanel editorPanel = new VisualEditorPanel( getDemoConfig(), getDemoActions(), getDemoContexts() ); + frame.getContentPane().add( editorPanel ); + frame.pack(); + frame.setVisible( true ); + } + catch ( final Exception e ) + { + e.printStackTrace(); + } + } + } ); + } + +} From 8536c2fdcefdcabbe8c4297513c14c0941f2e061 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Tue, 24 Oct 2017 12:28:22 +0200 Subject: [PATCH 026/184] Visual-editor: show all possible actions in the table, even if unbound. --- .../ui/behaviour/io/VisualEditorPanel.java | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 9bde5cd..301dcd8 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -9,6 +9,7 @@ import java.awt.Insets; import java.io.StringReader; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; @@ -207,7 +208,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a scrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER ); add( scrollPane, BorderLayout.CENTER ); - tableModel = new MyTableModel( config.actionToInputsMap ); + tableModel = new MyTableModel( actions, config.actionToInputsMap ); final JTable tableBindings = new JTable( tableModel ); tableBindings.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); tableBindings.setFillsViewportHeight( true ); @@ -231,7 +232,7 @@ public void valueChanged( final ListSelectionEvent e ) labelActionName.setText( action ); labelActionDescription.setText( "TODO" ); - textFieldBinding.setText( trigger.toString() ); + textFieldBinding.setText( trigger == null ? "" : trigger.toString() ); if ( contexts.isEmpty() ) { lblContext.setText( "" ); @@ -268,24 +269,37 @@ private static class MyTableModel extends AbstractTableModel private final List< Set< String > > contexts; - public MyTableModel( final Map< String, Set< Input > > actionToInputsMap ) + public MyTableModel( final Set< String > baseActions, final Map< String, Set< Input > > actionToInputsMap ) { this.actions = new ArrayList<>(); this.bindings = new ArrayList<>(); this.contexts = new ArrayList<>(); - final List< String > sortedActions = new ArrayList<>( actionToInputsMap.keySet() ); + final Set< String > allActions = new HashSet<>(); + allActions.addAll( baseActions ); + allActions.addAll( actionToInputsMap.keySet() ); + final List< String > sortedActions = new ArrayList<>( allActions ); sortedActions.sort( null ); final InputComparator inputComparator = new InputComparator(); for ( final String action : sortedActions ) { - final List< Input > sortedInputs = new ArrayList<>( actionToInputsMap.get( action ) ); - sortedInputs.sort( inputComparator ); - for ( final Input input : sortedInputs ) + final Set< Input > inputs = actionToInputsMap.get( action ); + if ( null == inputs ) { actions.add( action ); - bindings.add( input.trigger ); - contexts.add( input.contexts ); + bindings.add( null ); + contexts.add( Collections.emptySet() ); + } + else + { + final List< Input > sortedInputs = new ArrayList<>( inputs ); + sortedInputs.sort( inputComparator ); + for ( final Input input : sortedInputs ) + { + actions.add( action ); + bindings.add( input.trigger ); + contexts.add( input.contexts ); + } } } } From af02b5922973bce926cb75a82be98ced20f38ad9 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Tue, 24 Oct 2017 14:03:27 +0200 Subject: [PATCH 027/184] Visual editor: custom renderers for the table. --- .../ui/behaviour/io/VisualEditorPanel.java | 122 +++++++++++++++--- 1 file changed, 103 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 301dcd8..20c3d9d 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -33,6 +33,8 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellRenderer; import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.io.InputTriggerConfig.Input; @@ -40,6 +42,7 @@ public class VisualEditorPanel extends JPanel { + private static final long serialVersionUID = 1L; private JTextField textFieldFilter; @@ -232,30 +235,109 @@ public void valueChanged( final ListSelectionEvent e ) labelActionName.setText( action ); labelActionDescription.setText( "TODO" ); - textFieldBinding.setText( trigger == null ? "" : trigger.toString() ); - if ( contexts.isEmpty() ) - { - lblContext.setText( "" ); - } - else - { - final StringBuilder str = new StringBuilder(); - str.append( contexts.get( 0 ) ); - for ( int i = 1; i < contexts.size(); i++ ) - str.append( ", " + contexts.get( i ) ); - txtfieldContext.setText( str.toString() ); - } - + textFieldBinding.setText( trigger == null ? "" : prettyPrintTrigger( trigger ) ); + txtfieldContext.setText( prettyPrintContexts( contexts ) ); } } ); - scrollPane.setViewportView( tableBindings ); + // Renderers. + tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); + tableBindings.getColumnModel().getColumn( 2 ).setCellRenderer( new MyContextsRenderer() ); + scrollPane.setViewportView( tableBindings ); } /* * INNER CLASSES */ + private static final class MyContextsRenderer extends DefaultTableCellRenderer implements TableCellRenderer + { + + private static final long serialVersionUID = 1L; + + @Override + public Component getTableCellRendererComponent( final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column ) + { + super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column ); + @SuppressWarnings( "unchecked" ) + final List< String > contexts = ( List< String > ) value; + setText( prettyPrintContexts( contexts ) ); + setToolTipText( contexts.toString() ); + return this; + } + } + + private static final String prettyPrintContexts( final List< String > contexts ) + { + if ( null == contexts || contexts.isEmpty() ) + { + return ""; + } + else + { + final StringBuilder str = new StringBuilder(); + str.append( contexts.get( 0 ) ); + for ( int i = 1; i < contexts.size(); i++ ) + str.append( ", " + contexts.get( i ) ); + return str.toString(); + } + } + + private static final class MyBindingsRenderer extends DefaultTableCellRenderer implements TableCellRenderer + { + + private static final long serialVersionUID = 1L; + + @Override + public Component getTableCellRendererComponent( final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column ) + { + super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column ); + final InputTrigger input = ( InputTrigger ) value; + setText( null == input ? "" : prettyPrintTrigger( input ) ); + setToolTipText( null == input ? "" : input.toString() ); + return this; + } + } + + private static final String prettyPrintTrigger( final InputTrigger input ) + { + final String str = input.toString(); + final String str2 = str + .replaceAll( "shift", "\u21E7" ) + .replaceAll( "win", "\u229E" ) + .replaceAll( "control", "\u2303" ) + .replaceAll( "escape", "\u238B" ) + .replaceAll( "tab", "\u21E5" ) + .replaceAll( "caps lock", "\u21EA" ) + .replaceAll( "shift", "\u21E7" ) + .replaceAll( "control", "\u2303" ) + .replaceAll( "option", "\u2325" ) + .replaceAll( "Apple", "\uF8FF" ) + .replaceAll( "command", "\u2318" ) + .replaceAll( "space", "\u2423" ) + .replaceAll( "return", "\u23CE" ) + .replaceAll( "backspace", "\u232B" ) + .replaceAll( "delete", "\u2326" ) + .replaceAll( "home", "\u21F1" ) + .replaceAll( "end", "\u21F2" ) + .replaceAll( "page up", "\u21DE" ) + .replaceAll( "page down", "\u21DF" ) + .replaceAll( "up arrow", "\u2191" ) + .replaceAll( "down arrow", "\u2193" ) + .replaceAll( "left arrow", "\u2190" ) + .replaceAll( "right arrow", "\u2192" ) + .replaceAll( "clear", "\u2327" ) + .replaceAll( "num lock", "\u21ED" ) + .replaceAll( "enter", "\u2324" ) + .replaceAll( "eject", "\u23CF" ) + .replaceAll( "power", "\u233D" ) + .replaceAll( "button1", "left mouse button" ) + .replaceAll( "button2", "middle mouse button" ) + .replaceAll( "button3", "right mouse button" ) + .replaceAll( "scroll", "\u21c5" ); // double arrow. Not ideal. + return str2; + } + private static class MyTableModel extends AbstractTableModel { @@ -267,7 +349,7 @@ private static class MyTableModel extends AbstractTableModel private final List< InputTrigger > bindings; - private final List< Set< String > > contexts; + private final List< List< String > > contexts; public MyTableModel( final Set< String > baseActions, final Map< String, Set< Input > > actionToInputsMap ) { @@ -288,7 +370,7 @@ public MyTableModel( final Set< String > baseActions, final Map< String, Set< In { actions.add( action ); bindings.add( null ); - contexts.add( Collections.emptySet() ); + contexts.add( Collections.emptyList() ); } else { @@ -298,7 +380,9 @@ public MyTableModel( final Set< String > baseActions, final Map< String, Set< In { actions.add( action ); bindings.add( input.trigger ); - contexts.add( input.contexts ); + final List< String > cs = new ArrayList<>( input.contexts ); + cs.sort( null ); + contexts.add( cs ); } } } @@ -364,7 +448,7 @@ private static InputTriggerConfig getDemoConfig() "- !mapping" + "\n" + " action: drag1" + "\n" + " contexts: [all]" + "\n" + - " triggers: [button1, G]" + "\n" + + " triggers: [button1, win G]" + "\n" + "- !mapping" + "\n" + " action: scroll1" + "\n" + " contexts: [all]" + "\n" + From 13340b7a5a33430fd7d35ad906488b21be71e5c6 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Tue, 24 Oct 2017 18:09:15 +0200 Subject: [PATCH 028/184] WIP: Context editor as a tag editor. --- .../scijava/ui/behaviour/io/RoundBorder.java | 54 +++++++ .../ui/behaviour/io/TagPanelEditor.java | 140 ++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java create mode 100644 src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java diff --git a/src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java b/src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java new file mode 100644 index 0000000..6caab8b --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java @@ -0,0 +1,54 @@ +package org.scijava.ui.behaviour.io; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.geom.Area; +import java.awt.geom.RoundRectangle2D; + +import javax.swing.border.LineBorder; + +public class RoundBorder extends LineBorder +{ + + private static final long serialVersionUID = 1L; + private final Color backColor; + + public RoundBorder( final Color color, final Color backColor, final int arc ) + { + super( color, arc ); + this.backColor = backColor; + } + + @Override + public void paintBorder( final Component c, final Graphics g, final int x, final int y, final int width, final int height ) + { + if ( ( this.thickness > 0 ) && ( g instanceof Graphics2D ) ) + { + final Graphics2D g2d = ( Graphics2D ) g; + final Object oldRenderingHint = g2d.getRenderingHint( RenderingHints.KEY_ANTIALIASING ); + final Color oldColor = g2d.getColor(); + g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); + + final float arc = 4f * thickness; + final Shape inner = new RoundRectangle2D.Float( x, y, width - 1, height - 1, (int) arc, (int) arc ); + final Shape outer = new Rectangle( x, y, width, height ); + + g2d.setColor( backColor ); + final Area area = new Area(outer); + area.exclusiveOr( new Area(inner) ); + g2d.fill( area ); + + g2d.setColor( this.lineColor ); + g2d.draw( inner ); + + g2d.setColor( oldColor ); + g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, oldRenderingHint ); + } + } + +} \ No newline at end of file diff --git a/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java new file mode 100644 index 0000000..86ae769 --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java @@ -0,0 +1,140 @@ +package org.scijava.ui.behaviour.io; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +public class TagPanelEditor extends JPanel +{ + + private static final long serialVersionUID = 1L; + + private final List< String > selectedTags; + + private final Collection< String > tags; + + public TagPanelEditor( final Collection< String > tags ) + { + this.tags = tags; + this.selectedTags = new ArrayList<>(); + + setPreferredSize( new Dimension( 400, 26 ) ); + setMinimumSize( new Dimension( 26, 26 ) ); + setLayout( new BoxLayout( this, BoxLayout.LINE_AXIS ) ); + setBackground( Color.white ); + setBorder( new JTextField().getBorder() ); + + final JTextField txtfieldContext = new JTextField(); + txtfieldContext.setColumns( 10 ); + txtfieldContext.setBorder( null ); + txtfieldContext.setOpaque( false ); + add( txtfieldContext ); + add( Box.createHorizontalGlue() ); + + txtfieldContext.addKeyListener( new KeyAdapter() + { + @Override + public void keyReleased( final java.awt.event.KeyEvent evt ) + { + tagcheck( evt ); + } + + private void tagcheck( final KeyEvent evt ) + { + final String s = txtfieldContext.getText(); + if ( s.length() > 0 ) + { + for ( final String tag : tags ) + { + if ( s.equals( tag ) && !selectedTags.contains( tag) ) + { + selectedTags.add( tag ); + final TagPanel tagp = new TagPanel( tag ); + add( tagp, getComponentCount() - 2 ); + txtfieldContext.setText( "" ); + revalidate(); + } + } + } + } + } ); + } + + public List< String > getSelectedTags() + { + return Collections.unmodifiableList( selectedTags ); + } + + public void setTags( final Collection< String > tags ) + { + for ( final Component child : getComponents() ) + if ( child instanceof TagPanel ) + remove( child ); + + selectedTags.clear(); + for ( final String tag : tags ) + { + selectedTags.add( tag ); + final TagPanel tagp = new TagPanel( tag, this.tags.contains( tag ) ); + add( tagp, getComponentCount() - 2 ); + } + revalidate(); + } + + private final class TagPanel extends JPanel + { + + private static final long serialVersionUID = 1L; + + public TagPanel( final String tag ) + { + this( tag, true ); + } + + public TagPanel( final String tag, final boolean valid ) + { + final Font font = TagPanelEditor.this.getFont().deriveFont( TagPanelEditor.this.getFont().getSize2D() - 2f ); + final JLabel txt = new JLabel( tag ); + txt.setFont( font ); + txt.setOpaque( true ); + if ( !valid ) + txt.setBackground( Color.PINK ); + txt.setBorder( new RoundBorder( getBackground().darker(), Color.WHITE, 3 ) ); + + final JLabel close = new JLabel( "\u00D7" ); + close.setOpaque( true ); + close.setBackground( getBackground().darker().darker() ); + close.setFont( font ); + + setLayout( new FlowLayout( FlowLayout.CENTER, 2, 0 ) ); + close.addMouseListener( new java.awt.event.MouseAdapter() + { + @Override + public void mousePressed( final java.awt.event.MouseEvent evt ) + { + TagPanelEditor.this.remove( TagPanel.this ); + TagPanelEditor.this.revalidate(); + } + } ); + add( close ); + add( txt ); + setOpaque( false ); + } + + } + +} From c2f147d533e767ef03c5c540d5547d3fb0b741e4 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Tue, 24 Oct 2017 18:09:26 +0200 Subject: [PATCH 029/184] GUI tweaks. --- .../ui/behaviour/io/VisualEditorPanel.java | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 20c3d9d..b62ac10 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -110,7 +110,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel lblName = new JLabel( "Name:" ); final GridBagConstraints gbc_lblName = new GridBagConstraints(); - gbc_lblName.insets = new Insets( 0, 0, 5, 5 ); + gbc_lblName.insets = new Insets( 5, 5, 5, 5 ); gbc_lblName.anchor = GridBagConstraints.WEST; gbc_lblName.gridx = 0; gbc_lblName.gridy = 0; @@ -118,7 +118,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel labelActionName = new JLabel( "<>" ); final GridBagConstraints gbc_labelActionName = new GridBagConstraints(); - gbc_labelActionName.insets = new Insets( 0, 0, 5, 5 ); + gbc_labelActionName.insets = new Insets( 5, 5, 5, 5 ); gbc_labelActionName.gridx = 1; gbc_labelActionName.gridy = 0; panelCommandEditor.add( labelActionName, gbc_labelActionName ); @@ -126,14 +126,14 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel lblBinding = new JLabel( "Binding:" ); final GridBagConstraints gbc_lblBinding = new GridBagConstraints(); gbc_lblBinding.anchor = GridBagConstraints.WEST; - gbc_lblBinding.insets = new Insets( 0, 0, 5, 5 ); + gbc_lblBinding.insets = new Insets( 5, 5, 5, 5 ); gbc_lblBinding.gridx = 2; gbc_lblBinding.gridy = 0; panelCommandEditor.add( lblBinding, gbc_lblBinding ); textFieldBinding = new JTextField(); final GridBagConstraints gbc_textFieldBinding = new GridBagConstraints(); - gbc_textFieldBinding.insets = new Insets( 0, 0, 5, 5 ); + gbc_textFieldBinding.insets = new Insets( 5, 5, 5, 5 ); gbc_textFieldBinding.fill = GridBagConstraints.HORIZONTAL; gbc_textFieldBinding.gridx = 3; gbc_textFieldBinding.gridy = 0; @@ -142,14 +142,14 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JButton buttonSpecialChar = new JButton( "<" ); final GridBagConstraints gbc_buttonSpecialChar = new GridBagConstraints(); - gbc_buttonSpecialChar.insets = new Insets( 0, 0, 5, 0 ); + gbc_buttonSpecialChar.insets = new Insets( 5, 5, 5, 5 ); gbc_buttonSpecialChar.gridx = 4; gbc_buttonSpecialChar.gridy = 0; panelCommandEditor.add( buttonSpecialChar, gbc_buttonSpecialChar ); final JLabel lblDescription = new JLabel( "Description:" ); final GridBagConstraints gbc_lblDescription = new GridBagConstraints(); - gbc_lblDescription.insets = new Insets( 0, 0, 5, 5 ); + gbc_lblDescription.insets = new Insets( 5, 5, 5, 5 ); gbc_lblDescription.anchor = GridBagConstraints.WEST; gbc_lblDescription.gridx = 0; gbc_lblDescription.gridy = 1; @@ -158,31 +158,31 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel labelActionDescription = new JLabel( "<>" ); final GridBagConstraints gbc_labelActionDescription = new GridBagConstraints(); gbc_labelActionDescription.gridheight = 2; - gbc_labelActionDescription.insets = new Insets( 0, 0, 0, 5 ); + gbc_labelActionDescription.insets = new Insets( 5, 5, 5, 5 ); gbc_labelActionDescription.gridx = 1; gbc_labelActionDescription.gridy = 1; panelCommandEditor.add( labelActionDescription, gbc_labelActionDescription ); - final JLabel lblContext = new JLabel( "Context:" ); + final JLabel lblContext = new JLabel( "Contexts:" ); final GridBagConstraints gbc_lblContext = new GridBagConstraints(); gbc_lblContext.anchor = GridBagConstraints.WEST; - gbc_lblContext.insets = new Insets( 0, 0, 5, 5 ); + gbc_lblContext.insets = new Insets( 5, 5, 5, 5 ); gbc_lblContext.gridx = 2; gbc_lblContext.gridy = 1; panelCommandEditor.add( lblContext, gbc_lblContext ); - final JTextField txtfieldContext = new JTextField(); + final TagPanelEditor panelContextEditor = new TagPanelEditor( contexts ); final GridBagConstraints gbc_comboBoxContext = new GridBagConstraints(); gbc_comboBoxContext.gridwidth = 2; - gbc_comboBoxContext.insets = new Insets( 0, 0, 5, 0 ); - gbc_comboBoxContext.fill = GridBagConstraints.HORIZONTAL; + gbc_comboBoxContext.insets = new Insets( 5, 5, 5, 5 ); + gbc_comboBoxContext.fill = GridBagConstraints.BOTH; gbc_comboBoxContext.gridx = 3; gbc_comboBoxContext.gridy = 1; - panelCommandEditor.add( txtfieldContext, gbc_comboBoxContext ); + panelCommandEditor.add( panelContextEditor, gbc_comboBoxContext ); final JLabel lblConflicts = new JLabel( "Conflicts:" ); final GridBagConstraints gbc_lblConflicts = new GridBagConstraints(); - gbc_lblConflicts.insets = new Insets( 0, 0, 0, 5 ); + gbc_lblConflicts.insets = new Insets( 5, 5, 5, 5 ); gbc_lblConflicts.anchor = GridBagConstraints.WEST; gbc_lblConflicts.gridx = 2; gbc_lblConflicts.gridy = 2; @@ -236,7 +236,7 @@ public void valueChanged( final ListSelectionEvent e ) labelActionName.setText( action ); labelActionDescription.setText( "TODO" ); textFieldBinding.setText( trigger == null ? "" : prettyPrintTrigger( trigger ) ); - txtfieldContext.setText( prettyPrintContexts( contexts ) ); + panelContextEditor.setTags( contexts ); } } ); @@ -305,27 +305,25 @@ private static final String prettyPrintTrigger( final InputTrigger input ) final String str2 = str .replaceAll( "shift", "\u21E7" ) .replaceAll( "win", "\u229E" ) - .replaceAll( "control", "\u2303" ) + .replaceAll( "ctrl", "\u2303" ) .replaceAll( "escape", "\u238B" ) .replaceAll( "tab", "\u21E5" ) - .replaceAll( "caps lock", "\u21EA" ) - .replaceAll( "shift", "\u21E7" ) - .replaceAll( "control", "\u2303" ) + .replaceAll( "caps_lock", "\u21EA" ) .replaceAll( "option", "\u2325" ) .replaceAll( "Apple", "\uF8FF" ) .replaceAll( "command", "\u2318" ) .replaceAll( "space", "\u2423" ) .replaceAll( "return", "\u23CE" ) - .replaceAll( "backspace", "\u232B" ) + .replaceAll( "back_space", "\u232B" ) .replaceAll( "delete", "\u2326" ) .replaceAll( "home", "\u21F1" ) .replaceAll( "end", "\u21F2" ) - .replaceAll( "page up", "\u21DE" ) - .replaceAll( "page down", "\u21DF" ) - .replaceAll( "up arrow", "\u2191" ) - .replaceAll( "down arrow", "\u2193" ) - .replaceAll( "left arrow", "\u2190" ) - .replaceAll( "right arrow", "\u2192" ) + .replaceAll( "page_up", "\u21DE" ) + .replaceAll( "page_down", "\u21DF" ) + .replaceAll( "up", "\u2191" ) + .replaceAll( "down", "\u2193" ) + .replaceAll( "left", "\u2190" ) + .replaceAll( "right", "\u2192" ) .replaceAll( "clear", "\u2327" ) .replaceAll( "num lock", "\u21ED" ) .replaceAll( "enter", "\u2324" ) @@ -457,6 +455,10 @@ private static InputTriggerConfig getDemoConfig() " action: scroll1" + "\n" + " contexts: [trackscheme, mamut]" + "\n" + " triggers: [shift D]" + "\n" + + "- !mapping" + "\n" + + " action: destroy the world" + "\n" + + " contexts: [unknown context, mamut]" + "\n" + + " triggers: [control A]" + "\n" + "" ); final List< InputTriggerDescription > triggers = YamlConfigIO.read( reader ); final InputTriggerConfig config = new InputTriggerConfig( triggers ); From 105095d80233a5b79687ab6bcf261c9e82b2571b Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Wed, 25 Oct 2017 14:04:36 +0200 Subject: [PATCH 030/184] Better Tag field editor. - Autocompletion. - Remove tags with keyboard. - Unique tags only. - Discriminate valid vs invalid tags but accept them. --- .../ui/behaviour/io/TagPanelEditor.java | 221 ++++++++++++++---- 1 file changed, 176 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java index 86ae769..18aca50 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java @@ -1,10 +1,10 @@ package org.scijava.ui.behaviour.io; import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; +import java.awt.event.ActionEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.ArrayList; @@ -12,25 +12,39 @@ import java.util.Collections; import java.util.List; +import javax.swing.AbstractAction; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.BadLocationException; public class TagPanelEditor extends JPanel { private static final long serialVersionUID = 1L; + private static final String COMMIT_ACTION = "commit"; + private final List< String > selectedTags; - private final Collection< String > tags; + private final List< TagPanel > tagPanels; + + private final List< String > tags; + + private final JTextField textField; public TagPanelEditor( final Collection< String > tags ) { - this.tags = tags; + this.tags = new ArrayList<>( tags ); + this.tags.sort( null ); this.selectedTags = new ArrayList<>(); + this.tagPanels = new ArrayList<>(); setPreferredSize( new Dimension( 400, 26 ) ); setMinimumSize( new Dimension( 26, 26 ) ); @@ -38,40 +52,34 @@ public TagPanelEditor( final Collection< String > tags ) setBackground( Color.white ); setBorder( new JTextField().getBorder() ); - final JTextField txtfieldContext = new JTextField(); - txtfieldContext.setColumns( 10 ); - txtfieldContext.setBorder( null ); - txtfieldContext.setOpaque( false ); - add( txtfieldContext ); - add( Box.createHorizontalGlue() ); + this.textField = new JTextField(); + textField.setColumns( 10 ); + textField.setBorder( null ); + textField.setOpaque( false ); - txtfieldContext.addKeyListener( new KeyAdapter() + final Autocomplete autoComplete = new Autocomplete(); + textField.getDocument().addDocumentListener( autoComplete ); + textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ), COMMIT_ACTION ); + textField.getActionMap().put( COMMIT_ACTION, autoComplete.new CommitAction() ); + textField.addKeyListener( new KeyAdapter() { @Override - public void keyReleased( final java.awt.event.KeyEvent evt ) + public void keyPressed( final KeyEvent e ) { - tagcheck( evt ); - } - - private void tagcheck( final KeyEvent evt ) - { - final String s = txtfieldContext.getText(); - if ( s.length() > 0 ) + /* + * We have to use a key listener to deal separately with + * character removal and tag removal. + */ + if ( e.getKeyCode() == KeyEvent.VK_BACK_SPACE && textField.getText().isEmpty() && !selectedTags.isEmpty() ) { - for ( final String tag : tags ) - { - if ( s.equals( tag ) && !selectedTags.contains( tag) ) - { - selectedTags.add( tag ); - final TagPanel tagp = new TagPanel( tag ); - add( tagp, getComponentCount() - 2 ); - txtfieldContext.setText( "" ); - revalidate(); - } - } + removeTag( selectedTags.get( selectedTags.size() - 1 ) ); + e.consume(); } } } ); + + add( textField ); + add( Box.createHorizontalGlue() ); } public List< String > getSelectedTags() @@ -81,30 +89,155 @@ public List< String > getSelectedTags() public void setTags( final Collection< String > tags ) { - for ( final Component child : getComponents() ) - if ( child instanceof TagPanel ) - remove( child ); - + for ( final TagPanel tagPanel : tagPanels ) + remove( tagPanel ); selectedTags.clear(); + tagPanels.clear(); + for ( final String tag : tags ) - { - selectedTags.add( tag ); - final TagPanel tagp = new TagPanel( tag, this.tags.contains( tag ) ); - add( tagp, getComponentCount() - 2 ); - } + addTag( tag ); revalidate(); + repaint(); } - private final class TagPanel extends JPanel + private void addTag( final String tag ) { + final TagPanel tagp = new TagPanel( tag, this.tags.contains( tag ) ); + selectedTags.add( tag ); + tagPanels.add( tagp ); + add( tagp, getComponentCount() - 2 ); + } - private static final long serialVersionUID = 1L; + private void removeTag( final String tag ) + { + final int index = selectedTags.indexOf( tag ); + if ( index < 0 ) + return; + + selectedTags.remove( index ); + final TagPanel tagPanel = tagPanels.remove( index ); + remove( tagPanel ); + revalidate(); + repaint(); + } + + /* + * INNER CLASSES + */ + + /** + * Adapted from + * http://stackabuse.com/example-adding-autocomplete-to-jtextfield/ + */ + private class Autocomplete implements DocumentListener + { + + @Override + public void changedUpdate( final DocumentEvent ev ) + {} + + @Override + public void removeUpdate( final DocumentEvent ev ) + {} + + @Override + public void insertUpdate( final DocumentEvent ev ) + { + if ( ev.getLength() != 1 ) + return; + + final int pos = ev.getOffset(); + String content = null; + try + { + content = textField.getText( 0, pos + 1 ); + } + catch ( final BadLocationException e ) + { + e.printStackTrace(); + } + + // Find where the word starts + int w; + for ( w = pos; w >= 0; w-- ) + { + if ( !Character.isLetter( content.charAt( w ) ) ) + { + break; + } + } + + // Too few chars + if ( pos - w < 2 ) + return; + + final String prefix = content.substring( w + 1 ).toLowerCase(); + final int n = Collections.binarySearch( tags, prefix ); + if ( n < 0 && -n <= tags.size() ) + { + final String match = tags.get( -n - 1 ); + if ( match.startsWith( prefix ) ) + { + // A completion is found + final String completion = match.substring( pos - w ); + // We cannot modify Document from within notification, + // so we submit a task that does the change later + SwingUtilities.invokeLater( new CompletionTask( completion, pos + 1 ) ); + } + } + } - public TagPanel( final String tag ) + public class CommitAction extends AbstractAction { - this( tag, true ); + private static final long serialVersionUID = 5794543109646743416L; + + @Override + public void actionPerformed( final ActionEvent ev ) + { + final String tag = textField.getText(); + if ( selectedTags.contains( tag ) ) + { + // Do not allow more than 1 tag instance. + textField.setText( "" ); + return; + } + + addTag( tag ); + textField.setText( "" ); + revalidate(); + } } + private class CompletionTask implements Runnable + { + private String completion; + + private int position; + + CompletionTask( final String completion, final int position ) + { + this.completion = completion; + this.position = position; + } + + @Override + public void run() + { + final StringBuffer sb = new StringBuffer( textField.getText() ); + sb.insert( position, completion ); + textField.setText( sb.toString() ); + textField.setCaretPosition( position + completion.length() ); + textField.moveCaretPosition( position ); + } + } + + } + + private final class TagPanel extends JPanel + { + + private static final long serialVersionUID = 1L; + public TagPanel( final String tag, final boolean valid ) { final Font font = TagPanelEditor.this.getFont().deriveFont( TagPanelEditor.this.getFont().getSize2D() - 2f ); @@ -126,15 +259,13 @@ public TagPanel( final String tag, final boolean valid ) @Override public void mousePressed( final java.awt.event.MouseEvent evt ) { - TagPanelEditor.this.remove( TagPanel.this ); - TagPanelEditor.this.revalidate(); + removeTag( tag ); } } ); add( close ); add( txt ); setOpaque( false ); } - } } From 120bdab3c05c451b4e476aafc29a9ad1e112a040 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Wed, 25 Oct 2017 14:37:46 +0200 Subject: [PATCH 031/184] Hack to avoid issue with painted corners. --- .../scijava/ui/behaviour/io/RoundBorder.java | 8 +-- .../ui/behaviour/io/TagPanelEditor.java | 49 ++++++++++++------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java b/src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java index 6caab8b..02318b2 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java @@ -16,12 +16,12 @@ public class RoundBorder extends LineBorder { private static final long serialVersionUID = 1L; - private final Color backColor; + private final Component parent; - public RoundBorder( final Color color, final Color backColor, final int arc ) + public RoundBorder( final Color color, final Component parent, final int arc ) { super( color, arc ); - this.backColor = backColor; + this.parent = parent; } @Override @@ -38,7 +38,7 @@ public void paintBorder( final Component c, final Graphics g, final int x, final final Shape inner = new RoundRectangle2D.Float( x, y, width - 1, height - 1, (int) arc, (int) arc ); final Shape outer = new Rectangle( x, y, width, height ); - g2d.setColor( backColor ); + g2d.setColor( parent.getBackground() ); final Area area = new Area(outer); area.exclusiveOr( new Area(inner) ); g2d.fill( area ); diff --git a/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java index 18aca50..a6785de 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java @@ -39,8 +39,16 @@ public class TagPanelEditor extends JPanel private final JTextField textField; + private final boolean editable; + public TagPanelEditor( final Collection< String > tags ) { + this( tags, true ); + } + + public TagPanelEditor( final Collection< String > tags, final boolean editable ) + { + this.editable = editable; this.tags = new ArrayList<>( tags ); this.tags.sort( null ); this.selectedTags = new ArrayList<>(); @@ -56,27 +64,31 @@ public TagPanelEditor( final Collection< String > tags ) textField.setColumns( 10 ); textField.setBorder( null ); textField.setOpaque( false ); + textField.setEditable( editable ); - final Autocomplete autoComplete = new Autocomplete(); - textField.getDocument().addDocumentListener( autoComplete ); - textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ), COMMIT_ACTION ); - textField.getActionMap().put( COMMIT_ACTION, autoComplete.new CommitAction() ); - textField.addKeyListener( new KeyAdapter() + if ( editable ) { - @Override - public void keyPressed( final KeyEvent e ) + final Autocomplete autoComplete = new Autocomplete(); + textField.getDocument().addDocumentListener( autoComplete ); + textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ), COMMIT_ACTION ); + textField.getActionMap().put( COMMIT_ACTION, autoComplete.new CommitAction() ); + textField.addKeyListener( new KeyAdapter() { - /* - * We have to use a key listener to deal separately with - * character removal and tag removal. - */ - if ( e.getKeyCode() == KeyEvent.VK_BACK_SPACE && textField.getText().isEmpty() && !selectedTags.isEmpty() ) + @Override + public void keyPressed( final KeyEvent e ) { - removeTag( selectedTags.get( selectedTags.size() - 1 ) ); - e.consume(); + /* + * We have to use a key listener to deal separately with + * character removal and tag removal. + */ + if ( e.getKeyCode() == KeyEvent.VK_BACK_SPACE && textField.getText().isEmpty() && !selectedTags.isEmpty() ) + { + removeTag( selectedTags.get( selectedTags.size() - 1 ) ); + e.consume(); + } } - } - } ); + } ); + } add( textField ); add( Box.createHorizontalGlue() ); @@ -246,7 +258,7 @@ public TagPanel( final String tag, final boolean valid ) txt.setOpaque( true ); if ( !valid ) txt.setBackground( Color.PINK ); - txt.setBorder( new RoundBorder( getBackground().darker(), Color.WHITE, 3 ) ); + txt.setBorder( new RoundBorder( getBackground().darker(), TagPanelEditor.this, 3 ) ); final JLabel close = new JLabel( "\u00D7" ); close.setOpaque( true ); @@ -262,7 +274,8 @@ public void mousePressed( final java.awt.event.MouseEvent evt ) removeTag( tag ); } } ); - add( close ); + if ( editable ) + add( close ); add( txt ); setOpaque( false ); } From 469e1c08ff5dc3ff45c60245ce0f985fb106a4b8 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Wed, 25 Oct 2017 15:25:17 +0200 Subject: [PATCH 032/184] Listeners for tag panel editor. --- .../ui/behaviour/io/TagPanelEditor.java | 36 +++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java index a6785de..4133ced 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java @@ -2,7 +2,6 @@ import java.awt.Color; import java.awt.Dimension; -import java.awt.FlowLayout; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.KeyAdapter; @@ -10,6 +9,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; import javax.swing.AbstractAction; @@ -27,6 +27,12 @@ public class TagPanelEditor extends JPanel { + @FunctionalInterface + public static interface TagSelectionChangeListener + { + public void tagSelectionChanged(); + } + private static final long serialVersionUID = 1L; private static final String COMMIT_ACTION = "commit"; @@ -41,6 +47,8 @@ public class TagPanelEditor extends JPanel private final boolean editable; + private final HashSet< TagSelectionChangeListener > listeners; + public TagPanelEditor( final Collection< String > tags ) { this( tags, true ); @@ -53,6 +61,7 @@ public TagPanelEditor( final Collection< String > tags, final boolean editable ) this.tags.sort( null ); this.selectedTags = new ArrayList<>(); this.tagPanels = new ArrayList<>(); + this.listeners = new HashSet<>(); setPreferredSize( new Dimension( 400, 26 ) ); setMinimumSize( new Dimension( 26, 26 ) ); @@ -128,6 +137,7 @@ private void removeTag( final String tag ) selectedTags.remove( index ); final TagPanel tagPanel = tagPanels.remove( index ); + notifyListeners(); remove( tagPanel ); revalidate(); repaint(); @@ -216,7 +226,9 @@ public void actionPerformed( final ActionEvent ev ) addTag( tag ); textField.setText( "" ); + notifyListeners(); revalidate(); + repaint(); } } @@ -264,8 +276,6 @@ public TagPanel( final String tag, final boolean valid ) close.setOpaque( true ); close.setBackground( getBackground().darker().darker() ); close.setFont( font ); - - setLayout( new FlowLayout( FlowLayout.CENTER, 2, 0 ) ); close.addMouseListener( new java.awt.event.MouseAdapter() { @Override @@ -274,11 +284,31 @@ public void mousePressed( final java.awt.event.MouseEvent evt ) removeTag( tag ); } } ); + + setLayout( new BoxLayout( this, BoxLayout.LINE_AXIS ) ); if ( editable ) add( close ); + add( Box.createHorizontalStrut( 1 ) ); add( txt ); + add( Box.createHorizontalStrut( 4 ) ); setOpaque( false ); } } + private void notifyListeners() + { + for ( final TagSelectionChangeListener listener : listeners ) + listener.tagSelectionChanged(); + } + + public void addTagSelectionChangeListener( final TagSelectionChangeListener listener ) + { + listeners.add(listener); + } + + public void removeTagSelectionChangeListener( final TagSelectionChangeListener listener ) + { + listeners.remove(listener); + } + } From 46eb136408c87fa2ad8d9f483f11da84a9458993 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Wed, 25 Oct 2017 15:25:36 +0200 Subject: [PATCH 033/184] The contexts in the visual editor can be edited. --- .../ui/behaviour/io/VisualEditorPanel.java | 50 +++++++++++-------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index b62ac10..6f55b59 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -9,6 +9,7 @@ import java.awt.Insets; import java.io.StringReader; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; @@ -231,7 +232,6 @@ public void valueChanged( final ListSelectionEvent e ) final String action = tableModel.actions.get( row ); final InputTrigger trigger = tableModel.bindings.get( row ); final List< String > contexts = new ArrayList<>( tableModel.contexts.get( row ) ); - contexts.sort( null ); labelActionName.setText( action ); labelActionDescription.setText( "TODO" ); @@ -240,9 +240,14 @@ public void valueChanged( final ListSelectionEvent e ) } } ); + // Listen to changes in context editor and forward to table model. + panelContextEditor.addTagSelectionChangeListener( () -> contextsChanged( tableBindings.getSelectedRow(), panelContextEditor.getSelectedTags() ) ); + // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); - tableBindings.getColumnModel().getColumn( 2 ).setCellRenderer( new MyContextsRenderer() ); + tableBindings.getColumnModel().getColumn( 2 ).setCellRenderer( new MyContextsRenderer( contexts ) ); + tableBindings.getSelectionModel().setSelectionInterval( 0, 0 ); + tableBindings.setRowHeight( 30 ); scrollPane.setViewportView( tableBindings ); } @@ -250,39 +255,40 @@ public void valueChanged( final ListSelectionEvent e ) * INNER CLASSES */ - private static final class MyContextsRenderer extends DefaultTableCellRenderer implements TableCellRenderer + private void contextsChanged( final int row, final List< String > selectedContexts ) + { + if ( row < 0 ) + return; + + tableModel.contexts.set( row, new ArrayList<>( selectedContexts ) ); + tableModel.fireTableCellUpdated( row, 2 ); + } + + private static final class MyContextsRenderer extends TagPanelEditor implements TableCellRenderer { + public MyContextsRenderer( final Collection< String > tags ) + { + super( tags, false ); + setBorder( null ); + } + private static final long serialVersionUID = 1L; @Override public Component getTableCellRendererComponent( final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column ) { - super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column ); + setForeground( isSelected ? table.getSelectionForeground() : table.getForeground() ); + setBackground( isSelected ? table.getSelectionBackground() : table.getBackground() ); + @SuppressWarnings( "unchecked" ) final List< String > contexts = ( List< String > ) value; - setText( prettyPrintContexts( contexts ) ); + setTags( contexts ); setToolTipText( contexts.toString() ); return this; } } - private static final String prettyPrintContexts( final List< String > contexts ) - { - if ( null == contexts || contexts.isEmpty() ) - { - return ""; - } - else - { - final StringBuilder str = new StringBuilder(); - str.append( contexts.get( 0 ) ); - for ( int i = 1; i < contexts.size(); i++ ) - str.append( ", " + contexts.get( i ) ); - return str.toString(); - } - } - private static final class MyBindingsRenderer extends DefaultTableCellRenderer implements TableCellRenderer { @@ -471,7 +477,7 @@ private static Set< String > getDemoActions() actions.add( "drag1" ); actions.add( "scroll1" ); actions.add( "destroy the world" ); - actions.add( "awake the dragons" ); + actions.add( "ride the dragon" ); actions.add( "make some coffee" ); return actions; } From 46066bbb5921b80f37fd5154a794e76b64881bcd Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Thu, 26 Oct 2017 13:05:31 +0200 Subject: [PATCH 034/184] Refactor GUI elements. --- .../ui/behaviour/io/VisualEditorPanel.java | 9 +- .../io/gui/KeyBindingsPanelEditor.java | 421 ++++++++++++++++++ .../behaviour/io/{ => gui}/RoundBorder.java | 2 +- .../io/{ => gui}/TagPanelEditor.java | 28 +- 4 files changed, 446 insertions(+), 14 deletions(-) create mode 100644 src/main/java/org/scijava/ui/behaviour/io/gui/KeyBindingsPanelEditor.java rename src/main/java/org/scijava/ui/behaviour/io/{ => gui}/RoundBorder.java (97%) rename src/main/java/org/scijava/ui/behaviour/io/{ => gui}/TagPanelEditor.java (91%) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 6f55b59..bf85c80 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -39,6 +39,8 @@ import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.io.InputTriggerConfig.Input; +import org.scijava.ui.behaviour.io.gui.KeyBindingsPanelEditor; +import org.scijava.ui.behaviour.io.gui.TagPanelEditor; import org.scijava.ui.behaviour.io.yaml.YamlConfigIO; public class VisualEditorPanel extends JPanel @@ -48,7 +50,7 @@ public class VisualEditorPanel extends JPanel private JTextField textFieldFilter; - private JTextField textFieldBinding; + private KeyBindingsPanelEditor textFieldBinding; private InputTriggerConfig config; @@ -132,14 +134,13 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a gbc_lblBinding.gridy = 0; panelCommandEditor.add( lblBinding, gbc_lblBinding ); - textFieldBinding = new JTextField(); + textFieldBinding = new KeyBindingsPanelEditor( true ); final GridBagConstraints gbc_textFieldBinding = new GridBagConstraints(); gbc_textFieldBinding.insets = new Insets( 5, 5, 5, 5 ); gbc_textFieldBinding.fill = GridBagConstraints.HORIZONTAL; gbc_textFieldBinding.gridx = 3; gbc_textFieldBinding.gridy = 0; panelCommandEditor.add( textFieldBinding, gbc_textFieldBinding ); - textFieldBinding.setColumns( 10 ); final JButton buttonSpecialChar = new JButton( "<" ); final GridBagConstraints gbc_buttonSpecialChar = new GridBagConstraints(); @@ -235,7 +236,7 @@ public void valueChanged( final ListSelectionEvent e ) labelActionName.setText( action ); labelActionDescription.setText( "TODO" ); - textFieldBinding.setText( trigger == null ? "" : prettyPrintTrigger( trigger ) ); +// textFieldBinding.setText( trigger == null ? "" : prettyPrintTrigger( trigger ) ); TODO panelContextEditor.setTags( contexts ); } } ); diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/KeyBindingsPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/KeyBindingsPanelEditor.java new file mode 100644 index 0000000..9dd8218 --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/KeyBindingsPanelEditor.java @@ -0,0 +1,421 @@ +package org.scijava.ui.behaviour.io.gui; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import javax.swing.AbstractAction; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.SwingUtilities; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.text.BadLocationException; + +public class KeyBindingsPanelEditor extends JPanel +{ + + @FunctionalInterface + public static interface KeyBindingsChangeListener + { + public void keyBindingsChanged(); + } + + private static final long serialVersionUID = 1L; + + private static final String COMMIT_ACTION = "commit"; + + protected final List< String > selectedKeys; + + protected final List< KeyItem > keyItems; + + private final JTextField textField; + + private final boolean editable; + + private final HashSet< KeyBindingsChangeListener > listeners; + + public KeyBindingsPanelEditor( final boolean editable ) + { + this.editable = editable; + this.selectedKeys = new ArrayList<>(); + this.keyItems = new ArrayList<>(); + this.listeners = new HashSet<>(); + + setPreferredSize( new Dimension( 400, 26 ) ); + setMinimumSize( new Dimension( 26, 26 ) ); + setLayout( new BoxLayout( this, BoxLayout.LINE_AXIS ) ); + setBackground( Color.white ); + setBorder( new JTextField().getBorder() ); + + this.textField = new JTextField(); + textField.setColumns( 10 ); + textField.setBorder( null ); + textField.setOpaque( false ); + textField.setEditable( editable ); + + if ( editable ) + { + final Autocomplete autoComplete = new Autocomplete(); + textField.getDocument().addDocumentListener( autoComplete ); + textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ), COMMIT_ACTION ); + textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_SPACE, 0 ), COMMIT_ACTION ); + textField.getActionMap().put( COMMIT_ACTION, autoComplete.new CommitAction() ); + textField.addKeyListener( new KeyAdapter() + { + @Override + public void keyPressed( final KeyEvent e ) + { + /* + * We have to use a key listener to deal separately with + * character removal and tag removal. + */ + if ( e.getKeyCode() == KeyEvent.VK_BACK_SPACE && textField.getText().isEmpty() && !selectedKeys.isEmpty() ) + { + removeTag( selectedKeys.get( selectedKeys.size() - 1 ) ); + e.consume(); + } + } + } ); + } + + add( textField ); + add( Box.createHorizontalGlue() ); + } + + public void setKeys( final Collection< String > tags ) + { + for ( final KeyItem keyItem : keyItems ) + remove( keyItem ); + selectedKeys.clear(); + keyItems.clear(); + + for ( final String tag : tags ) + addKey( tag ); + revalidate(); + repaint(); + } + + protected void addKey( final String key ) + { + final KeyItem tagp = new KeyItem( key, INPUT_TRIGGER_SYNTAX_TAGS.contains( key ) ); + selectedKeys.add( key ); + keyItems.add( tagp ); + add( tagp, getComponentCount() - 2 ); + } + + private void removeTag( final String tag ) + { + final int index = selectedKeys.indexOf( tag ); + if ( index < 0 ) + return; + + selectedKeys.remove( index ); + final KeyItem tagPanel = keyItems.remove( index ); + notifyListeners(); + remove( tagPanel ); + revalidate(); + repaint(); + } + + /* + * INNER CLASSES + */ + + /** + * Adapted from + * http://stackabuse.com/example-adding-autocomplete-to-jtextfield/ + */ + private class Autocomplete implements DocumentListener + { + + @Override + public void changedUpdate( final DocumentEvent ev ) + {} + + @Override + public void removeUpdate( final DocumentEvent ev ) + {} + + @Override + public void insertUpdate( final DocumentEvent ev ) + { + if ( ev.getLength() != 1 ) + return; + + final int pos = ev.getOffset(); + String content = null; + try + { + content = textField.getText( 0, pos + 1 ); + } + catch ( final BadLocationException e ) + { + e.printStackTrace(); + } + + // Find where the word starts + int w; + for ( w = pos; w >= 0; w-- ) + { + if ( !Character.isLetter( content.charAt( w ) ) ) + { + break; + } + } + + // Too few chars + if ( pos - w < 2 ) + return; + + final String prefix = content.substring( w + 1 ).toLowerCase(); + final int n = Collections.binarySearch( INPUT_TRIGGER_SYNTAX_TAGS, prefix ); + if ( n < 0 && -n <= INPUT_TRIGGER_SYNTAX_TAGS.size() ) + { + final String match = INPUT_TRIGGER_SYNTAX_TAGS.get( -n - 1 ); + if ( match.startsWith( prefix ) ) + { + // A completion is found + final String completion = match.substring( pos - w ); + // We cannot modify Document from within notification, + // so we submit a task that does the change later + SwingUtilities.invokeLater( new CompletionTask( completion, pos + 1 ) ); + } + } + } + + public class CommitAction extends AbstractAction + { + private static final long serialVersionUID = 5794543109646743416L; + + @Override + public void actionPerformed( final ActionEvent ev ) + { + final String key = textField.getText().trim().toUpperCase(); + if ( selectedKeys.contains( key ) ) + { + // Do not allow more than 1 tag instance. + textField.setText( "" ); + return; + } + + addKey( key ); + textField.setText( "" ); + notifyListeners(); + revalidate(); + repaint(); + } + } + + private class CompletionTask implements Runnable + { + private String completion; + + private int position; + + CompletionTask( final String completion, final int position ) + { + this.completion = completion; + this.position = position; + } + + @Override + public void run() + { + final StringBuffer sb = new StringBuffer( textField.getText() ); + sb.insert( position, completion ); + textField.setText( sb.toString() ); + textField.setCaretPosition( position + completion.length() ); + textField.moveCaretPosition( position ); + } + } + + } + + final class KeyItem extends JPanel + { + + private static final long serialVersionUID = 1L; + + public KeyItem( final String tag, final boolean valid ) + { + final Font parentFont = KeyBindingsPanelEditor.this.getFont(); + final Font font = parentFont.deriveFont( parentFont.getSize2D() - 2f ); + final String str = TRIGGER_SYMBOLS.containsKey( tag ) ? TRIGGER_SYMBOLS.get( tag ) : tag; + final JLabel txt = new JLabel( str ); + txt.setFont( font ); + txt.setOpaque( true ); + if ( !valid ) + txt.setBackground( Color.PINK ); + txt.setBorder( new RoundBorder( getBackground().darker(), KeyBindingsPanelEditor.this, 3 ) ); + + final JLabel close = new JLabel( "\u00D7" ); + close.setOpaque( true ); + close.setBackground( getBackground().darker().darker() ); + close.setFont( font ); + close.addMouseListener( new java.awt.event.MouseAdapter() + { + @Override + public void mousePressed( final java.awt.event.MouseEvent evt ) + { + removeTag( tag ); + } + } ); + + setLayout( new BoxLayout( this, BoxLayout.LINE_AXIS ) ); + if ( editable ) + add( close ); + add( Box.createHorizontalStrut( 1 ) ); + add( txt ); + add( Box.createHorizontalStrut( 4 ) ); + setOpaque( false ); + } + } + + private void notifyListeners() + { + for ( final KeyBindingsChangeListener listener : listeners ) + listener.keyBindingsChanged(); + } + + public void addTagSelectionChangeListener( final KeyBindingsChangeListener listener ) + { + listeners.add( listener ); + } + + public void removeTagSelectionChangeListener( final KeyBindingsChangeListener listener ) + { + listeners.remove( listener ); + } + + private static final List< String > INPUT_TRIGGER_SYNTAX_TAGS = new ArrayList<>(); + + private static final Map< String, String > TRIGGER_SYMBOLS = new HashMap<>(); + + static + { + for ( int i = 0; i < 26; i++ ) + { + INPUT_TRIGGER_SYNTAX_TAGS.add( String.valueOf( ( char ) ( 'A' + i ) ) ); + INPUT_TRIGGER_SYNTAX_TAGS.add( String.valueOf( ( char ) ( 'a' + i ) ) ); + // Show small letters as upper case. + TRIGGER_SYMBOLS.put( String.valueOf( ( char ) ( 'a' + i ) ), String.valueOf( ( char ) ( 'A' + i ) ) ); + } + for ( int i = 0; i < 10; i++ ) + INPUT_TRIGGER_SYNTAX_TAGS.add( String.valueOf( ( char ) ( '0' + i ) ) ); + + INPUT_TRIGGER_SYNTAX_TAGS.addAll( + Arrays.asList( new String[] { + "ENTER", + "BACK_SPACE", + "TAB", + "CANCEL", + "CLEAR", + "COMPOSE", + "PAUSE", + "CAPS_LOCK", + "ESCAPE", + "SPACE", + "PAGE_UP", + "PAGE_DOWN", + "END", + "HOME", + "BEGIN", + "COMMA", + "PERIOD", + "SLASH", + "SEMICOLON", + "EQUALS", + "OPEN_BRACKET", + "BACK_SLASH", + "CLOSE_BRACKET", + "LEFT", + "UP", + "RIGHT", + "DOWN", + "NUMPAD0", + "NUMPAD1", + "NUMPAD2", + "NUMPAD3", + "NUMPAD4", + "NUMPAD5", + "NUMPAD6", + "NUMPAD7", + "NUMPAD8", + "NUMPAD9", + "MULTIPLY", + "ADD", + "SEPARATOR", + "SUBTRACT", + "DECIMAL", + "DIVIDE", + "DELETE", + "NUM_LOCK", + "SCROLL_LOCK", + "ctrl", + "alt", + "altGraph", + "shift", + "meta", + "win", + "double-click", + "button1 ", + "button2 ", + "button3 ", + "scroll" + } ) ); + INPUT_TRIGGER_SYNTAX_TAGS.sort( null ); + + TRIGGER_SYMBOLS.put( "ENTER", "\u23CE" ); + TRIGGER_SYMBOLS.put( "BACK_SPACE", "\u232B" ); + TRIGGER_SYMBOLS.put( "DELETE", "\u2326" ); + TRIGGER_SYMBOLS.put( "TAB", "\u2B7E" ); + TRIGGER_SYMBOLS.put( "PAUSE", "\u23F8" ); + TRIGGER_SYMBOLS.put( "CAPS_LOCK", "\u21EA" ); + TRIGGER_SYMBOLS.put( "PAGE_UP", "\u21DE" ); + TRIGGER_SYMBOLS.put( "PAGE_DOWN", "\u21DF" ); + TRIGGER_SYMBOLS.put( "END", "\u2198" ); + TRIGGER_SYMBOLS.put( "HOME", "\u2196" ); + TRIGGER_SYMBOLS.put( "ESCAPE", "\u238b" ); + TRIGGER_SYMBOLS.put( "LEFT", "\u2190" ); + TRIGGER_SYMBOLS.put( "UP", "\u2191" ); + TRIGGER_SYMBOLS.put( "RIGHT", "\u2192" ); + TRIGGER_SYMBOLS.put( "DOWN", "\u2193" ); + TRIGGER_SYMBOLS.put( "NUMPAD0", "\u24ea" ); + TRIGGER_SYMBOLS.put( "NUMPAD1", "\u2460" ); + TRIGGER_SYMBOLS.put( "NUMPAD2", "\u2461" ); + TRIGGER_SYMBOLS.put( "NUMPAD3", "\u2462" ); + TRIGGER_SYMBOLS.put( "NUMPAD4", "\u2463" ); + TRIGGER_SYMBOLS.put( "NUMPAD5", "\u2464" ); + TRIGGER_SYMBOLS.put( "NUMPAD6", "\u2465" ); + TRIGGER_SYMBOLS.put( "NUMPAD7", "\u2466" ); + TRIGGER_SYMBOLS.put( "NUMPAD8", "\u2467" ); + TRIGGER_SYMBOLS.put( "NUMPAD9", "\u2468" ); + TRIGGER_SYMBOLS.put( "MULTIPLY", "\u00d7" ); + TRIGGER_SYMBOLS.put( "DIVIDE", "\u00f7" ); + TRIGGER_SYMBOLS.put( "ADD", "\u00d7" ); + TRIGGER_SYMBOLS.put( "ctrl", "\u2303" ); + TRIGGER_SYMBOLS.put( "alt", "\u2387" ); + TRIGGER_SYMBOLS.put( "shift", "\u21e7" ); + TRIGGER_SYMBOLS.put( "meta", "\u25c6" ); + TRIGGER_SYMBOLS.put( "win", "\u2756" ); + // Vertical bar is special + TRIGGER_SYMBOLS.put( "|", " | " ); + } + +} diff --git a/src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java similarity index 97% rename from src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java rename to src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java index 02318b2..a38336b 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/RoundBorder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java @@ -1,4 +1,4 @@ -package org.scijava.ui.behaviour.io; +package org.scijava.ui.behaviour.io.gui; import java.awt.Color; import java.awt.Component; diff --git a/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java similarity index 91% rename from src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java rename to src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java index 4133ced..df77b30 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java @@ -1,4 +1,4 @@ -package org.scijava.ui.behaviour.io; +package org.scijava.ui.behaviour.io.gui; import java.awt.Color; import java.awt.Dimension; @@ -11,6 +11,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import javax.swing.AbstractAction; import javax.swing.Box; @@ -37,11 +38,11 @@ public static interface TagSelectionChangeListener private static final String COMMIT_ACTION = "commit"; - private final List< String > selectedTags; + protected final List< String > selectedTags; - private final List< TagPanel > tagPanels; + protected final List< TagPanel > tagPanels; - private final List< String > tags; + protected final List< String > tags; private final JTextField textField; @@ -49,14 +50,22 @@ public static interface TagSelectionChangeListener private final HashSet< TagSelectionChangeListener > listeners; + private final Map< String, String > printables; + public TagPanelEditor( final Collection< String > tags ) { this( tags, true ); } public TagPanelEditor( final Collection< String > tags, final boolean editable ) + { + this( tags, editable, Collections.emptyMap() ); + } + + public TagPanelEditor( final Collection< String > tags, final boolean editable, final Map< String, String > printables ) { this.editable = editable; + this.printables = printables; this.tags = new ArrayList<>( tags ); this.tags.sort( null ); this.selectedTags = new ArrayList<>(); @@ -121,7 +130,7 @@ public void setTags( final Collection< String > tags ) repaint(); } - private void addTag( final String tag ) + protected void addTag( final String tag ) { final TagPanel tagp = new TagPanel( tag, this.tags.contains( tag ) ); selectedTags.add( tag ); @@ -257,7 +266,7 @@ public void run() } - private final class TagPanel extends JPanel + final class TagPanel extends JPanel { private static final long serialVersionUID = 1L; @@ -265,7 +274,8 @@ private final class TagPanel extends JPanel public TagPanel( final String tag, final boolean valid ) { final Font font = TagPanelEditor.this.getFont().deriveFont( TagPanelEditor.this.getFont().getSize2D() - 2f ); - final JLabel txt = new JLabel( tag ); + final String str = printables.containsKey( tag ) ? printables.get( tag ) : tag; + final JLabel txt = new JLabel( str ); txt.setFont( font ); txt.setOpaque( true ); if ( !valid ) @@ -303,12 +313,12 @@ private void notifyListeners() public void addTagSelectionChangeListener( final TagSelectionChangeListener listener ) { - listeners.add(listener); + listeners.add( listener ); } public void removeTagSelectionChangeListener( final TagSelectionChangeListener listener ) { - listeners.remove(listener); + listeners.remove( listener ); } } From df86ef0e8d55e296a18bc7d933cc14590643937e Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Thu, 26 Oct 2017 17:04:04 +0200 Subject: [PATCH 035/184] Rework the InputTriggerPanelEditor. --- ...itor.java => InputTriggerPanelEditor.java} | 286 ++++++++++++------ 1 file changed, 198 insertions(+), 88 deletions(-) rename src/main/java/org/scijava/ui/behaviour/io/gui/{KeyBindingsPanelEditor.java => InputTriggerPanelEditor.java} (57%) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/KeyBindingsPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java similarity index 57% rename from src/main/java/org/scijava/ui/behaviour/io/gui/KeyBindingsPanelEditor.java rename to src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index 9dd8218..ad41f53 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/KeyBindingsPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -8,7 +8,6 @@ import java.awt.event.KeyEvent; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -27,33 +26,33 @@ import javax.swing.event.DocumentListener; import javax.swing.text.BadLocationException; -public class KeyBindingsPanelEditor extends JPanel +import org.scijava.ui.behaviour.InputTrigger; + +public class InputTriggerPanelEditor extends JPanel { @FunctionalInterface - public static interface KeyBindingsChangeListener + public static interface InputTriggerChangeListener { - public void keyBindingsChanged(); + public void inputTriggerChanged(); } private static final long serialVersionUID = 1L; private static final String COMMIT_ACTION = "commit"; - protected final List< String > selectedKeys; - - protected final List< KeyItem > keyItems; + private final List< KeyItem > keyItems; private final JTextField textField; - private final boolean editable; + private final HashSet< InputTriggerChangeListener > listeners; + + private InputTrigger trigger = InputTrigger.NOT_MAPPED; - private final HashSet< KeyBindingsChangeListener > listeners; + private String invalidTriggerStr = null; - public KeyBindingsPanelEditor( final boolean editable ) + public InputTriggerPanelEditor( final boolean editable ) { - this.editable = editable; - this.selectedKeys = new ArrayList<>(); this.keyItems = new ArrayList<>(); this.listeners = new HashSet<>(); @@ -74,7 +73,7 @@ public KeyBindingsPanelEditor( final boolean editable ) final Autocomplete autoComplete = new Autocomplete(); textField.getDocument().addDocumentListener( autoComplete ); textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ), COMMIT_ACTION ); - textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_SPACE, 0 ), COMMIT_ACTION ); + textField.getInputMap().put( KeyStroke.getKeyStroke( ' ' ), COMMIT_ACTION ); textField.getActionMap().put( COMMIT_ACTION, autoComplete.new CommitAction() ); textField.addKeyListener( new KeyAdapter() { @@ -85,9 +84,9 @@ public void keyPressed( final KeyEvent e ) * We have to use a key listener to deal separately with * character removal and tag removal. */ - if ( e.getKeyCode() == KeyEvent.VK_BACK_SPACE && textField.getText().isEmpty() && !selectedKeys.isEmpty() ) + if ( e.getKeyCode() == KeyEvent.VK_BACK_SPACE && textField.getText().isEmpty() && !keyItems.isEmpty() ) { - removeTag( selectedKeys.get( selectedKeys.size() - 1 ) ); + removeLastKeyItem(); e.consume(); } } @@ -98,37 +97,161 @@ public void keyPressed( final KeyEvent e ) add( Box.createHorizontalGlue() ); } - public void setKeys( final Collection< String > tags ) + public void setInputTrigger( final InputTrigger trigger ) { - for ( final KeyItem keyItem : keyItems ) - remove( keyItem ); - selectedKeys.clear(); - keyItems.clear(); + this.trigger = trigger; + this.invalidTriggerStr = null; + regenKeyPanels(); + } - for ( final String tag : tags ) - addKey( tag ); - revalidate(); - repaint(); + public InputTrigger getInputTrigger() + { + return trigger; } - protected void addKey( final String key ) + private void checkAndAppendKey( final String key ) { - final KeyItem tagp = new KeyItem( key, INPUT_TRIGGER_SYNTAX_TAGS.contains( key ) ); - selectedKeys.add( key ); - keyItems.add( tagp ); - add( tagp, getComponentCount() - 2 ); + final String trimmed = key.trim(); + if ( trimmed.equals( "|" ) ) + { + /* + * Special case: the user wants to enter keys to ignore. + */ + + final String str = ( null == trigger || trigger == InputTrigger.NOT_MAPPED ) + ? trimmed + : trigger.toString() + " " + trimmed; + + this.trigger = null; + this.invalidTriggerStr = str.trim(); + regenKeyPanels(); + return; + } + + // Find its proper case equivalent in the syntax list. + String properCapKey = null; + for ( int i = 0; i < INPUT_TRIGGER_SYNTAX_TAGS.size(); i++ ) + { + if ( INPUT_TRIGGER_SYNTAX_TAGS.get( i ).equalsIgnoreCase( trimmed ) ) + { + properCapKey = INPUT_TRIGGER_SYNTAX_TAGS.get( i ); + break; + } + } + + if ( null != properCapKey ) + { + // Try to append the key to the trigger. + final String str = ( null == trigger ) + ? invalidTriggerStr + " " + properCapKey + : ( trigger == InputTrigger.NOT_MAPPED ) + ? properCapKey + : trigger.toString() + " " + properCapKey; + + try + { + this.trigger = InputTrigger.getFromString( str ); + this.invalidTriggerStr = null; + } + catch ( final IllegalArgumentException iae ) + { + this.trigger = null; + this.invalidTriggerStr = str.trim(); + } + regenKeyPanels(); + } } - private void removeTag( final String tag ) + private void removeLastKeyItem() { - final int index = selectedKeys.indexOf( tag ); - if ( index < 0 ) + // Try to remove the last key item. + final String[] tokens; + if ( null == trigger ) + { + /* + * The trigger was invalid. In that case we show what would be the + * key sequence in red. + */ + tokens = invalidTriggerStr.split( " " ); + } + else + { + /* + * The trigger field is valid. + */ + tokens = trigger.toString().split( " " ); + } + if ( tokens.length == 0 ) return; - selectedKeys.remove( index ); - final KeyItem tagPanel = keyItems.remove( index ); + final StringBuilder strBlder = new StringBuilder(); + for ( int i = 0; i < tokens.length - 1; i++ ) + strBlder.append( tokens[ i ] + " " ); + + final String str = strBlder.toString(); + try + { + this.trigger = str.isEmpty() + ? InputTrigger.NOT_MAPPED + : InputTrigger.getFromString( str ); + this.invalidTriggerStr = null; + } + catch ( final IllegalArgumentException iae ) + { + this.trigger = null; + this.invalidTriggerStr = str.trim(); + } + regenKeyPanels(); notifyListeners(); - remove( tagPanel ); + } + + private void regenKeyPanels() + { + // Clear + for ( final KeyItem keyItem : keyItems ) + remove( keyItem ); + keyItems.clear(); + + final String[] tokens; + boolean valid; + if ( null == trigger ) + { + /* + * The trigger was invalid. In that case we show what would be the + * key sequence in red. + */ + tokens = invalidTriggerStr.split( " " ); + valid = false; + } + else + { + /* + * The trigger field is valid. + */ + + valid = true; + if ( trigger == InputTrigger.NOT_MAPPED ) + tokens = new String[] {}; + else + tokens = trigger.toString().split( " " ); + + } + + if ( tokens.length == 0 ) + { + trigger = InputTrigger.NOT_MAPPED; + invalidTriggerStr = null; + } + else + { + for ( final String key : tokens ) + { + final KeyItem tagp = new KeyItem( key, valid ); + keyItems.add( tagp ); + add( tagp, getComponentCount() - 2 ); + } + } + revalidate(); repaint(); } @@ -183,12 +306,13 @@ public void insertUpdate( final DocumentEvent ev ) if ( pos - w < 2 ) return; - final String prefix = content.substring( w + 1 ).toLowerCase(); - final int n = Collections.binarySearch( INPUT_TRIGGER_SYNTAX_TAGS, prefix ); + final String prefix = content.substring( w + 1 ); + // We search on the lower case list. + final int n = Collections.binarySearch( INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS, prefix.toLowerCase() ); if ( n < 0 && -n <= INPUT_TRIGGER_SYNTAX_TAGS.size() ) { final String match = INPUT_TRIGGER_SYNTAX_TAGS.get( -n - 1 ); - if ( match.startsWith( prefix ) ) + if ( match.toLowerCase().startsWith( prefix.toLowerCase() ) ) { // A completion is found final String completion = match.substring( pos - w ); @@ -206,19 +330,10 @@ public class CommitAction extends AbstractAction @Override public void actionPerformed( final ActionEvent ev ) { - final String key = textField.getText().trim().toUpperCase(); - if ( selectedKeys.contains( key ) ) - { - // Do not allow more than 1 tag instance. - textField.setText( "" ); - return; - } - - addKey( key ); + final String key = textField.getText().trim(); + checkAndAppendKey( key ); textField.setText( "" ); notifyListeners(); - revalidate(); - repaint(); } } @@ -247,80 +362,62 @@ public void run() } - final class KeyItem extends JPanel + private final class KeyItem extends JPanel { private static final long serialVersionUID = 1L; public KeyItem( final String tag, final boolean valid ) { - final Font parentFont = KeyBindingsPanelEditor.this.getFont(); + final Font parentFont = InputTriggerPanelEditor.this.getFont(); final Font font = parentFont.deriveFont( parentFont.getSize2D() - 2f ); - final String str = TRIGGER_SYMBOLS.containsKey( tag ) ? TRIGGER_SYMBOLS.get( tag ) : tag; + final String str = TRIGGER_SYMBOLS.containsKey( tag ) ? ( " " + TRIGGER_SYMBOLS.get( tag ) + " " ) : ( " " + tag + " " ); final JLabel txt = new JLabel( str ); txt.setFont( font ); txt.setOpaque( true ); if ( !valid ) txt.setBackground( Color.PINK ); - txt.setBorder( new RoundBorder( getBackground().darker(), KeyBindingsPanelEditor.this, 3 ) ); - - final JLabel close = new JLabel( "\u00D7" ); - close.setOpaque( true ); - close.setBackground( getBackground().darker().darker() ); - close.setFont( font ); - close.addMouseListener( new java.awt.event.MouseAdapter() - { - @Override - public void mousePressed( final java.awt.event.MouseEvent evt ) - { - removeTag( tag ); - } - } ); + txt.setBorder( new RoundBorder( getBackground().darker(), InputTriggerPanelEditor.this, 1 ) ); setLayout( new BoxLayout( this, BoxLayout.LINE_AXIS ) ); - if ( editable ) - add( close ); add( Box.createHorizontalStrut( 1 ) ); add( txt ); - add( Box.createHorizontalStrut( 4 ) ); + add( Box.createHorizontalStrut( 1 ) ); setOpaque( false ); } } private void notifyListeners() { - for ( final KeyBindingsChangeListener listener : listeners ) - listener.keyBindingsChanged(); + for ( final InputTriggerChangeListener listener : listeners ) + listener.inputTriggerChanged(); } - public void addTagSelectionChangeListener( final KeyBindingsChangeListener listener ) + public void addInputTriggerChangeListener( final InputTriggerChangeListener listener ) { listeners.add( listener ); } - public void removeTagSelectionChangeListener( final KeyBindingsChangeListener listener ) + public void removeInputTriggerChangeListener( final InputTriggerChangeListener listener ) { listeners.remove( listener ); } private static final List< String > INPUT_TRIGGER_SYNTAX_TAGS = new ArrayList<>(); - + private static final List< String > INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS; private static final Map< String, String > TRIGGER_SYMBOLS = new HashMap<>(); - static { for ( int i = 0; i < 26; i++ ) - { INPUT_TRIGGER_SYNTAX_TAGS.add( String.valueOf( ( char ) ( 'A' + i ) ) ); - INPUT_TRIGGER_SYNTAX_TAGS.add( String.valueOf( ( char ) ( 'a' + i ) ) ); - // Show small letters as upper case. - TRIGGER_SYMBOLS.put( String.valueOf( ( char ) ( 'a' + i ) ), String.valueOf( ( char ) ( 'A' + i ) ) ); - } for ( int i = 0; i < 10; i++ ) - INPUT_TRIGGER_SYNTAX_TAGS.add( String.valueOf( ( char ) ( '0' + i ) ) ); + INPUT_TRIGGER_SYNTAX_TAGS.add( "" + i ); + for ( int i = 1; i <= 24; i++ ) + INPUT_TRIGGER_SYNTAX_TAGS.add( "F" + i ); INPUT_TRIGGER_SYNTAX_TAGS.addAll( Arrays.asList( new String[] { + "all", "ENTER", "BACK_SPACE", "TAB", @@ -374,12 +471,16 @@ public void removeTagSelectionChangeListener( final KeyBindingsChangeListener li "meta", "win", "double-click", - "button1 ", - "button2 ", - "button3 ", - "scroll" + "button1", + "button2", + "button3", + "scroll", + "|" } ) ); - INPUT_TRIGGER_SYNTAX_TAGS.sort( null ); + INPUT_TRIGGER_SYNTAX_TAGS.sort( String.CASE_INSENSITIVE_ORDER ); + INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS = new ArrayList<>(INPUT_TRIGGER_SYNTAX_TAGS.size()); + for ( final String tag : INPUT_TRIGGER_SYNTAX_TAGS ) + INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS.add( tag.toLowerCase() ); TRIGGER_SYMBOLS.put( "ENTER", "\u23CE" ); TRIGGER_SYMBOLS.put( "BACK_SPACE", "\u232B" ); @@ -408,14 +509,23 @@ public void removeTagSelectionChangeListener( final KeyBindingsChangeListener li TRIGGER_SYMBOLS.put( "NUMPAD9", "\u2468" ); TRIGGER_SYMBOLS.put( "MULTIPLY", "\u00d7" ); TRIGGER_SYMBOLS.put( "DIVIDE", "\u00f7" ); - TRIGGER_SYMBOLS.put( "ADD", "\u00d7" ); + TRIGGER_SYMBOLS.put( "ADD", "+" ); + TRIGGER_SYMBOLS.put( "SUBTRACT", "-" ); + TRIGGER_SYMBOLS.put( "COMMA", ","); + TRIGGER_SYMBOLS.put( "PERIOD", "."); + TRIGGER_SYMBOLS.put( "SLASH", "/" ); + TRIGGER_SYMBOLS.put( "SEMICOLON", ";" ); + TRIGGER_SYMBOLS.put( "EQUALS", "="); + TRIGGER_SYMBOLS.put( "OPEN_BRACKET", "["); + TRIGGER_SYMBOLS.put( "BACK_SLASH", "\\"); + TRIGGER_SYMBOLS.put( "CLOSE_BRACKET", "]"); TRIGGER_SYMBOLS.put( "ctrl", "\u2303" ); TRIGGER_SYMBOLS.put( "alt", "\u2387" ); TRIGGER_SYMBOLS.put( "shift", "\u21e7" ); TRIGGER_SYMBOLS.put( "meta", "\u25c6" ); TRIGGER_SYMBOLS.put( "win", "\u2756" ); // Vertical bar is special - TRIGGER_SYMBOLS.put( "|", " | " ); + TRIGGER_SYMBOLS.put( "|", " | " ); } } From df25c6b533b456a9f0896f47d2ddfa36e86070c6 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Thu, 26 Oct 2017 17:06:12 +0200 Subject: [PATCH 036/184] Use the input trigger editor in the visual editor. --- .../ui/behaviour/io/VisualEditorPanel.java | 109 ++++++++---------- 1 file changed, 46 insertions(+), 63 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index bf85c80..302894a 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -34,12 +34,11 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; -import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.io.InputTriggerConfig.Input; -import org.scijava.ui.behaviour.io.gui.KeyBindingsPanelEditor; +import org.scijava.ui.behaviour.io.gui.InputTriggerPanelEditor; import org.scijava.ui.behaviour.io.gui.TagPanelEditor; import org.scijava.ui.behaviour.io.yaml.YamlConfigIO; @@ -50,13 +49,7 @@ public class VisualEditorPanel extends JPanel private JTextField textFieldFilter; - private KeyBindingsPanelEditor textFieldBinding; - - private InputTriggerConfig config; - - private Set< String > actions; - - private Set< String > contexts; + private InputTriggerPanelEditor textFieldBinding; private final MyTableModel tableModel; @@ -65,10 +58,6 @@ public class VisualEditorPanel extends JPanel */ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > actions, final Set< String > contexts ) { - this.config = config; - this.actions = actions; - this.contexts = contexts; - /* * GUI */ @@ -119,7 +108,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a gbc_lblName.gridy = 0; panelCommandEditor.add( lblName, gbc_lblName ); - final JLabel labelActionName = new JLabel( "<>" ); + final JLabel labelActionName = new JLabel(); final GridBagConstraints gbc_labelActionName = new GridBagConstraints(); gbc_labelActionName.insets = new Insets( 5, 5, 5, 5 ); gbc_labelActionName.gridx = 1; @@ -134,7 +123,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a gbc_lblBinding.gridy = 0; panelCommandEditor.add( lblBinding, gbc_lblBinding ); - textFieldBinding = new KeyBindingsPanelEditor( true ); + textFieldBinding = new InputTriggerPanelEditor( true ); final GridBagConstraints gbc_textFieldBinding = new GridBagConstraints(); gbc_textFieldBinding.insets = new Insets( 5, 5, 5, 5 ); gbc_textFieldBinding.fill = GridBagConstraints.HORIZONTAL; @@ -157,7 +146,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a gbc_lblDescription.gridy = 1; panelCommandEditor.add( lblDescription, gbc_lblDescription ); - final JLabel labelActionDescription = new JLabel( "<>" ); + final JLabel labelActionDescription = new JLabel(); final GridBagConstraints gbc_labelActionDescription = new GridBagConstraints(); gbc_labelActionDescription.gridheight = 2; gbc_labelActionDescription.insets = new Insets( 5, 5, 5, 5 ); @@ -231,16 +220,21 @@ public void valueChanged( final ListSelectionEvent e ) return; final String action = tableModel.actions.get( row ); + labelActionName.setText( action ); + final InputTrigger trigger = tableModel.bindings.get( row ); + textFieldBinding.setInputTrigger( trigger ); + final List< String > contexts = new ArrayList<>( tableModel.contexts.get( row ) ); + panelContextEditor.setTags( contexts ); - labelActionName.setText( action ); labelActionDescription.setText( "TODO" ); -// textFieldBinding.setText( trigger == null ? "" : prettyPrintTrigger( trigger ) ); TODO - panelContextEditor.setTags( contexts ); } } ); + // Listen to changes in the + textFieldBinding.addInputTriggerChangeListener( () -> keybindingsChanged( tableBindings.getSelectedRow(), textFieldBinding.getInputTrigger() ) ); + // Listen to changes in context editor and forward to table model. panelContextEditor.addTagSelectionChangeListener( () -> contextsChanged( tableBindings.getSelectedRow(), panelContextEditor.getSelectedTags() ) ); @@ -256,6 +250,15 @@ public void valueChanged( final ListSelectionEvent e ) * INNER CLASSES */ + private void keybindingsChanged( final int row, final InputTrigger inputTrigger ) + { + if ( row < 0 ) + return; + + tableModel.bindings.set( row, inputTrigger ); + tableModel.fireTableCellUpdated( row, 1 ); + } + private void contextsChanged( final int row, final List< String > selectedContexts ) { if ( row < 0 ) @@ -268,14 +271,14 @@ private void contextsChanged( final int row, final List< String > selectedContex private static final class MyContextsRenderer extends TagPanelEditor implements TableCellRenderer { + private static final long serialVersionUID = 1L; + public MyContextsRenderer( final Collection< String > tags ) { super( tags, false ); setBorder( null ); } - private static final long serialVersionUID = 1L; - @Override public Component getTableCellRendererComponent( final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column ) { @@ -290,59 +293,39 @@ public Component getTableCellRendererComponent( final JTable table, final Object } } - private static final class MyBindingsRenderer extends DefaultTableCellRenderer implements TableCellRenderer + private static final class MyBindingsRenderer extends InputTriggerPanelEditor implements TableCellRenderer { private static final long serialVersionUID = 1L; + public MyBindingsRenderer() + { + super( false ); + setBorder( null ); + } + @Override public Component getTableCellRendererComponent( final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column ) { - super.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column ); + setForeground( isSelected ? table.getSelectionForeground() : table.getForeground() ); + setBackground( isSelected ? table.getSelectionBackground() : table.getBackground() ); + final InputTrigger input = ( InputTrigger ) value; - setText( null == input ? "" : prettyPrintTrigger( input ) ); - setToolTipText( null == input ? "" : input.toString() ); + if ( null != input ) + { + setInputTrigger( input ); + final String val = input.toString(); + setToolTipText( val ); + } + else + { + setInputTrigger( InputTrigger.NOT_MAPPED ); + setToolTipText( "No binding" ); + } return this; } } - private static final String prettyPrintTrigger( final InputTrigger input ) - { - final String str = input.toString(); - final String str2 = str - .replaceAll( "shift", "\u21E7" ) - .replaceAll( "win", "\u229E" ) - .replaceAll( "ctrl", "\u2303" ) - .replaceAll( "escape", "\u238B" ) - .replaceAll( "tab", "\u21E5" ) - .replaceAll( "caps_lock", "\u21EA" ) - .replaceAll( "option", "\u2325" ) - .replaceAll( "Apple", "\uF8FF" ) - .replaceAll( "command", "\u2318" ) - .replaceAll( "space", "\u2423" ) - .replaceAll( "return", "\u23CE" ) - .replaceAll( "back_space", "\u232B" ) - .replaceAll( "delete", "\u2326" ) - .replaceAll( "home", "\u21F1" ) - .replaceAll( "end", "\u21F2" ) - .replaceAll( "page_up", "\u21DE" ) - .replaceAll( "page_down", "\u21DF" ) - .replaceAll( "up", "\u2191" ) - .replaceAll( "down", "\u2193" ) - .replaceAll( "left", "\u2190" ) - .replaceAll( "right", "\u2192" ) - .replaceAll( "clear", "\u2327" ) - .replaceAll( "num lock", "\u21ED" ) - .replaceAll( "enter", "\u2324" ) - .replaceAll( "eject", "\u23CF" ) - .replaceAll( "power", "\u233D" ) - .replaceAll( "button1", "left mouse button" ) - .replaceAll( "button2", "middle mouse button" ) - .replaceAll( "button3", "right mouse button" ) - .replaceAll( "scroll", "\u21c5" ); // double arrow. Not ideal. - return str2; - } - private static class MyTableModel extends AbstractTableModel { @@ -374,7 +357,7 @@ public MyTableModel( final Set< String > baseActions, final Map< String, Set< In if ( null == inputs ) { actions.add( action ); - bindings.add( null ); + bindings.add( InputTrigger.NOT_MAPPED ); contexts.add( Collections.emptyList() ); } else From cd634503139417c6c02552ba825b42b2f90be80e Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Thu, 26 Oct 2017 17:08:14 +0200 Subject: [PATCH 037/184] Remove the special char button. --- .../ui/behaviour/io/VisualEditorPanel.java | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 302894a..7d32c43 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -94,9 +94,9 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JPanel panelCommandEditor = new JPanel(); panelEditor.add( panelCommandEditor, BorderLayout.CENTER ); final GridBagLayout gbl_panelCommandEditor = new GridBagLayout(); - gbl_panelCommandEditor.columnWidths = new int[] { 30, 100, 30, 0, 0 }; + gbl_panelCommandEditor.columnWidths = new int[] { 30, 100, 30, 0 }; gbl_panelCommandEditor.rowHeights = new int[] { 20, 20, 20 }; - gbl_panelCommandEditor.columnWeights = new double[] { 0.0, 1.0, 0.0, 1.0, 0.0 }; + gbl_panelCommandEditor.columnWeights = new double[] { 0.0, 1.0, 0.0, 1.0 }; gbl_panelCommandEditor.rowWeights = new double[] { 0.0, 0.0, 0.0 }; panelCommandEditor.setLayout( gbl_panelCommandEditor ); @@ -125,19 +125,12 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a textFieldBinding = new InputTriggerPanelEditor( true ); final GridBagConstraints gbc_textFieldBinding = new GridBagConstraints(); - gbc_textFieldBinding.insets = new Insets( 5, 5, 5, 5 ); + gbc_textFieldBinding.insets = new Insets(5, 5, 5, 5); gbc_textFieldBinding.fill = GridBagConstraints.HORIZONTAL; gbc_textFieldBinding.gridx = 3; gbc_textFieldBinding.gridy = 0; panelCommandEditor.add( textFieldBinding, gbc_textFieldBinding ); - final JButton buttonSpecialChar = new JButton( "<" ); - final GridBagConstraints gbc_buttonSpecialChar = new GridBagConstraints(); - gbc_buttonSpecialChar.insets = new Insets( 5, 5, 5, 5 ); - gbc_buttonSpecialChar.gridx = 4; - gbc_buttonSpecialChar.gridy = 0; - panelCommandEditor.add( buttonSpecialChar, gbc_buttonSpecialChar ); - final JLabel lblDescription = new JLabel( "Description:" ); final GridBagConstraints gbc_lblDescription = new GridBagConstraints(); gbc_lblDescription.insets = new Insets( 5, 5, 5, 5 ); @@ -149,7 +142,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel labelActionDescription = new JLabel(); final GridBagConstraints gbc_labelActionDescription = new GridBagConstraints(); gbc_labelActionDescription.gridheight = 2; - gbc_labelActionDescription.insets = new Insets( 5, 5, 5, 5 ); + gbc_labelActionDescription.insets = new Insets(5, 5, 5, 5); gbc_labelActionDescription.gridx = 1; gbc_labelActionDescription.gridy = 1; panelCommandEditor.add( labelActionDescription, gbc_labelActionDescription ); @@ -164,8 +157,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final TagPanelEditor panelContextEditor = new TagPanelEditor( contexts ); final GridBagConstraints gbc_comboBoxContext = new GridBagConstraints(); - gbc_comboBoxContext.gridwidth = 2; - gbc_comboBoxContext.insets = new Insets( 5, 5, 5, 5 ); + gbc_comboBoxContext.insets = new Insets(5, 5, 5, 5); gbc_comboBoxContext.fill = GridBagConstraints.BOTH; gbc_comboBoxContext.gridx = 3; gbc_comboBoxContext.gridy = 1; @@ -173,7 +165,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel lblConflicts = new JLabel( "Conflicts:" ); final GridBagConstraints gbc_lblConflicts = new GridBagConstraints(); - gbc_lblConflicts.insets = new Insets( 5, 5, 5, 5 ); + gbc_lblConflicts.insets = new Insets(5, 5, 5, 5); gbc_lblConflicts.anchor = GridBagConstraints.WEST; gbc_lblConflicts.gridx = 2; gbc_lblConflicts.gridy = 2; @@ -181,7 +173,6 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel lblConflict = new JLabel( "TODO" ); final GridBagConstraints gbc_lblConflict = new GridBagConstraints(); - gbc_lblConflict.gridwidth = 2; gbc_lblConflict.gridx = 3; gbc_lblConflict.gridy = 2; panelCommandEditor.add( lblConflict, gbc_lblConflict ); From 7e74be8dd17a139c807eb96a423a39698070c601 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Fri, 27 Oct 2017 16:59:13 +0200 Subject: [PATCH 038/184] Visual-editor: GUI tweak. --- .../ui/behaviour/io/VisualEditorPanel.java | 83 ++++++++++--------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 7d32c43..e04b7c6 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -76,28 +76,31 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a panelEditor.add( panelCommandButtons, BorderLayout.NORTH ); panelCommandButtons.setLayout( new BoxLayout( panelCommandButtons, BoxLayout.X_AXIS ) ); - final JButton btnCopyCommand = new JButton( "Copy binding" ); + final JButton btnCopyCommand = new JButton( "Copy" ); + btnCopyCommand.setToolTipText("Duplicate action binding \nto a new, blank binding."); panelCommandButtons.add( btnCopyCommand ); - final JButton btnUnbindAction = new JButton( "Unbind action" ); + final JButton btnUnbindAction = new JButton( "Unbind" ); + btnUnbindAction.setToolTipText("Remove current binding\nfor current action."); panelCommandButtons.add( btnUnbindAction ); - final JButton btnDeleteAction = new JButton( "Delete binding" ); + final JButton btnDeleteAction = new JButton( "Unbind all" ); + btnDeleteAction.setToolTipText("Remove all bindings\nto current action."); panelCommandButtons.add( btnDeleteAction ); final Component horizontalGlue = Box.createHorizontalGlue(); panelCommandButtons.add( horizontalGlue ); final JButton btnExportCsv = new JButton( "Export CSV" ); + btnExportCsv.setToolTipText("Export all action bindings \nto a CSV file."); panelCommandButtons.add( btnExportCsv ); final JPanel panelCommandEditor = new JPanel(); panelEditor.add( panelCommandEditor, BorderLayout.CENTER ); final GridBagLayout gbl_panelCommandEditor = new GridBagLayout(); - gbl_panelCommandEditor.columnWidths = new int[] { 30, 100, 30, 0 }; - gbl_panelCommandEditor.rowHeights = new int[] { 20, 20, 20 }; - gbl_panelCommandEditor.columnWeights = new double[] { 0.0, 1.0, 0.0, 1.0 }; - gbl_panelCommandEditor.rowWeights = new double[] { 0.0, 0.0, 0.0 }; + gbl_panelCommandEditor.columnWidths = new int[] { 30, 100 }; + gbl_panelCommandEditor.columnWeights = new double[] { 0.0, 1.0 }; + gbl_panelCommandEditor.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 1.0 }; panelCommandEditor.setLayout( gbl_panelCommandEditor ); final JLabel lblName = new JLabel( "Name:" ); @@ -110,7 +113,8 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel labelActionName = new JLabel(); final GridBagConstraints gbc_labelActionName = new GridBagConstraints(); - gbc_labelActionName.insets = new Insets( 5, 5, 5, 5 ); + gbc_labelActionName.anchor = GridBagConstraints.WEST; + gbc_labelActionName.insets = new Insets(5, 5, 5, 5); gbc_labelActionName.gridx = 1; gbc_labelActionName.gridy = 0; panelCommandEditor.add( labelActionName, gbc_labelActionName ); @@ -119,64 +123,67 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final GridBagConstraints gbc_lblBinding = new GridBagConstraints(); gbc_lblBinding.anchor = GridBagConstraints.WEST; gbc_lblBinding.insets = new Insets( 5, 5, 5, 5 ); - gbc_lblBinding.gridx = 2; - gbc_lblBinding.gridy = 0; + gbc_lblBinding.gridx = 0; + gbc_lblBinding.gridy = 1; panelCommandEditor.add( lblBinding, gbc_lblBinding ); textFieldBinding = new InputTriggerPanelEditor( true ); final GridBagConstraints gbc_textFieldBinding = new GridBagConstraints(); gbc_textFieldBinding.insets = new Insets(5, 5, 5, 5); gbc_textFieldBinding.fill = GridBagConstraints.HORIZONTAL; - gbc_textFieldBinding.gridx = 3; - gbc_textFieldBinding.gridy = 0; + gbc_textFieldBinding.gridx = 1; + gbc_textFieldBinding.gridy = 1; panelCommandEditor.add( textFieldBinding, gbc_textFieldBinding ); - final JLabel lblDescription = new JLabel( "Description:" ); - final GridBagConstraints gbc_lblDescription = new GridBagConstraints(); - gbc_lblDescription.insets = new Insets( 5, 5, 5, 5 ); - gbc_lblDescription.anchor = GridBagConstraints.WEST; - gbc_lblDescription.gridx = 0; - gbc_lblDescription.gridy = 1; - panelCommandEditor.add( lblDescription, gbc_lblDescription ); - - final JLabel labelActionDescription = new JLabel(); - final GridBagConstraints gbc_labelActionDescription = new GridBagConstraints(); - gbc_labelActionDescription.gridheight = 2; - gbc_labelActionDescription.insets = new Insets(5, 5, 5, 5); - gbc_labelActionDescription.gridx = 1; - gbc_labelActionDescription.gridy = 1; - panelCommandEditor.add( labelActionDescription, gbc_labelActionDescription ); final JLabel lblContext = new JLabel( "Contexts:" ); final GridBagConstraints gbc_lblContext = new GridBagConstraints(); gbc_lblContext.anchor = GridBagConstraints.WEST; gbc_lblContext.insets = new Insets( 5, 5, 5, 5 ); - gbc_lblContext.gridx = 2; - gbc_lblContext.gridy = 1; + gbc_lblContext.gridx = 0; + gbc_lblContext.gridy = 2; panelCommandEditor.add( lblContext, gbc_lblContext ); final TagPanelEditor panelContextEditor = new TagPanelEditor( contexts ); final GridBagConstraints gbc_comboBoxContext = new GridBagConstraints(); gbc_comboBoxContext.insets = new Insets(5, 5, 5, 5); gbc_comboBoxContext.fill = GridBagConstraints.BOTH; - gbc_comboBoxContext.gridx = 3; - gbc_comboBoxContext.gridy = 1; + gbc_comboBoxContext.gridx = 1; + gbc_comboBoxContext.gridy = 2; panelCommandEditor.add( panelContextEditor, gbc_comboBoxContext ); final JLabel lblConflicts = new JLabel( "Conflicts:" ); final GridBagConstraints gbc_lblConflicts = new GridBagConstraints(); - gbc_lblConflicts.insets = new Insets(5, 5, 5, 5); + gbc_lblConflicts.insets = new Insets( 5, 5, 5, 5 ); gbc_lblConflicts.anchor = GridBagConstraints.WEST; - gbc_lblConflicts.gridx = 2; - gbc_lblConflicts.gridy = 2; + gbc_lblConflicts.gridx = 0; + gbc_lblConflicts.gridy = 3; panelCommandEditor.add( lblConflicts, gbc_lblConflicts ); - final JLabel lblConflict = new JLabel( "TODO" ); + final JLabel lblConflict = new JLabel( "" ); final GridBagConstraints gbc_lblConflict = new GridBagConstraints(); - gbc_lblConflict.gridx = 3; - gbc_lblConflict.gridy = 2; + gbc_lblConflict.insets = new Insets(5, 5, 5, 5); + gbc_lblConflict.gridx = 1; + gbc_lblConflict.gridy = 3; panelCommandEditor.add( lblConflict, gbc_lblConflict ); + final JLabel lblDescription = new JLabel( "Description:" ); + final GridBagConstraints gbc_lblDescription = new GridBagConstraints(); + gbc_lblDescription.fill = GridBagConstraints.VERTICAL; + gbc_lblDescription.insets = new Insets(5, 5, 5, 5); + gbc_lblDescription.anchor = GridBagConstraints.WEST; + gbc_lblDescription.gridx = 0; + gbc_lblDescription.gridy = 4; + panelCommandEditor.add( lblDescription, gbc_lblDescription ); + + final JLabel labelActionDescription = new JLabel(); + final GridBagConstraints gbc_labelActionDescription = new GridBagConstraints(); + gbc_labelActionDescription.fill = GridBagConstraints.VERTICAL; + gbc_labelActionDescription.insets = new Insets(5, 5, 5, 5); + gbc_labelActionDescription.gridx = 1; + gbc_labelActionDescription.gridy = 4; + panelCommandEditor.add( labelActionDescription, gbc_labelActionDescription ); + final JPanel panelButtons = new JPanel(); panelEditor.add( panelButtons, BorderLayout.SOUTH ); final FlowLayout flowLayout = ( FlowLayout ) panelButtons.getLayout(); @@ -218,8 +225,6 @@ public void valueChanged( final ListSelectionEvent e ) final List< String > contexts = new ArrayList<>( tableModel.contexts.get( row ) ); panelContextEditor.setTags( contexts ); - - labelActionDescription.setText( "TODO" ); } } ); From 1b8529be42cbb1c6bc8ed8621552ccdf7e0f0b3b Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Fri, 27 Oct 2017 18:09:06 +0200 Subject: [PATCH 039/184] Deal with the 'Copy' and 'Unbind' buttons. --- .../ui/behaviour/io/VisualEditorPanel.java | 171 ++++++++++++++---- 1 file changed, 134 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index e04b7c6..65f8933 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -12,6 +12,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -49,10 +50,16 @@ public class VisualEditorPanel extends JPanel private JTextField textFieldFilter; - private InputTriggerPanelEditor textFieldBinding; - private final MyTableModel tableModel; + private final InputTriggerPanelEditor keybindingEditor; + + private final TagPanelEditor contextsEditor; + + private final JLabel labelActionName; + + private final JTable tableBindings; + /** * Create the panel. */ @@ -77,22 +84,22 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a panelCommandButtons.setLayout( new BoxLayout( panelCommandButtons, BoxLayout.X_AXIS ) ); final JButton btnCopyCommand = new JButton( "Copy" ); - btnCopyCommand.setToolTipText("Duplicate action binding \nto a new, blank binding."); + btnCopyCommand.setToolTipText( "Duplicate action binding \nto a new, blank binding." ); panelCommandButtons.add( btnCopyCommand ); final JButton btnUnbindAction = new JButton( "Unbind" ); - btnUnbindAction.setToolTipText("Remove current binding\nfor current action."); + btnUnbindAction.setToolTipText( "Remove current binding\nfor current action." ); panelCommandButtons.add( btnUnbindAction ); final JButton btnDeleteAction = new JButton( "Unbind all" ); - btnDeleteAction.setToolTipText("Remove all bindings\nto current action."); + btnDeleteAction.setToolTipText( "Remove all bindings\nto current action." ); panelCommandButtons.add( btnDeleteAction ); final Component horizontalGlue = Box.createHorizontalGlue(); panelCommandButtons.add( horizontalGlue ); final JButton btnExportCsv = new JButton( "Export CSV" ); - btnExportCsv.setToolTipText("Export all action bindings \nto a CSV file."); + btnExportCsv.setToolTipText( "Export all action bindings \nto a CSV file." ); panelCommandButtons.add( btnExportCsv ); final JPanel panelCommandEditor = new JPanel(); @@ -111,10 +118,10 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a gbc_lblName.gridy = 0; panelCommandEditor.add( lblName, gbc_lblName ); - final JLabel labelActionName = new JLabel(); + this.labelActionName = new JLabel(); final GridBagConstraints gbc_labelActionName = new GridBagConstraints(); gbc_labelActionName.anchor = GridBagConstraints.WEST; - gbc_labelActionName.insets = new Insets(5, 5, 5, 5); + gbc_labelActionName.insets = new Insets( 5, 5, 5, 5 ); gbc_labelActionName.gridx = 1; gbc_labelActionName.gridy = 0; panelCommandEditor.add( labelActionName, gbc_labelActionName ); @@ -127,14 +134,13 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a gbc_lblBinding.gridy = 1; panelCommandEditor.add( lblBinding, gbc_lblBinding ); - textFieldBinding = new InputTriggerPanelEditor( true ); + this.keybindingEditor = new InputTriggerPanelEditor( true ); final GridBagConstraints gbc_textFieldBinding = new GridBagConstraints(); - gbc_textFieldBinding.insets = new Insets(5, 5, 5, 5); + gbc_textFieldBinding.insets = new Insets( 5, 5, 5, 5 ); gbc_textFieldBinding.fill = GridBagConstraints.HORIZONTAL; gbc_textFieldBinding.gridx = 1; gbc_textFieldBinding.gridy = 1; - panelCommandEditor.add( textFieldBinding, gbc_textFieldBinding ); - + panelCommandEditor.add( keybindingEditor, gbc_textFieldBinding ); final JLabel lblContext = new JLabel( "Contexts:" ); final GridBagConstraints gbc_lblContext = new GridBagConstraints(); @@ -144,13 +150,13 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a gbc_lblContext.gridy = 2; panelCommandEditor.add( lblContext, gbc_lblContext ); - final TagPanelEditor panelContextEditor = new TagPanelEditor( contexts ); + this.contextsEditor = new TagPanelEditor( contexts ); final GridBagConstraints gbc_comboBoxContext = new GridBagConstraints(); - gbc_comboBoxContext.insets = new Insets(5, 5, 5, 5); + gbc_comboBoxContext.insets = new Insets( 5, 5, 5, 5 ); gbc_comboBoxContext.fill = GridBagConstraints.BOTH; gbc_comboBoxContext.gridx = 1; gbc_comboBoxContext.gridy = 2; - panelCommandEditor.add( panelContextEditor, gbc_comboBoxContext ); + panelCommandEditor.add( contextsEditor, gbc_comboBoxContext ); final JLabel lblConflicts = new JLabel( "Conflicts:" ); final GridBagConstraints gbc_lblConflicts = new GridBagConstraints(); @@ -162,7 +168,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel lblConflict = new JLabel( "" ); final GridBagConstraints gbc_lblConflict = new GridBagConstraints(); - gbc_lblConflict.insets = new Insets(5, 5, 5, 5); + gbc_lblConflict.insets = new Insets( 5, 5, 5, 5 ); gbc_lblConflict.gridx = 1; gbc_lblConflict.gridy = 3; panelCommandEditor.add( lblConflict, gbc_lblConflict ); @@ -170,7 +176,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel lblDescription = new JLabel( "Description:" ); final GridBagConstraints gbc_lblDescription = new GridBagConstraints(); gbc_lblDescription.fill = GridBagConstraints.VERTICAL; - gbc_lblDescription.insets = new Insets(5, 5, 5, 5); + gbc_lblDescription.insets = new Insets( 5, 5, 5, 5 ); gbc_lblDescription.anchor = GridBagConstraints.WEST; gbc_lblDescription.gridx = 0; gbc_lblDescription.gridy = 4; @@ -179,7 +185,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel labelActionDescription = new JLabel(); final GridBagConstraints gbc_labelActionDescription = new GridBagConstraints(); gbc_labelActionDescription.fill = GridBagConstraints.VERTICAL; - gbc_labelActionDescription.insets = new Insets(5, 5, 5, 5); + gbc_labelActionDescription.insets = new Insets( 5, 5, 5, 5 ); gbc_labelActionDescription.gridx = 1; gbc_labelActionDescription.gridy = 4; panelCommandEditor.add( labelActionDescription, gbc_labelActionDescription ); @@ -201,7 +207,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a add( scrollPane, BorderLayout.CENTER ); tableModel = new MyTableModel( actions, config.actionToInputsMap ); - final JTable tableBindings = new JTable( tableModel ); + tableBindings = new JTable( tableModel ); tableBindings.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); tableBindings.setFillsViewportHeight( true ); tableBindings.setAutoResizeMode( JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS ); @@ -212,27 +218,19 @@ public void valueChanged( final ListSelectionEvent e ) { if ( e.getValueIsAdjusting() ) return; - - final int row = tableBindings.getSelectedRow(); - if ( row < 0 ) - return; - - final String action = tableModel.actions.get( row ); - labelActionName.setText( action ); - - final InputTrigger trigger = tableModel.bindings.get( row ); - textFieldBinding.setInputTrigger( trigger ); - - final List< String > contexts = new ArrayList<>( tableModel.contexts.get( row ) ); - panelContextEditor.setTags( contexts ); + updateEditors(); } } ); // Listen to changes in the - textFieldBinding.addInputTriggerChangeListener( () -> keybindingsChanged( tableBindings.getSelectedRow(), textFieldBinding.getInputTrigger() ) ); + keybindingEditor.addInputTriggerChangeListener( () -> keybindingsChanged( tableBindings.getSelectedRow(), keybindingEditor.getInputTrigger() ) ); // Listen to changes in context editor and forward to table model. - panelContextEditor.addTagSelectionChangeListener( () -> contextsChanged( tableBindings.getSelectedRow(), panelContextEditor.getSelectedTags() ) ); + contextsEditor.addTagSelectionChangeListener( () -> contextsChanged( tableBindings.getSelectedRow(), contextsEditor.getSelectedTags() ) ); + + // Button presses. + btnCopyCommand.addActionListener( ( e ) -> copyCommand( tableBindings.getSelectedRow() ) ); + btnUnbindAction.addActionListener( ( e ) -> unbindCommand( tableBindings.getSelectedRow() ) ); // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); @@ -242,9 +240,100 @@ public void valueChanged( final ListSelectionEvent e ) scrollPane.setViewportView( tableBindings ); } - /* - * INNER CLASSES - */ + private void updateEditors() + { + final int row = tableBindings.getSelectedRow(); + if ( row < 0 ) + { + labelActionName.setText( "" ); + keybindingEditor.setInputTrigger( InputTrigger.NOT_MAPPED ); + contextsEditor.setTags( Collections.emptyList() ); + return; + } + + final String action = tableModel.actions.get( row ); + final InputTrigger trigger = tableModel.bindings.get( row ); + final List< String > contexts = new ArrayList<>( tableModel.contexts.get( row ) ); + + labelActionName.setText( action ); + keybindingEditor.setInputTrigger( trigger ); + contextsEditor.setTags( contexts ); + } + + private void unbindCommand( final int row ) + { + if ( row < 0 ) + return; + + final InputTrigger inputTrigger = tableModel.bindings.get( row ); + if ( inputTrigger == InputTrigger.NOT_MAPPED ) + return; + + // Update model & + keybindingsChanged( row, InputTrigger.NOT_MAPPED ); + contextsChanged( row, Collections.emptyList() ); + + // Find whether we have two lines with the same action, unbound. + removeDuplicates(); + } + + private void removeDuplicates() + { + final Map< String, Set< InputTrigger > > bindings = new HashMap<>(); + final List< Integer > toRemove = new ArrayList<>(); + for ( int row = 0; row < tableModel.getRowCount(); row++ ) + { + final String action = tableModel.actions.get( row ); + final InputTrigger trigger = tableModel.bindings.get( row ); + + if ( bindings.get( action ) == null ) + { + final Set< InputTrigger > triggers = new HashSet<>(); + triggers.add( trigger ); + bindings.put( action, triggers ); + } + else + { + final Set< InputTrigger > triggers = bindings.get( action ); + final boolean notAlreadyPresent = triggers.add( trigger ); + if ( !notAlreadyPresent ) + toRemove.add( Integer.valueOf( row ) ); + } + } + + toRemove.sort( Comparator.reverseOrder() ); + for ( final Integer rowToRemove : toRemove ) + { + final int row = rowToRemove.intValue(); + tableModel.actions.remove( row ); + tableModel.bindings.remove( row ); + tableModel.contexts.remove( row ); + tableModel.fireTableRowsDeleted( row, row ); + } + + updateEditors(); + } + + private void copyCommand( final int row ) + { + if ( row < 0 ) + return; + + final String action = tableModel.actions.get( row ); + // Check whether there is already a line in the table without a binding. + for ( int i = 0; i < tableModel.actions.size(); i++ ) + { + // Brute force. + if ( tableModel.actions.get( i ).equals( action ) && tableModel.bindings.get( i ) == InputTrigger.NOT_MAPPED ) + return; + } + + // Create one then. + tableModel.actions.add( row + 1, action ); + tableModel.bindings.add( row + 1, InputTrigger.NOT_MAPPED ); + tableModel.contexts.add( row + 1, Collections.emptyList() ); + tableModel.fireTableRowsInserted( row, row ); + } private void keybindingsChanged( final int row, final InputTrigger inputTrigger ) { @@ -264,6 +353,10 @@ private void contextsChanged( final int row, final List< String > selectedContex tableModel.fireTableCellUpdated( row, 2 ); } + /* + * INNER CLASSES + */ + private static final class MyContextsRenderer extends TagPanelEditor implements TableCellRenderer { @@ -413,6 +506,10 @@ private static final class InputComparator implements Comparator< Input > @Override public int compare( final Input o1, final Input o2 ) { + if ( o1.trigger == InputTrigger.NOT_MAPPED ) + return 1; + if ( o2.trigger == InputTrigger.NOT_MAPPED ) + return -1; return o1.trigger.toString().compareTo( o2.trigger.toString() ); } From cff227eddf8feb5d1f907326b4d13a12df9a8592 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sat, 28 Oct 2017 16:36:53 +0200 Subject: [PATCH 040/184] Remove duplicates after changing selection too. --- .../java/org/scijava/ui/behaviour/io/VisualEditorPanel.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 65f8933..1e48840 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -218,7 +218,9 @@ public void valueChanged( final ListSelectionEvent e ) { if ( e.getValueIsAdjusting() ) return; + removeDuplicates(); updateEditors(); + } } ); From 988874354352bf4b17b1b60e07c9a36f85307a84 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sat, 28 Oct 2017 16:41:26 +0200 Subject: [PATCH 041/184] Button to remove all bindings from a command. --- .../ui/behaviour/io/VisualEditorPanel.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 1e48840..210bf57 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -233,6 +233,7 @@ public void valueChanged( final ListSelectionEvent e ) // Button presses. btnCopyCommand.addActionListener( ( e ) -> copyCommand( tableBindings.getSelectedRow() ) ); btnUnbindAction.addActionListener( ( e ) -> unbindCommand( tableBindings.getSelectedRow() ) ); + btnDeleteAction.addActionListener( (e)-> unbindAllCommand(tableBindings.getSelectedRow()) ); // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); @@ -242,6 +243,24 @@ public void valueChanged( final ListSelectionEvent e ) scrollPane.setViewportView( tableBindings ); } + private void unbindAllCommand( final int row ) + { + if (row < 0) + return; + + final String action = tableModel.actions.get( row ); + for ( int i = 0; i < tableModel.actions.size(); i++ ) + { + if (tableModel.actions.get( i ).equals( action )) + { + tableModel.bindings.set( i, InputTrigger.NOT_MAPPED ); + tableModel.contexts.set( i, Collections.emptyList() ); + } + } + removeDuplicates(); + tableModel.fireTableRowsUpdated( row, row ); + } + private void updateEditors() { final int row = tableBindings.getSelectedRow(); From 1a51860f5f5a56d58e3106bac3e44358409c47b6 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 29 Oct 2017 00:19:39 +0200 Subject: [PATCH 042/184] Implement the `Export to CSV` button. --- .../ui/behaviour/io/VisualEditorPanel.java | 95 ++++++++++++++++++- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 210bf57..c4e2203 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -7,6 +7,9 @@ import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; import java.io.StringReader; import java.util.ArrayList; import java.util.Collection; @@ -22,18 +25,22 @@ import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; +import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.ScrollPaneConstants; +import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import javax.swing.filechooser.FileFilter; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; @@ -48,6 +55,26 @@ public class VisualEditorPanel extends JPanel private static final long serialVersionUID = 1L; + private static JFileChooser fileChooser = new JFileChooser(); + static + { + fileChooser.setFileFilter( new FileFilter() + { + + @Override + public String getDescription() + { + return "CSV files"; + } + + @Override + public boolean accept( final File f ) + { + return f.isFile() && f.getName().toLowerCase().endsWith( ".csv" ); + } + } ); + } + private JTextField textFieldFilter; private final MyTableModel tableModel; @@ -233,7 +260,8 @@ public void valueChanged( final ListSelectionEvent e ) // Button presses. btnCopyCommand.addActionListener( ( e ) -> copyCommand( tableBindings.getSelectedRow() ) ); btnUnbindAction.addActionListener( ( e ) -> unbindCommand( tableBindings.getSelectedRow() ) ); - btnDeleteAction.addActionListener( (e)-> unbindAllCommand(tableBindings.getSelectedRow()) ); + btnDeleteAction.addActionListener( ( e ) -> unbindAllCommand( tableBindings.getSelectedRow() ) ); + btnExportCsv.addActionListener( ( e ) -> exportToCsv() ); // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); @@ -243,15 +271,75 @@ public void valueChanged( final ListSelectionEvent e ) scrollPane.setViewportView( tableBindings ); } + private final static String CSV_SEPARATOR = ","; + + private void exportToCsv() + { + final int userSignal = fileChooser.showSaveDialog( this ); + if ( userSignal != JFileChooser.APPROVE_OPTION ) + return; + + final File file = fileChooser.getSelectedFile(); + if ( file.exists() ) + { + if ( !file.canWrite() ) + { + JOptionPane.showMessageDialog( fileChooser, "Cannot write on existing file " + file.getAbsolutePath(), "File error", JOptionPane.ERROR_MESSAGE ); + return; + } + final int doOverwrite = JOptionPane.showConfirmDialog( fileChooser, "The file already exists. Do you want to overwrite it?", "Overwrite?", JOptionPane.YES_NO_OPTION ); + if ( doOverwrite != JOptionPane.YES_OPTION ) + return; + } + + + final StringBuilder sb = new StringBuilder(); + sb.append( MyTableModel.TABLE_HEADERS[0] ); + sb.append( CSV_SEPARATOR + '\t' ); + sb.append( MyTableModel.TABLE_HEADERS[1] ); + sb.append( CSV_SEPARATOR + '\t' ); + sb.append( MyTableModel.TABLE_HEADERS[2] ); + sb.append( '\n' ); + + for ( int i = 0; i < tableModel.actions.size(); i++ ) + { + sb.append( tableModel.actions.get( i ) ); + sb.append( CSV_SEPARATOR + '\t' ); + sb.append( tableModel.bindings.get( i ).toString() ); + sb.append( CSV_SEPARATOR + '\t' ); + final List< String > contexts = tableModel.contexts.get( i ); + if (!contexts.isEmpty()) + { + sb.append( contexts.get( 0 ) ); + for ( int j = 1; j < contexts.size(); j++ ) + sb.append( " - " + contexts.get( j ) ); + } + sb.append( '\n' ); + } + + try (final PrintWriter pw = new PrintWriter( file )) + { + + pw.write( sb.toString() ); + pw.close(); + } + catch ( final FileNotFoundException e ) + { + JOptionPane.showMessageDialog( fileChooser, "Error writing file:\n" + e.getMessage(), "Error writing file.", JOptionPane.ERROR_MESSAGE ); + e.printStackTrace(); + } + + } + private void unbindAllCommand( final int row ) { - if (row < 0) + if ( row < 0 ) return; final String action = tableModel.actions.get( row ); for ( int i = 0; i < tableModel.actions.size(); i++ ) { - if (tableModel.actions.get( i ).equals( action )) + if ( tableModel.actions.get( i ).equals( action ) ) { tableModel.bindings.set( i, InputTrigger.NOT_MAPPED ); tableModel.contexts.set( i, Collections.emptyList() ); @@ -609,6 +697,7 @@ public void run() { final JFrame frame = new JFrame( "Behaviour Key bindings editor" ); final VisualEditorPanel editorPanel = new VisualEditorPanel( getDemoConfig(), getDemoActions(), getDemoContexts() ); + SwingUtilities.updateComponentTreeUI(VisualEditorPanel.fileChooser); frame.getContentPane().add( editorPanel ); frame.pack(); frame.setVisible( true ); From 8fa199a848c9d966dde901e43c58b3384d57c31a Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 29 Oct 2017 10:20:21 +0100 Subject: [PATCH 043/184] Implement apply/restore buttons. --- .../ui/behaviour/io/VisualEditorPanel.java | 52 +++++++++++++++++-- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index c4e2203..87e32e2 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -77,7 +77,7 @@ public boolean accept( final File f ) private JTextField textFieldFilter; - private final MyTableModel tableModel; + private MyTableModel tableModel; private final InputTriggerPanelEditor keybindingEditor; @@ -87,6 +87,12 @@ public boolean accept( final File f ) private final JTable tableBindings; + private final InputTriggerConfig config; + + private final Set< String > actions; + + private final Set< String > contexts; + /** * Create the panel. */ @@ -96,6 +102,9 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a * GUI */ + this.config = config; + this.actions = actions; + this.contexts = contexts; setLayout( new BorderLayout( 0, 0 ) ); textFieldFilter = new JTextField(); @@ -223,9 +232,11 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a flowLayout.setAlignment( FlowLayout.TRAILING ); final JButton btnRestore = new JButton( "Restore" ); + btnRestore.setToolTipText( "Re-read the key bindings from the config." ); panelButtons.add( btnRestore ); final JButton btnApply = new JButton( "Apply" ); + btnApply.setToolTipText( "Write these key bindings in the config." ); panelButtons.add( btnApply ); final JScrollPane scrollPane = new JScrollPane(); @@ -233,11 +244,11 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a scrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER ); add( scrollPane, BorderLayout.CENTER ); - tableModel = new MyTableModel( actions, config.actionToInputsMap ); - tableBindings = new JTable( tableModel ); + tableBindings = new JTable(); tableBindings.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); tableBindings.setFillsViewportHeight( true ); tableBindings.setAutoResizeMode( JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS ); + tableBindings.setRowHeight( 30 ); tableBindings.getSelectionModel().addListSelectionListener( new ListSelectionListener() { @Override @@ -262,13 +273,44 @@ public void valueChanged( final ListSelectionEvent e ) btnUnbindAction.addActionListener( ( e ) -> unbindCommand( tableBindings.getSelectedRow() ) ); btnDeleteAction.addActionListener( ( e ) -> unbindAllCommand( tableBindings.getSelectedRow() ) ); btnExportCsv.addActionListener( ( e ) -> exportToCsv() ); + btnRestore.addActionListener( (e) -> configToModel() ); + btnApply.addActionListener( (e) -> modelToConfig() ); + + configToModel(); + scrollPane.setViewportView( tableBindings ); + } + + private void modelToConfig() + { + final HashMap< String, Set< Input > > actionToInputsMap = config.actionToInputsMap; + actionToInputsMap.clear(); + for ( int i = 0; i < tableModel.actions.size(); i++ ) + { + final InputTrigger inputTrigger = tableModel.bindings.get( i ); + if (inputTrigger == InputTrigger.NOT_MAPPED) + continue; + + final String action = tableModel.actions.get( i ); + final Set< String > cs = new HashSet<>(tableModel.contexts.get( i ) ); + final Input input = new Input( inputTrigger, action, cs ); + Set< Input > inputs = actionToInputsMap.get( action ); + if (null == inputs) + { + inputs = new HashSet<>(); + actionToInputsMap.put( action, inputs ); + } + inputs.add( input ); + } + } + private void configToModel() + { + tableModel = new MyTableModel( actions, config.actionToInputsMap ); + tableBindings.setModel( tableModel ); // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); tableBindings.getColumnModel().getColumn( 2 ).setCellRenderer( new MyContextsRenderer( contexts ) ); tableBindings.getSelectionModel().setSelectionInterval( 0, 0 ); - tableBindings.setRowHeight( 30 ); - scrollPane.setViewportView( tableBindings ); } private final static String CSV_SEPARATOR = ","; From 7e7ee6ba528a585140e14d637837f206d76b2f31 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 29 Oct 2017 13:20:06 +0100 Subject: [PATCH 044/184] Detect and report keybindings conflicts. --- .../ui/behaviour/io/VisualEditorPanel.java | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 87e32e2..c865db1 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -1,9 +1,11 @@ package org.scijava.ui.behaviour.io; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; import java.awt.EventQueue; import java.awt.FlowLayout; +import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; @@ -93,6 +95,8 @@ public boolean accept( final File f ) private final Set< String > contexts; + private final JLabel lblConflict; + /** * Create the panel. */ @@ -202,9 +206,13 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a gbc_lblConflicts.gridy = 3; panelCommandEditor.add( lblConflicts, gbc_lblConflicts ); - final JLabel lblConflict = new JLabel( "" ); + lblConflict = new JLabel( "" ); + lblConflict.setToolTipText( "Conflicts with other commands." ); + lblConflict.setForeground( Color.PINK.darker() ); + lblConflict.setFont( getFont().deriveFont( Font.BOLD ) ); final GridBagConstraints gbc_lblConflict = new GridBagConstraints(); gbc_lblConflict.insets = new Insets( 5, 5, 5, 5 ); + gbc_lblConflict.anchor = GridBagConstraints.WEST; gbc_lblConflict.gridx = 1; gbc_lblConflict.gridy = 3; panelCommandEditor.add( lblConflict, gbc_lblConflict ); @@ -258,7 +266,6 @@ public void valueChanged( final ListSelectionEvent e ) return; removeDuplicates(); updateEditors(); - } } ); @@ -280,6 +287,32 @@ public void valueChanged( final ListSelectionEvent e ) scrollPane.setViewportView( tableBindings ); } + private void lookForConflicts(final int row) + { + lblConflict.setText( "" ); + final InputTrigger inputTrigger = tableModel.bindings.get( row ); + if (inputTrigger == InputTrigger.NOT_MAPPED) + return; + + final ArrayList< String > conflicts = new ArrayList<>(); + for ( int i = 0; i < tableModel.actions.size(); i++ ) + { + if (i == row) + continue; + + if (tableModel.bindings.get( i ).equals( inputTrigger )) + conflicts.add( tableModel.actions.get( i ) ); + } + + if (!conflicts.isEmpty()) + { + final StringBuilder str = new StringBuilder( conflicts.get( 0 ) ); + for ( int i = 1; i < conflicts.size(); i++ ) + str.append( ", " + conflicts.get( i ) ); + lblConflict.setText( str.toString() ); + } + } + private void modelToConfig() { final HashMap< String, Set< Input > > actionToInputsMap = config.actionToInputsMap; @@ -409,6 +442,7 @@ private void updateEditors() labelActionName.setText( action ); keybindingEditor.setInputTrigger( trigger ); contextsEditor.setTags( contexts ); + lookForConflicts( row ); } private void unbindCommand( final int row ) @@ -493,6 +527,7 @@ private void keybindingsChanged( final int row, final InputTrigger inputTrigger tableModel.bindings.set( row, inputTrigger ); tableModel.fireTableCellUpdated( row, 1 ); + lookForConflicts( row ); } private void contextsChanged( final int row, final List< String > selectedContexts ) From c69bd0c21c701e631e97a0c5784950ed0072e244 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 29 Oct 2017 13:49:24 +0100 Subject: [PATCH 045/184] Implements the description field. Descriptions are passed at construction using a map of action names to description. Put null if you do not want any description. The description is then displayed in a scrollable JTextArea. --- .../ui/behaviour/io/VisualEditorPanel.java | 99 +++++++++++-------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index c865db1..3c059f5 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -34,6 +34,7 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; +import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.ScrollPaneConstants; @@ -91,23 +92,25 @@ public boolean accept( final File f ) private final InputTriggerConfig config; - private final Set< String > actions; + private final Map< String, String > actionDescriptions; private final Set< String > contexts; private final JLabel lblConflict; + private JTextArea textAreaDescription; + /** * Create the panel. */ - public VisualEditorPanel( final InputTriggerConfig config, final Set< String > actions, final Set< String > contexts ) + public VisualEditorPanel( final InputTriggerConfig config, final Map< String, String > actionDescriptions, final Set< String > contexts ) { /* * GUI */ this.config = config; - this.actions = actions; + this.actionDescriptions = actionDescriptions; this.contexts = contexts; setLayout( new BorderLayout( 0, 0 ) ); @@ -145,9 +148,10 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JPanel panelCommandEditor = new JPanel(); panelEditor.add( panelCommandEditor, BorderLayout.CENTER ); final GridBagLayout gbl_panelCommandEditor = new GridBagLayout(); + gbl_panelCommandEditor.rowHeights = new int[] { 0, 0, 0, 0, 60 }; gbl_panelCommandEditor.columnWidths = new int[] { 30, 100 }; gbl_panelCommandEditor.columnWeights = new double[] { 0.0, 1.0 }; - gbl_panelCommandEditor.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 1.0 }; + gbl_panelCommandEditor.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0 }; panelCommandEditor.setLayout( gbl_panelCommandEditor ); final JLabel lblName = new JLabel( "Name:" ); @@ -161,7 +165,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a this.labelActionName = new JLabel(); final GridBagConstraints gbc_labelActionName = new GridBagConstraints(); gbc_labelActionName.anchor = GridBagConstraints.WEST; - gbc_labelActionName.insets = new Insets( 5, 5, 5, 5 ); + gbc_labelActionName.insets = new Insets( 5, 5, 5, 0 ); gbc_labelActionName.gridx = 1; gbc_labelActionName.gridy = 0; panelCommandEditor.add( labelActionName, gbc_labelActionName ); @@ -211,7 +215,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a lblConflict.setForeground( Color.PINK.darker() ); lblConflict.setFont( getFont().deriveFont( Font.BOLD ) ); final GridBagConstraints gbc_lblConflict = new GridBagConstraints(); - gbc_lblConflict.insets = new Insets( 5, 5, 5, 5 ); + gbc_lblConflict.insets = new Insets( 5, 5, 5, 0 ); gbc_lblConflict.anchor = GridBagConstraints.WEST; gbc_lblConflict.gridx = 1; gbc_lblConflict.gridy = 3; @@ -219,20 +223,30 @@ public VisualEditorPanel( final InputTriggerConfig config, final Set< String > a final JLabel lblDescription = new JLabel( "Description:" ); final GridBagConstraints gbc_lblDescription = new GridBagConstraints(); - gbc_lblDescription.fill = GridBagConstraints.VERTICAL; gbc_lblDescription.insets = new Insets( 5, 5, 5, 5 ); - gbc_lblDescription.anchor = GridBagConstraints.WEST; + gbc_lblDescription.anchor = GridBagConstraints.NORTHWEST; gbc_lblDescription.gridx = 0; gbc_lblDescription.gridy = 4; panelCommandEditor.add( lblDescription, gbc_lblDescription ); - final JLabel labelActionDescription = new JLabel(); - final GridBagConstraints gbc_labelActionDescription = new GridBagConstraints(); - gbc_labelActionDescription.fill = GridBagConstraints.VERTICAL; - gbc_labelActionDescription.insets = new Insets( 5, 5, 5, 5 ); - gbc_labelActionDescription.gridx = 1; - gbc_labelActionDescription.gridy = 4; - panelCommandEditor.add( labelActionDescription, gbc_labelActionDescription ); + final JScrollPane scrollPaneDescription = new JScrollPane(); + scrollPaneDescription.setOpaque( false ); + scrollPaneDescription.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER ); + final GridBagConstraints gbc_scrollPaneDescription = new GridBagConstraints(); + gbc_scrollPaneDescription.insets = new Insets( 5, 5, 5, 5 ); + gbc_scrollPaneDescription.fill = GridBagConstraints.BOTH; + gbc_scrollPaneDescription.gridx = 1; + gbc_scrollPaneDescription.gridy = 4; + panelCommandEditor.add( scrollPaneDescription, gbc_scrollPaneDescription ); + + textAreaDescription = new JTextArea(); + textAreaDescription.setRows(3); + textAreaDescription.setFont( getFont().deriveFont( getFont().getSize2D() - 1f ) ); + textAreaDescription.setOpaque( false ); + textAreaDescription.setWrapStyleWord( true ); + textAreaDescription.setEditable( false ); + textAreaDescription.setLineWrap( true ); + scrollPaneDescription.setViewportView( textAreaDescription ); final JPanel panelButtons = new JPanel(); panelEditor.add( panelButtons, BorderLayout.SOUTH ); @@ -280,31 +294,31 @@ public void valueChanged( final ListSelectionEvent e ) btnUnbindAction.addActionListener( ( e ) -> unbindCommand( tableBindings.getSelectedRow() ) ); btnDeleteAction.addActionListener( ( e ) -> unbindAllCommand( tableBindings.getSelectedRow() ) ); btnExportCsv.addActionListener( ( e ) -> exportToCsv() ); - btnRestore.addActionListener( (e) -> configToModel() ); - btnApply.addActionListener( (e) -> modelToConfig() ); + btnRestore.addActionListener( ( e ) -> configToModel() ); + btnApply.addActionListener( ( e ) -> modelToConfig() ); configToModel(); scrollPane.setViewportView( tableBindings ); } - private void lookForConflicts(final int row) + private void lookForConflicts( final int row ) { lblConflict.setText( "" ); final InputTrigger inputTrigger = tableModel.bindings.get( row ); - if (inputTrigger == InputTrigger.NOT_MAPPED) + if ( inputTrigger == InputTrigger.NOT_MAPPED ) return; final ArrayList< String > conflicts = new ArrayList<>(); for ( int i = 0; i < tableModel.actions.size(); i++ ) { - if (i == row) + if ( i == row ) continue; - if (tableModel.bindings.get( i ).equals( inputTrigger )) + if ( tableModel.bindings.get( i ).equals( inputTrigger ) ) conflicts.add( tableModel.actions.get( i ) ); } - if (!conflicts.isEmpty()) + if ( !conflicts.isEmpty() ) { final StringBuilder str = new StringBuilder( conflicts.get( 0 ) ); for ( int i = 1; i < conflicts.size(); i++ ) @@ -320,14 +334,14 @@ private void modelToConfig() for ( int i = 0; i < tableModel.actions.size(); i++ ) { final InputTrigger inputTrigger = tableModel.bindings.get( i ); - if (inputTrigger == InputTrigger.NOT_MAPPED) + if ( inputTrigger == InputTrigger.NOT_MAPPED ) continue; final String action = tableModel.actions.get( i ); - final Set< String > cs = new HashSet<>(tableModel.contexts.get( i ) ); + final Set< String > cs = new HashSet<>( tableModel.contexts.get( i ) ); final Input input = new Input( inputTrigger, action, cs ); Set< Input > inputs = actionToInputsMap.get( action ); - if (null == inputs) + if ( null == inputs ) { inputs = new HashSet<>(); actionToInputsMap.put( action, inputs ); @@ -338,7 +352,7 @@ private void modelToConfig() private void configToModel() { - tableModel = new MyTableModel( actions, config.actionToInputsMap ); + tableModel = new MyTableModel( actionDescriptions.keySet(), config.actionToInputsMap ); tableBindings.setModel( tableModel ); // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); @@ -367,13 +381,12 @@ private void exportToCsv() return; } - final StringBuilder sb = new StringBuilder(); - sb.append( MyTableModel.TABLE_HEADERS[0] ); + sb.append( MyTableModel.TABLE_HEADERS[ 0 ] ); sb.append( CSV_SEPARATOR + '\t' ); - sb.append( MyTableModel.TABLE_HEADERS[1] ); + sb.append( MyTableModel.TABLE_HEADERS[ 1 ] ); sb.append( CSV_SEPARATOR + '\t' ); - sb.append( MyTableModel.TABLE_HEADERS[2] ); + sb.append( MyTableModel.TABLE_HEADERS[ 2 ] ); sb.append( '\n' ); for ( int i = 0; i < tableModel.actions.size(); i++ ) @@ -383,7 +396,7 @@ private void exportToCsv() sb.append( tableModel.bindings.get( i ).toString() ); sb.append( CSV_SEPARATOR + '\t' ); final List< String > contexts = tableModel.contexts.get( i ); - if (!contexts.isEmpty()) + if ( !contexts.isEmpty() ) { sb.append( contexts.get( 0 ) ); for ( int j = 1; j < contexts.size(); j++ ) @@ -438,10 +451,14 @@ private void updateEditors() final String action = tableModel.actions.get( row ); final InputTrigger trigger = tableModel.bindings.get( row ); final List< String > contexts = new ArrayList<>( tableModel.contexts.get( row ) ); + final String description = actionDescriptions.get( action ); labelActionName.setText( action ); keybindingEditor.setInputTrigger( trigger ); contextsEditor.setTags( contexts ); + textAreaDescription.setText( ( null == description ) ? "" : description ); + textAreaDescription.setCaretPosition( 0 ); + lookForConflicts( row ); } @@ -734,14 +751,18 @@ private static InputTriggerConfig getDemoConfig() return config; } - private static Set< String > getDemoActions() + private static Map< String, String > getDemoActions() { - final Set< String > actions = new HashSet<>(); - actions.add( "drag1" ); - actions.add( "scroll1" ); - actions.add( "destroy the world" ); - actions.add( "ride the dragon" ); - actions.add( "make some coffee" ); + final Map< String, String > actions = new HashMap<>(); + actions.put( "drag1", "Move an item around the editor." ); + actions.put( "scroll1", null ); + actions.put( "destroy the world", "Make a disgusting coffee for breakfast. \n" + + "For this one, you are by yourself. Good luck and know that we are with you. This is a long line. Hopefully long engouh.\n" + + "Hey, what about we add:\n" + + "tabulation1\ttabulation2\n" + + "lalallala\ttrollololo." ); + actions.put( "ride the dragon", "Go to work by bike." ); + actions.put( "make some coffee", null ); return actions; } @@ -774,7 +795,7 @@ public void run() { final JFrame frame = new JFrame( "Behaviour Key bindings editor" ); final VisualEditorPanel editorPanel = new VisualEditorPanel( getDemoConfig(), getDemoActions(), getDemoContexts() ); - SwingUtilities.updateComponentTreeUI(VisualEditorPanel.fileChooser); + SwingUtilities.updateComponentTreeUI( VisualEditorPanel.fileChooser ); frame.getContentPane().add( editorPanel ); frame.pack(); frame.setVisible( true ); From 24e296ceae938ae6061e4cca2322b193fed6f5a8 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 29 Oct 2017 23:43:42 +0100 Subject: [PATCH 046/184] Use a row filter (with regex) on action names. Using JTable standard API. Side benefit is that the table can be sorted as wel. --- .../ui/behaviour/io/VisualEditorPanel.java | 171 +++++++++++++----- 1 file changed, 130 insertions(+), 41 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 3c059f5..2f839e3 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -37,15 +37,19 @@ import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.ListSelectionModel; +import javax.swing.RowFilter; import javax.swing.ScrollPaneConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.filechooser.FileFilter; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableRowSorter; import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.io.InputTriggerConfig.Input; @@ -114,9 +118,45 @@ public VisualEditorPanel( final InputTriggerConfig config, final Map< String, St this.contexts = contexts; setLayout( new BorderLayout( 0, 0 ) ); + final JPanel panelFilter = new JPanel(); + add( panelFilter, BorderLayout.NORTH ); + panelFilter.setLayout( new BoxLayout( panelFilter, BoxLayout.X_AXIS ) ); + + final Component horizontalStrut = Box.createHorizontalStrut( 5 ); + panelFilter.add( horizontalStrut ); + + final JLabel lblFilter = new JLabel( "Filter:" ); + lblFilter.setToolTipText( "Fiter on action names. Accept regular expressions." ); + lblFilter.setAlignmentX( Component.CENTER_ALIGNMENT ); + panelFilter.add( lblFilter ); + + final Component horizontalStrut_1 = Box.createHorizontalStrut( 5 ); + panelFilter.add( horizontalStrut_1 ); + textFieldFilter = new JTextField(); - add( textFieldFilter, BorderLayout.NORTH ); + panelFilter.add( textFieldFilter ); textFieldFilter.setColumns( 10 ); + textFieldFilter.getDocument().addDocumentListener( new DocumentListener() + { + + @Override + public void removeUpdate( final DocumentEvent e ) + { + filterRows(); + } + + @Override + public void insertUpdate( final DocumentEvent e ) + { + filterRows(); + } + + @Override + public void changedUpdate( final DocumentEvent e ) + { + filterRows(); + } + } ); final JPanel panelEditor = new JPanel(); add( panelEditor, BorderLayout.SOUTH ); @@ -240,7 +280,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Map< String, St panelCommandEditor.add( scrollPaneDescription, gbc_scrollPaneDescription ); textAreaDescription = new JTextArea(); - textAreaDescription.setRows(3); + textAreaDescription.setRows( 3 ); textAreaDescription.setFont( getFont().deriveFont( getFont().getSize2D() - 1f ) ); textAreaDescription.setOpaque( false ); textAreaDescription.setWrapStyleWord( true ); @@ -284,15 +324,15 @@ public void valueChanged( final ListSelectionEvent e ) } ); // Listen to changes in the - keybindingEditor.addInputTriggerChangeListener( () -> keybindingsChanged( tableBindings.getSelectedRow(), keybindingEditor.getInputTrigger() ) ); + keybindingEditor.addInputTriggerChangeListener( () -> keybindingsChanged( keybindingEditor.getInputTrigger() ) ); // Listen to changes in context editor and forward to table model. - contextsEditor.addTagSelectionChangeListener( () -> contextsChanged( tableBindings.getSelectedRow(), contextsEditor.getSelectedTags() ) ); + contextsEditor.addTagSelectionChangeListener( () -> contextsChanged( contextsEditor.getSelectedTags() ) ); // Button presses. - btnCopyCommand.addActionListener( ( e ) -> copyCommand( tableBindings.getSelectedRow() ) ); - btnUnbindAction.addActionListener( ( e ) -> unbindCommand( tableBindings.getSelectedRow() ) ); - btnDeleteAction.addActionListener( ( e ) -> unbindAllCommand( tableBindings.getSelectedRow() ) ); + btnCopyCommand.addActionListener( ( e ) -> copyCommand() ); + btnUnbindAction.addActionListener( ( e ) -> unbindCommand() ); + btnDeleteAction.addActionListener( ( e ) -> unbindAllCommand() ); btnExportCsv.addActionListener( ( e ) -> exportToCsv() ); btnRestore.addActionListener( ( e ) -> configToModel() ); btnApply.addActionListener( ( e ) -> modelToConfig() ); @@ -301,17 +341,22 @@ public void valueChanged( final ListSelectionEvent e ) scrollPane.setViewportView( tableBindings ); } - private void lookForConflicts( final int row ) + private void lookForConflicts() { + final int viewRow = tableBindings.getSelectedRow(); + if ( viewRow < 0 ) + return; + final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); + lblConflict.setText( "" ); - final InputTrigger inputTrigger = tableModel.bindings.get( row ); + final InputTrigger inputTrigger = tableModel.bindings.get( modelRow ); if ( inputTrigger == InputTrigger.NOT_MAPPED ) return; final ArrayList< String > conflicts = new ArrayList<>(); for ( int i = 0; i < tableModel.actions.size(); i++ ) { - if ( i == row ) + if ( i == modelRow ) continue; if ( tableModel.bindings.get( i ).equals( inputTrigger ) ) @@ -360,6 +405,26 @@ private void configToModel() tableBindings.getSelectionModel().setSelectionInterval( 0, 0 ); } + private void filterRows() + { + final TableRowSorter< MyTableModel > tableRowSorter = new TableRowSorter<>( tableModel ); + tableRowSorter.setComparator( 1, new InputTriggerComparator() ); + tableBindings.setRowSorter( tableRowSorter ); + RowFilter< MyTableModel, Integer > rf = null; + try + { + final int[] indices = new int[ tableModel.actions.size() ]; + for ( int i = 0; i < indices.length; i++ ) + indices[ i ] = i; + rf = RowFilter.regexFilter( textFieldFilter.getText(), 0 ); + } + catch ( final java.util.regex.PatternSyntaxException pse ) + { + return; + } + tableRowSorter.setRowFilter( rf ); + } + private final static String CSV_SEPARATOR = ","; private void exportToCsv() @@ -419,12 +484,14 @@ private void exportToCsv() } - private void unbindAllCommand( final int row ) + private void unbindAllCommand() { - if ( row < 0 ) + final int viewRow = tableBindings.getSelectedRow(); + if ( viewRow < 0 ) return; + final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - final String action = tableModel.actions.get( row ); + final String action = tableModel.actions.get( modelRow ); for ( int i = 0; i < tableModel.actions.size(); i++ ) { if ( tableModel.actions.get( i ).equals( action ) ) @@ -434,13 +501,13 @@ private void unbindAllCommand( final int row ) } } removeDuplicates(); - tableModel.fireTableRowsUpdated( row, row ); + tableModel.fireTableRowsUpdated( modelRow, modelRow ); } private void updateEditors() { - final int row = tableBindings.getSelectedRow(); - if ( row < 0 ) + final int viewRow = tableBindings.getSelectedRow(); + if ( viewRow < 0 ) { labelActionName.setText( "" ); keybindingEditor.setInputTrigger( InputTrigger.NOT_MAPPED ); @@ -448,9 +515,10 @@ private void updateEditors() return; } - final String action = tableModel.actions.get( row ); - final InputTrigger trigger = tableModel.bindings.get( row ); - final List< String > contexts = new ArrayList<>( tableModel.contexts.get( row ) ); + final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); + final String action = tableModel.actions.get( modelRow ); + final InputTrigger trigger = tableModel.bindings.get( modelRow ); + final List< String > contexts = new ArrayList<>( tableModel.contexts.get( modelRow ) ); final String description = actionDescriptions.get( action ); labelActionName.setText( action ); @@ -459,21 +527,23 @@ private void updateEditors() textAreaDescription.setText( ( null == description ) ? "" : description ); textAreaDescription.setCaretPosition( 0 ); - lookForConflicts( row ); + lookForConflicts(); } - private void unbindCommand( final int row ) + private void unbindCommand() { - if ( row < 0 ) + final int viewRow = tableBindings.getSelectedRow(); + if ( viewRow < 0 ) return; + final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - final InputTrigger inputTrigger = tableModel.bindings.get( row ); + final InputTrigger inputTrigger = tableModel.bindings.get( modelRow ); if ( inputTrigger == InputTrigger.NOT_MAPPED ) return; // Update model & - keybindingsChanged( row, InputTrigger.NOT_MAPPED ); - contextsChanged( row, Collections.emptyList() ); + keybindingsChanged( InputTrigger.NOT_MAPPED ); + contextsChanged( Collections.emptyList() ); // Find whether we have two lines with the same action, unbound. removeDuplicates(); @@ -516,12 +586,14 @@ private void removeDuplicates() updateEditors(); } - private void copyCommand( final int row ) + private void copyCommand() { - if ( row < 0 ) + final int viewRow = tableBindings.getSelectedRow(); + if ( viewRow < 0 ) return; + final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - final String action = tableModel.actions.get( row ); + final String action = tableModel.actions.get( modelRow ); // Check whether there is already a line in the table without a binding. for ( int i = 0; i < tableModel.actions.size(); i++ ) { @@ -531,29 +603,33 @@ private void copyCommand( final int row ) } // Create one then. - tableModel.actions.add( row + 1, action ); - tableModel.bindings.add( row + 1, InputTrigger.NOT_MAPPED ); - tableModel.contexts.add( row + 1, Collections.emptyList() ); - tableModel.fireTableRowsInserted( row, row ); + tableModel.actions.add( modelRow + 1, action ); + tableModel.bindings.add( modelRow + 1, InputTrigger.NOT_MAPPED ); + tableModel.contexts.add( modelRow + 1, Collections.emptyList() ); + tableModel.fireTableRowsInserted( modelRow, modelRow ); } - private void keybindingsChanged( final int row, final InputTrigger inputTrigger ) + private void keybindingsChanged( final InputTrigger inputTrigger ) { - if ( row < 0 ) + final int viewRow = tableBindings.getSelectedRow(); + if ( viewRow < 0 ) return; + final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - tableModel.bindings.set( row, inputTrigger ); - tableModel.fireTableCellUpdated( row, 1 ); - lookForConflicts( row ); + tableModel.bindings.set( modelRow, inputTrigger ); + tableModel.fireTableCellUpdated( modelRow, 1 ); + lookForConflicts(); } - private void contextsChanged( final int row, final List< String > selectedContexts ) + private void contextsChanged( final List< String > selectedContexts ) { - if ( row < 0 ) + final int viewRow = tableBindings.getSelectedRow(); + if ( viewRow < 0 ) return; + final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - tableModel.contexts.set( row, new ArrayList<>( selectedContexts ) ); - tableModel.fireTableCellUpdated( row, 2 ); + tableModel.contexts.set( modelRow, new ArrayList<>( selectedContexts ) ); + tableModel.fireTableCellUpdated( modelRow, 2 ); } /* @@ -715,7 +791,20 @@ public int compare( final Input o1, final Input o2 ) return -1; return o1.trigger.toString().compareTo( o2.trigger.toString() ); } + } + private static final class InputTriggerComparator implements Comparator< InputTrigger > + { + + @Override + public int compare( final InputTrigger o1, final InputTrigger o2 ) + { + if ( o1 == InputTrigger.NOT_MAPPED ) + return 1; + if ( o2 == InputTrigger.NOT_MAPPED ) + return -1; + return o1.toString().compareTo( o2.toString() ); + } } /* From 9bfd7daa095a487293a5a95c2010f0eec93fdf4d Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 29 Oct 2017 23:51:55 +0100 Subject: [PATCH 047/184] Formatting, docs, variable names and user texts. Let's use 'command' instead of 'action' or 'behaviour' for the user. --- .../ui/behaviour/io/VisualEditorPanel.java | 102 ++++++++++-------- 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 2f839e3..4c82ad0 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -90,7 +90,7 @@ public boolean accept( final File f ) private final TagPanelEditor contextsEditor; - private final JLabel labelActionName; + private final JLabel labelCommandName; private final JTable tableBindings; @@ -105,16 +105,26 @@ public boolean accept( final File f ) private JTextArea textAreaDescription; /** - * Create the panel. + * Creates a visual editor for an {@link InputTriggerConfig}. The config + * object is directly modified when the user clicks the 'Apply' button. + * + * @param config + * the {@link InputTriggerConfig} object to modify. + * @param commandDescriptions + * The commands available. They are specified as a map from + * command name to their description. Use null as + * value to not specify a description. + * @param contexts + * The contexts available. */ - public VisualEditorPanel( final InputTriggerConfig config, final Map< String, String > actionDescriptions, final Set< String > contexts ) + public VisualEditorPanel( final InputTriggerConfig config, final Map< String, String > commandDescriptions, final Set< String > contexts ) { /* * GUI */ this.config = config; - this.actionDescriptions = actionDescriptions; + this.actionDescriptions = commandDescriptions; this.contexts = contexts; setLayout( new BorderLayout( 0, 0 ) ); @@ -126,7 +136,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Map< String, St panelFilter.add( horizontalStrut ); final JLabel lblFilter = new JLabel( "Filter:" ); - lblFilter.setToolTipText( "Fiter on action names. Accept regular expressions." ); + lblFilter.setToolTipText( "Fiter on command names. Accept regular expressions." ); lblFilter.setAlignmentX( Component.CENTER_ALIGNMENT ); panelFilter.add( lblFilter ); @@ -167,22 +177,22 @@ public void changedUpdate( final DocumentEvent e ) panelCommandButtons.setLayout( new BoxLayout( panelCommandButtons, BoxLayout.X_AXIS ) ); final JButton btnCopyCommand = new JButton( "Copy" ); - btnCopyCommand.setToolTipText( "Duplicate action binding \nto a new, blank binding." ); + btnCopyCommand.setToolTipText( "Duplicate command binding to a new, blank binding." ); panelCommandButtons.add( btnCopyCommand ); final JButton btnUnbindAction = new JButton( "Unbind" ); - btnUnbindAction.setToolTipText( "Remove current binding\nfor current action." ); + btnUnbindAction.setToolTipText( "Remove current binding for selected command." ); panelCommandButtons.add( btnUnbindAction ); final JButton btnDeleteAction = new JButton( "Unbind all" ); - btnDeleteAction.setToolTipText( "Remove all bindings\nto current action." ); + btnDeleteAction.setToolTipText( "Remove all bindings to selected command." ); panelCommandButtons.add( btnDeleteAction ); final Component horizontalGlue = Box.createHorizontalGlue(); panelCommandButtons.add( horizontalGlue ); final JButton btnExportCsv = new JButton( "Export CSV" ); - btnExportCsv.setToolTipText( "Export all action bindings \nto a CSV file." ); + btnExportCsv.setToolTipText( "Export all command bindings to a CSV file." ); panelCommandButtons.add( btnExportCsv ); final JPanel panelCommandEditor = new JPanel(); @@ -202,13 +212,13 @@ public void changedUpdate( final DocumentEvent e ) gbc_lblName.gridy = 0; panelCommandEditor.add( lblName, gbc_lblName ); - this.labelActionName = new JLabel(); + this.labelCommandName = new JLabel(); final GridBagConstraints gbc_labelActionName = new GridBagConstraints(); gbc_labelActionName.anchor = GridBagConstraints.WEST; gbc_labelActionName.insets = new Insets( 5, 5, 5, 0 ); gbc_labelActionName.gridx = 1; gbc_labelActionName.gridy = 0; - panelCommandEditor.add( labelActionName, gbc_labelActionName ); + panelCommandEditor.add( labelCommandName, gbc_labelActionName ); final JLabel lblBinding = new JLabel( "Binding:" ); final GridBagConstraints gbc_lblBinding = new GridBagConstraints(); @@ -354,13 +364,13 @@ private void lookForConflicts() return; final ArrayList< String > conflicts = new ArrayList<>(); - for ( int i = 0; i < tableModel.actions.size(); i++ ) + for ( int i = 0; i < tableModel.commands.size(); i++ ) { if ( i == modelRow ) continue; if ( tableModel.bindings.get( i ).equals( inputTrigger ) ) - conflicts.add( tableModel.actions.get( i ) ); + conflicts.add( tableModel.commands.get( i ) ); } if ( !conflicts.isEmpty() ) @@ -376,13 +386,13 @@ private void modelToConfig() { final HashMap< String, Set< Input > > actionToInputsMap = config.actionToInputsMap; actionToInputsMap.clear(); - for ( int i = 0; i < tableModel.actions.size(); i++ ) + for ( int i = 0; i < tableModel.commands.size(); i++ ) { final InputTrigger inputTrigger = tableModel.bindings.get( i ); if ( inputTrigger == InputTrigger.NOT_MAPPED ) continue; - final String action = tableModel.actions.get( i ); + final String action = tableModel.commands.get( i ); final Set< String > cs = new HashSet<>( tableModel.contexts.get( i ) ); final Input input = new Input( inputTrigger, action, cs ); Set< Input > inputs = actionToInputsMap.get( action ); @@ -413,7 +423,7 @@ private void filterRows() RowFilter< MyTableModel, Integer > rf = null; try { - final int[] indices = new int[ tableModel.actions.size() ]; + final int[] indices = new int[ tableModel.commands.size() ]; for ( int i = 0; i < indices.length; i++ ) indices[ i ] = i; rf = RowFilter.regexFilter( textFieldFilter.getText(), 0 ); @@ -454,9 +464,9 @@ private void exportToCsv() sb.append( MyTableModel.TABLE_HEADERS[ 2 ] ); sb.append( '\n' ); - for ( int i = 0; i < tableModel.actions.size(); i++ ) + for ( int i = 0; i < tableModel.commands.size(); i++ ) { - sb.append( tableModel.actions.get( i ) ); + sb.append( tableModel.commands.get( i ) ); sb.append( CSV_SEPARATOR + '\t' ); sb.append( tableModel.bindings.get( i ).toString() ); sb.append( CSV_SEPARATOR + '\t' ); @@ -491,10 +501,10 @@ private void unbindAllCommand() return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - final String action = tableModel.actions.get( modelRow ); - for ( int i = 0; i < tableModel.actions.size(); i++ ) + final String action = tableModel.commands.get( modelRow ); + for ( int i = 0; i < tableModel.commands.size(); i++ ) { - if ( tableModel.actions.get( i ).equals( action ) ) + if ( tableModel.commands.get( i ).equals( action ) ) { tableModel.bindings.set( i, InputTrigger.NOT_MAPPED ); tableModel.contexts.set( i, Collections.emptyList() ); @@ -509,19 +519,19 @@ private void updateEditors() final int viewRow = tableBindings.getSelectedRow(); if ( viewRow < 0 ) { - labelActionName.setText( "" ); + labelCommandName.setText( "" ); keybindingEditor.setInputTrigger( InputTrigger.NOT_MAPPED ); contextsEditor.setTags( Collections.emptyList() ); return; } final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - final String action = tableModel.actions.get( modelRow ); + final String action = tableModel.commands.get( modelRow ); final InputTrigger trigger = tableModel.bindings.get( modelRow ); final List< String > contexts = new ArrayList<>( tableModel.contexts.get( modelRow ) ); final String description = actionDescriptions.get( action ); - labelActionName.setText( action ); + labelCommandName.setText( action ); keybindingEditor.setInputTrigger( trigger ); contextsEditor.setTags( contexts ); textAreaDescription.setText( ( null == description ) ? "" : description ); @@ -555,7 +565,7 @@ private void removeDuplicates() final List< Integer > toRemove = new ArrayList<>(); for ( int row = 0; row < tableModel.getRowCount(); row++ ) { - final String action = tableModel.actions.get( row ); + final String action = tableModel.commands.get( row ); final InputTrigger trigger = tableModel.bindings.get( row ); if ( bindings.get( action ) == null ) @@ -577,7 +587,7 @@ private void removeDuplicates() for ( final Integer rowToRemove : toRemove ) { final int row = rowToRemove.intValue(); - tableModel.actions.remove( row ); + tableModel.commands.remove( row ); tableModel.bindings.remove( row ); tableModel.contexts.remove( row ); tableModel.fireTableRowsDeleted( row, row ); @@ -593,17 +603,17 @@ private void copyCommand() return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - final String action = tableModel.actions.get( modelRow ); + final String action = tableModel.commands.get( modelRow ); // Check whether there is already a line in the table without a binding. - for ( int i = 0; i < tableModel.actions.size(); i++ ) + for ( int i = 0; i < tableModel.commands.size(); i++ ) { // Brute force. - if ( tableModel.actions.get( i ).equals( action ) && tableModel.bindings.get( i ) == InputTrigger.NOT_MAPPED ) + if ( tableModel.commands.get( i ).equals( action ) && tableModel.bindings.get( i ) == InputTrigger.NOT_MAPPED ) return; } // Create one then. - tableModel.actions.add( modelRow + 1, action ); + tableModel.commands.add( modelRow + 1, action ); tableModel.bindings.add( modelRow + 1, InputTrigger.NOT_MAPPED ); tableModel.contexts.add( modelRow + 1, Collections.emptyList() ); tableModel.fireTableRowsInserted( modelRow, modelRow ); @@ -699,32 +709,32 @@ private static class MyTableModel extends AbstractTableModel private static final long serialVersionUID = 1L; - private static final String[] TABLE_HEADERS = new String[] { "Action", "Binding", "Contexts" }; + private static final String[] TABLE_HEADERS = new String[] { "Command", "Binding", "Contexts" }; - private final List< String > actions; + private final List< String > commands; private final List< InputTrigger > bindings; private final List< List< String > > contexts; - public MyTableModel( final Set< String > baseActions, final Map< String, Set< Input > > actionToInputsMap ) + public MyTableModel( final Set< String > baseCommands, final Map< String, Set< Input > > actionToInputsMap ) { - this.actions = new ArrayList<>(); + this.commands = new ArrayList<>(); this.bindings = new ArrayList<>(); this.contexts = new ArrayList<>(); - final Set< String > allActions = new HashSet<>(); - allActions.addAll( baseActions ); - allActions.addAll( actionToInputsMap.keySet() ); - final List< String > sortedActions = new ArrayList<>( allActions ); - sortedActions.sort( null ); + final Set< String > allCommands = new HashSet<>(); + allCommands.addAll( baseCommands ); + allCommands.addAll( actionToInputsMap.keySet() ); + final List< String > sortedCommands = new ArrayList<>( allCommands ); + sortedCommands.sort( null ); final InputComparator inputComparator = new InputComparator(); - for ( final String action : sortedActions ) + for ( final String command : sortedCommands ) { - final Set< Input > inputs = actionToInputsMap.get( action ); + final Set< Input > inputs = actionToInputsMap.get( command ); if ( null == inputs ) { - actions.add( action ); + commands.add( command ); bindings.add( InputTrigger.NOT_MAPPED ); contexts.add( Collections.emptyList() ); } @@ -734,7 +744,7 @@ public MyTableModel( final Set< String > baseActions, final Map< String, Set< In sortedInputs.sort( inputComparator ); for ( final Input input : sortedInputs ) { - actions.add( action ); + commands.add( command ); bindings.add( input.trigger ); final List< String > cs = new ArrayList<>( input.contexts ); cs.sort( null ); @@ -747,7 +757,7 @@ public MyTableModel( final Set< String > baseActions, final Map< String, Set< In @Override public int getRowCount() { - return actions.size(); + return commands.size(); } @Override @@ -762,7 +772,7 @@ public Object getValueAt( final int rowIndex, final int columnIndex ) switch ( columnIndex ) { case 0: - return actions.get( rowIndex ); + return commands.get( rowIndex ); case 1: return bindings.get( rowIndex ); case 2: @@ -866,6 +876,8 @@ private static Set< String > getDemoContexts() /** * Launch the application. + * + * @param args * * @throws UnsupportedLookAndFeelException * @throws IllegalAccessException From a556e815baaf05759525c065783a7eec73171b94 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Mon, 30 Oct 2017 00:07:25 +0100 Subject: [PATCH 048/184] Return a last valid InputTrigger if the user quit mid-editing a keybinding. --- .../ui/behaviour/io/VisualEditorPanel.java | 5 ++++- .../io/gui/InputTriggerPanelEditor.java | 20 ++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 4c82ad0..0b0c03d 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -334,7 +334,10 @@ public void valueChanged( final ListSelectionEvent e ) } ); // Listen to changes in the - keybindingEditor.addInputTriggerChangeListener( () -> keybindingsChanged( keybindingEditor.getInputTrigger() ) ); + keybindingEditor.addInputTriggerChangeListener( () -> keybindingsChanged( + keybindingEditor.getInputTrigger() == null + ? keybindingEditor.getLastValidInputTrigger() + : keybindingEditor.getInputTrigger() ) ); // Listen to changes in context editor and forward to table model. contextsEditor.addTagSelectionChangeListener( () -> contextsChanged( contextsEditor.getSelectedTags() ) ); diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index ad41f53..56e9f80 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -49,6 +49,8 @@ public static interface InputTriggerChangeListener private InputTrigger trigger = InputTrigger.NOT_MAPPED; + private InputTrigger lastValidInputTrigger = InputTrigger.NOT_MAPPED; + private String invalidTriggerStr = null; public InputTriggerPanelEditor( final boolean editable ) @@ -109,6 +111,11 @@ public InputTrigger getInputTrigger() return trigger; } + public InputTrigger getLastValidInputTrigger() + { + return lastValidInputTrigger; + } + private void checkAndAppendKey( final String key ) { final String trimmed = key.trim(); @@ -120,7 +127,7 @@ private void checkAndAppendKey( final String key ) final String str = ( null == trigger || trigger == InputTrigger.NOT_MAPPED ) ? trimmed - : trigger.toString() + " " + trimmed; + : trigger.toString() + " " + trimmed; this.trigger = null; this.invalidTriggerStr = str.trim(); @@ -144,13 +151,14 @@ private void checkAndAppendKey( final String key ) // Try to append the key to the trigger. final String str = ( null == trigger ) ? invalidTriggerStr + " " + properCapKey - : ( trigger == InputTrigger.NOT_MAPPED ) + : ( trigger == InputTrigger.NOT_MAPPED ) ? properCapKey - : trigger.toString() + " " + properCapKey; + : trigger.toString() + " " + properCapKey; try { this.trigger = InputTrigger.getFromString( str ); + this.lastValidInputTrigger = trigger; this.invalidTriggerStr = null; } catch ( final IllegalArgumentException iae ) @@ -194,6 +202,7 @@ private void removeLastKeyItem() this.trigger = str.isEmpty() ? InputTrigger.NOT_MAPPED : InputTrigger.getFromString( str ); + this.lastValidInputTrigger = trigger; this.invalidTriggerStr = null; } catch ( final IllegalArgumentException iae ) @@ -240,6 +249,7 @@ private void regenKeyPanels() if ( tokens.length == 0 ) { trigger = InputTrigger.NOT_MAPPED; + lastValidInputTrigger = trigger; invalidTriggerStr = null; } else @@ -339,9 +349,9 @@ public void actionPerformed( final ActionEvent ev ) private class CompletionTask implements Runnable { - private String completion; + private final String completion; - private int position; + private final int position; CompletionTask( final String completion, final int position ) { From 19231f4dee8d582544151d48a96aebbda55b3096 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Mon, 30 Oct 2017 00:09:56 +0100 Subject: [PATCH 049/184] Handle properly a last valid InputTrigger. --- .../org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index 56e9f80..85c3ff5 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -102,6 +102,7 @@ public void keyPressed( final KeyEvent e ) public void setInputTrigger( final InputTrigger trigger ) { this.trigger = trigger; + this.lastValidInputTrigger = trigger; this.invalidTriggerStr = null; regenKeyPanels(); } From 5ac74d5807ff235208fc9dded9b55a138552edab Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Mon, 30 Oct 2017 11:07:25 +0100 Subject: [PATCH 050/184] Don't update potentially removed rows. --- .../java/org/scijava/ui/behaviour/io/VisualEditorPanel.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 0b0c03d..a76eecb 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -107,7 +107,7 @@ public boolean accept( final File f ) /** * Creates a visual editor for an {@link InputTriggerConfig}. The config * object is directly modified when the user clicks the 'Apply' button. - * + * * @param config * the {@link InputTriggerConfig} object to modify. * @param commandDescriptions @@ -514,7 +514,6 @@ private void unbindAllCommand() } } removeDuplicates(); - tableModel.fireTableRowsUpdated( modelRow, modelRow ); } private void updateEditors() @@ -879,7 +878,7 @@ private static Set< String > getDemoContexts() /** * Launch the application. - * + * * @param args * * @throws UnsupportedLookAndFeelException From 3e21072bcc684b17cc75d2f50f50a9e6878f8319 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 1 Nov 2017 15:25:43 +0100 Subject: [PATCH 051/184] include tag remove "X" into RoundedBorder --- .../ui/behaviour/io/gui/TagPanelEditor.java | 60 ++++++++++++------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java index df77b30..c653146 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java @@ -243,9 +243,9 @@ public void actionPerformed( final ActionEvent ev ) private class CompletionTask implements Runnable { - private String completion; + private final String completion; - private int position; + private final int position; CompletionTask( final String completion, final int position ) { @@ -268,43 +268,57 @@ public void run() final class TagPanel extends JPanel { - private static final long serialVersionUID = 1L; public TagPanel( final String tag, final boolean valid ) { + final Color bg = valid ? getBackground() : Color.PINK; final Font font = TagPanelEditor.this.getFont().deriveFont( TagPanelEditor.this.getFont().getSize2D() - 2f ); + + final JPanel content = new JPanel(); + content.setLayout( new BoxLayout( content, BoxLayout.LINE_AXIS ) ); + content.setOpaque( true ); + content.setBackground( bg ); + content.setBorder( new RoundBorder( bg.darker(), TagPanelEditor.this, 1 ) ); + + if ( editable ) + { + final JLabel close = new JLabel( "\u00D7" ); + close.setFont( font ); + close.setOpaque( false ); + close.addMouseListener( new java.awt.event.MouseAdapter() + { + @Override + public void mousePressed( final java.awt.event.MouseEvent evt ) + { + removeTag( tag ); + } + } ); + content.add( close ); + content.add( createHorizontalStrutWithMaxHeight1( 2 ) ); + } + final String str = printables.containsKey( tag ) ? printables.get( tag ) : tag; final JLabel txt = new JLabel( str ); txt.setFont( font ); - txt.setOpaque( true ); - if ( !valid ) - txt.setBackground( Color.PINK ); - txt.setBorder( new RoundBorder( getBackground().darker(), TagPanelEditor.this, 3 ) ); - - final JLabel close = new JLabel( "\u00D7" ); - close.setOpaque( true ); - close.setBackground( getBackground().darker().darker() ); - close.setFont( font ); - close.addMouseListener( new java.awt.event.MouseAdapter() - { - @Override - public void mousePressed( final java.awt.event.MouseEvent evt ) - { - removeTag( tag ); - } - } ); + txt.setOpaque( false ); + content.add( txt ); setLayout( new BoxLayout( this, BoxLayout.LINE_AXIS ) ); - if ( editable ) - add( close ); add( Box.createHorizontalStrut( 1 ) ); - add( txt ); + add( content ); add( Box.createHorizontalStrut( 4 ) ); setOpaque( false ); } } + private static Box.Filler createHorizontalStrutWithMaxHeight1( final int width ) + { + return new Box.Filler( new Dimension( width, 0 ), new Dimension( width, 0 ), + new Dimension( width, 1 ) ); + } + + private void notifyListeners() { for ( final TagSelectionChangeListener listener : listeners ) From f24958e140c3aecd4dfbf8e829f5f3d652f921c9 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 1 Nov 2017 16:11:05 +0100 Subject: [PATCH 052/184] fix typo --- .../java/org/scijava/ui/behaviour/io/VisualEditorPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index a76eecb..8d18d6f 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -136,7 +136,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Map< String, St panelFilter.add( horizontalStrut ); final JLabel lblFilter = new JLabel( "Filter:" ); - lblFilter.setToolTipText( "Fiter on command names. Accept regular expressions." ); + lblFilter.setToolTipText( "Filter on command names. Accept regular expressions." ); lblFilter.setAlignmentX( Component.CENTER_ALIGNMENT ); panelFilter.add( lblFilter ); From b724eb360631d1ef4a7187d804b91453901c5cc2 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 1 Nov 2017 16:12:20 +0100 Subject: [PATCH 053/184] fix incomplete comment --- .../java/org/scijava/ui/behaviour/io/VisualEditorPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 8d18d6f..37c85eb 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -333,7 +333,7 @@ public void valueChanged( final ListSelectionEvent e ) } } ); - // Listen to changes in the + // Listen to changes in the keybinding editor and forward to table model. keybindingEditor.addInputTriggerChangeListener( () -> keybindingsChanged( keybindingEditor.getInputTrigger() == null ? keybindingEditor.getLastValidInputTrigger() From 8908d577508595ce525995d81eb5a34b8df808a3 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 1 Nov 2017 16:14:25 +0100 Subject: [PATCH 054/184] =?UTF-8?q?Use=20the=20=E2=8C=98=20symbol=20for=20?= =?UTF-8?q?"meta"=20on=20Macs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/behaviour/io/gui/InputTriggerPanelEditor.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index 85c3ff5..e4b9d84 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -12,6 +12,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Locale; import java.util.Map; import javax.swing.AbstractAction; @@ -533,10 +534,15 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l TRIGGER_SYMBOLS.put( "ctrl", "\u2303" ); TRIGGER_SYMBOLS.put( "alt", "\u2387" ); TRIGGER_SYMBOLS.put( "shift", "\u21e7" ); - TRIGGER_SYMBOLS.put( "meta", "\u25c6" ); + TRIGGER_SYMBOLS.put( "meta", isMac() ? "\u2318" : "\u25c6" ); TRIGGER_SYMBOLS.put( "win", "\u2756" ); // Vertical bar is special TRIGGER_SYMBOLS.put( "|", " | " ); } + private static boolean isMac() + { + final String OS = System.getProperty( "os.name", "generic" ).toLowerCase( Locale.ENGLISH ); + return ( OS.indexOf( "mac" ) >= 0 ) || ( OS.indexOf( "darwin" ) >= 0 ); + } } From ae606edf3f4019e32875fd2cb495a3fc7ece2f49 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 1 Nov 2017 16:15:18 +0100 Subject: [PATCH 055/184] Accept "cmd" and "command" tags, and translate them into "meta" --- .../ui/behaviour/io/gui/InputTriggerPanelEditor.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index e4b9d84..f18870a 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -150,6 +150,9 @@ private void checkAndAppendKey( final String key ) if ( null != properCapKey ) { + // Some tags are replaced for constructing the trigger, e.g., "cmd" is replaces by "meta" + properCapKey = INPUT_TRIGGER_SYNTAX_TAG_REMAP.getOrDefault( properCapKey, properCapKey ); + // Try to append the key to the trigger. final String str = ( null == trigger ) ? invalidTriggerStr + " " + properCapKey @@ -418,6 +421,8 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l private static final List< String > INPUT_TRIGGER_SYNTAX_TAGS = new ArrayList<>(); private static final List< String > INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS; private static final Map< String, String > TRIGGER_SYMBOLS = new HashMap<>(); + private static final Map INPUT_TRIGGER_SYNTAX_TAG_REMAP = new HashMap<>(); + static { for ( int i = 0; i < 26; i++ ) @@ -481,6 +486,8 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l "altGraph", "shift", "meta", + "command", + "cmd", "win", "double-click", "button1", @@ -494,6 +501,10 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l for ( final String tag : INPUT_TRIGGER_SYNTAX_TAGS ) INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS.add( tag.toLowerCase() ); + INPUT_TRIGGER_SYNTAX_TAG_REMAP.put( "cmd", "meta" ); + INPUT_TRIGGER_SYNTAX_TAG_REMAP.put( "command", "meta" ); + INPUT_TRIGGER_SYNTAX_TAG_REMAP.put( "windows", "win" ); + TRIGGER_SYMBOLS.put( "ENTER", "\u23CE" ); TRIGGER_SYMBOLS.put( "BACK_SPACE", "\u232B" ); TRIGGER_SYMBOLS.put( "DELETE", "\u2326" ); From e1f58f4c5aab97e74bc9df64f45b1d751ff31097 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 2 Nov 2017 18:59:27 +0100 Subject: [PATCH 056/184] Shift/Tab in the bindings table should move focus to next component --- .../java/org/scijava/ui/behaviour/io/VisualEditorPanel.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 37c85eb..8a80564 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -9,6 +9,7 @@ import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; +import java.awt.KeyboardFocusManager; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; @@ -332,6 +333,8 @@ public void valueChanged( final ListSelectionEvent e ) updateEditors(); } } ); + tableBindings.setFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null ); + tableBindings.setFocusTraversalKeys( KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null ); // Listen to changes in the keybinding editor and forward to table model. keybindingEditor.addInputTriggerChangeListener( () -> keybindingsChanged( From f5788489563cdc28cf42634e405bc34b7bcd2301 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 2 Nov 2017 19:01:22 +0100 Subject: [PATCH 057/184] Add method to hide restore/apply buttons, for embedding editor elsewhere --- .../ui/behaviour/io/VisualEditorPanel.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 8a80564..8a5e7fc 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -105,6 +105,10 @@ public boolean accept( final File f ) private JTextArea textAreaDescription; + private final JPanel panelEditor; + + private final JPanel panelButtons; + /** * Creates a visual editor for an {@link InputTriggerConfig}. The config * object is directly modified when the user clicks the 'Apply' button. @@ -169,7 +173,7 @@ public void changedUpdate( final DocumentEvent e ) } } ); - final JPanel panelEditor = new JPanel(); + panelEditor = new JPanel(); add( panelEditor, BorderLayout.SOUTH ); panelEditor.setLayout( new BorderLayout( 0, 0 ) ); @@ -299,7 +303,7 @@ public void changedUpdate( final DocumentEvent e ) textAreaDescription.setLineWrap( true ); scrollPaneDescription.setViewportView( textAreaDescription ); - final JPanel panelButtons = new JPanel(); + panelButtons = new JPanel(); panelEditor.add( panelButtons, BorderLayout.SOUTH ); final FlowLayout flowLayout = ( FlowLayout ) panelButtons.getLayout(); flowLayout.setAlignment( FlowLayout.TRAILING ); @@ -388,7 +392,14 @@ private void lookForConflicts() } } - private void modelToConfig() + public void setButtonPanelVisible( boolean visible ) + { + panelEditor.remove( panelButtons ); + if ( visible ) + panelEditor.add( panelButtons, BorderLayout.SOUTH ); + } + + public void modelToConfig() { final HashMap< String, Set< Input > > actionToInputsMap = config.actionToInputsMap; actionToInputsMap.clear(); @@ -411,7 +422,7 @@ private void modelToConfig() } } - private void configToModel() + public void configToModel() { tableModel = new MyTableModel( actionDescriptions.keySet(), config.actionToInputsMap ); tableBindings.setModel( tableModel ); From 55c3e40d1879af8c3c63876f00ece939a7e6c5b6 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 2 Nov 2017 19:23:58 +0100 Subject: [PATCH 058/184] TAB in PanelEditor commits if there is anything to commit, otherwise moves focus to next component --- .../ui/behaviour/io/gui/InputTriggerPanelEditor.java | 8 ++++++++ .../scijava/ui/behaviour/io/gui/TagPanelEditor.java | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index f18870a..0fdc74f 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -3,6 +3,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.Font; +import java.awt.KeyboardFocusManager; import java.awt.event.ActionEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -77,6 +78,8 @@ public InputTriggerPanelEditor( final boolean editable ) textField.getDocument().addDocumentListener( autoComplete ); textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ), COMMIT_ACTION ); textField.getInputMap().put( KeyStroke.getKeyStroke( ' ' ), COMMIT_ACTION ); + textField.setFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.emptySet() ); + textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_TAB, 0 ), COMMIT_ACTION ); textField.getActionMap().put( COMMIT_ACTION, autoComplete.new CommitAction() ); textField.addKeyListener( new KeyAdapter() { @@ -346,6 +349,11 @@ public class CommitAction extends AbstractAction public void actionPerformed( final ActionEvent ev ) { final String key = textField.getText().trim(); + if ( key.isEmpty() ) + { + KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(); + return; + } checkAndAppendKey( key ); textField.setText( "" ); notifyListeners(); diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java index c653146..afa18e5 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java @@ -3,6 +3,7 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.Font; +import java.awt.KeyboardFocusManager; import java.awt.event.ActionEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -89,6 +90,8 @@ public TagPanelEditor( final Collection< String > tags, final boolean editable, final Autocomplete autoComplete = new Autocomplete(); textField.getDocument().addDocumentListener( autoComplete ); textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ), COMMIT_ACTION ); + textField.setFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, Collections.emptySet() ); + textField.getInputMap().put( KeyStroke.getKeyStroke( KeyEvent.VK_TAB, 0 ), COMMIT_ACTION ); textField.getActionMap().put( COMMIT_ACTION, autoComplete.new CommitAction() ); textField.addKeyListener( new KeyAdapter() { @@ -226,6 +229,13 @@ public class CommitAction extends AbstractAction public void actionPerformed( final ActionEvent ev ) { final String tag = textField.getText(); + + if ( tag.isEmpty() ) + { + KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent(); + return; + } + if ( selectedTags.contains( tag ) ) { // Do not allow more than 1 tag instance. From d4deb10a51c51e015f1df9021e3fccd0dd78f068 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 2 Nov 2017 19:24:21 +0100 Subject: [PATCH 059/184] Make description not focusable --- src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 8a5e7fc..b58db18 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -301,6 +301,7 @@ public void changedUpdate( final DocumentEvent e ) textAreaDescription.setWrapStyleWord( true ); textAreaDescription.setEditable( false ); textAreaDescription.setLineWrap( true ); + textAreaDescription.setFocusable( false ); scrollPaneDescription.setViewportView( textAreaDescription ); panelButtons = new JPanel(); From 9f14b98e0a41247a09371cd1e28359c81529c050 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 2 Nov 2017 19:48:04 +0100 Subject: [PATCH 060/184] Add InputTriggerConfig.clear() --- .../java/org/scijava/ui/behaviour/io/InputTriggerConfig.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 789c111..e2beb66 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -306,6 +306,11 @@ public Set< InputTrigger > getInputs( final String behaviourName, final Set< Str return triggers; } + void clear() + { + actionToInputsMap.clear(); + } + void add( final String trigger, final String behaviourName, final String context ) { add( InputTrigger.getFromString( trigger ), behaviourName, context ); From 5a02233ff3fc6dbc276462505662524991f6fc81 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 2 Nov 2017 19:50:15 +0100 Subject: [PATCH 061/184] Revise modelToConfig * Use InputTriggerConfig.clear()/add() instead of modifying actionToInputsMap directly. * Put explicit InputTrigger.NOT_MAPPED for any unmapped actions (otherwise default keybindings will be picked up) --- .../ui/behaviour/io/VisualEditorPanel.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index b58db18..e066841 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -402,8 +402,7 @@ public void setButtonPanelVisible( boolean visible ) public void modelToConfig() { - final HashMap< String, Set< Input > > actionToInputsMap = config.actionToInputsMap; - actionToInputsMap.clear(); + config.clear(); for ( int i = 0; i < tableModel.commands.size(); i++ ) { final InputTrigger inputTrigger = tableModel.bindings.get( i ); @@ -412,14 +411,16 @@ public void modelToConfig() final String action = tableModel.commands.get( i ); final Set< String > cs = new HashSet<>( tableModel.contexts.get( i ) ); - final Input input = new Input( inputTrigger, action, cs ); - Set< Input > inputs = actionToInputsMap.get( action ); - if ( null == inputs ) - { - inputs = new HashSet<>(); - actionToInputsMap.put( action, inputs ); - } - inputs.add( input ); + config.add( inputTrigger, action, cs ); + } + + // fill in InputTrigger.NOT_MAPPED for any action that doesn't have any input + for ( String context : contexts ) + { + final Set< String > cs = Collections.singleton( context ); + for ( String action : actionDescriptions.keySet() ) + if ( config.getInputs( action, cs ).isEmpty() ) + config.add( InputTrigger.NOT_MAPPED, action, cs ); } } From 57e27f70c6d2885075067877604566cb121bd66d Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 2 Nov 2017 23:55:25 +0100 Subject: [PATCH 062/184] Add methods to extract sets of behaviour names and contexts from InputTriggerConfig --- .../io/InputTriggerDescriptionsBuilder.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java index edcfb6f..f9281c3 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java @@ -32,10 +32,12 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map.Entry; import java.util.Set; +import java.util.stream.Collectors; import javax.swing.InputMap; import org.scijava.ui.behaviour.InputTriggerMap; @@ -98,6 +100,20 @@ public List< InputTriggerDescription > getDescriptions() return descs; } + public Set< String > getContexts() + { + final Set< String > contexts = new LinkedHashSet<>(); + for ( final Entry< String, Set< Input > > entry : config.actionToInputsMap.entrySet() ) + for ( final Input input : entry.getValue() ) + contexts.addAll( input.contexts ); + return contexts; + } + + public Set< String > getBehaviourNames() + { + return config.actionToInputsMap.keySet(); + } + public void addMap( final InputTriggerMap map, final String context ) { config.addMap( map, context ); From 67e4851752fab1d0e14f8d79d33ee99980abfca8 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 2 Nov 2017 18:29:16 +0100 Subject: [PATCH 063/184] Move demo code out of VisualEditorPanel --- .../ui/behaviour/io/VisualEditorPanel.java | 105 +---------------- .../behaviour/io/VisualEditorPanelDemo.java | 109 ++++++++++++++++++ 2 files changed, 111 insertions(+), 103 deletions(-) create mode 100644 src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index e066841..0d80fec 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -3,7 +3,6 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; -import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridBagConstraints; @@ -13,7 +12,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; -import java.io.StringReader; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -24,12 +22,10 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; - import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFileChooser; -import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -40,9 +36,6 @@ import javax.swing.ListSelectionModel; import javax.swing.RowFilter; import javax.swing.ScrollPaneConstants; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; @@ -51,19 +44,18 @@ import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableRowSorter; - import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.io.InputTriggerConfig.Input; import org.scijava.ui.behaviour.io.gui.InputTriggerPanelEditor; import org.scijava.ui.behaviour.io.gui.TagPanelEditor; -import org.scijava.ui.behaviour.io.yaml.YamlConfigIO; public class VisualEditorPanel extends JPanel { private static final long serialVersionUID = 1L; - private static JFileChooser fileChooser = new JFileChooser(); + static JFileChooser fileChooser = new JFileChooser(); + static { fileChooser.setFileFilter( new FileFilter() @@ -834,97 +826,4 @@ public int compare( final InputTrigger o1, final InputTrigger o2 ) return o1.toString().compareTo( o2.toString() ); } } - - /* - * DEMO METHODS. - */ - - private static InputTriggerConfig getDemoConfig() - { - final StringReader reader = new StringReader( "---\n" + - "- !mapping" + "\n" + - " action: fluke" + "\n" + - " contexts: [all]" + "\n" + - " triggers: [F]" + "\n" + - "- !mapping" + "\n" + - " action: drag1" + "\n" + - " contexts: [all]" + "\n" + - " triggers: [button1, win G]" + "\n" + - "- !mapping" + "\n" + - " action: scroll1" + "\n" + - " contexts: [all]" + "\n" + - " triggers: [scroll]" + "\n" + - "- !mapping" + "\n" + - " action: scroll1" + "\n" + - " contexts: [trackscheme, mamut]" + "\n" + - " triggers: [shift D]" + "\n" + - "- !mapping" + "\n" + - " action: destroy the world" + "\n" + - " contexts: [unknown context, mamut]" + "\n" + - " triggers: [control A]" + "\n" + - "" ); - final List< InputTriggerDescription > triggers = YamlConfigIO.read( reader ); - final InputTriggerConfig config = new InputTriggerConfig( triggers ); - return config; - } - - private static Map< String, String > getDemoActions() - { - final Map< String, String > actions = new HashMap<>(); - actions.put( "drag1", "Move an item around the editor." ); - actions.put( "scroll1", null ); - actions.put( "destroy the world", "Make a disgusting coffee for breakfast. \n" - + "For this one, you are by yourself. Good luck and know that we are with you. This is a long line. Hopefully long engouh.\n" - + "Hey, what about we add:\n" - + "tabulation1\ttabulation2\n" - + "lalallala\ttrollololo." ); - actions.put( "ride the dragon", "Go to work by bike." ); - actions.put( "make some coffee", null ); - return actions; - } - - private static Set< String > getDemoContexts() - { - final Set< String > contexts = new HashSet<>(); - contexts.add( "all" ); - contexts.add( "mamut" ); - contexts.add( "trackscheme" ); - return contexts; - } - - /** - * Launch the application. - * - * @param args - * - * @throws UnsupportedLookAndFeelException - * @throws IllegalAccessException - * @throws InstantiationException - * @throws ClassNotFoundException - */ - public static void main( final String[] args ) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException - { - UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() ); - EventQueue.invokeLater( new Runnable() - { - @Override - public void run() - { - try - { - final JFrame frame = new JFrame( "Behaviour Key bindings editor" ); - final VisualEditorPanel editorPanel = new VisualEditorPanel( getDemoConfig(), getDemoActions(), getDemoContexts() ); - SwingUtilities.updateComponentTreeUI( VisualEditorPanel.fileChooser ); - frame.getContentPane().add( editorPanel ); - frame.pack(); - frame.setVisible( true ); - } - catch ( final Exception e ) - { - e.printStackTrace(); - } - } - } ); - } - } diff --git a/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java new file mode 100644 index 0000000..7f78caf --- /dev/null +++ b/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java @@ -0,0 +1,109 @@ +package org.scijava.ui.behaviour.io; + +import java.awt.EventQueue; +import java.io.StringReader; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import org.scijava.ui.behaviour.io.yaml.YamlConfigIO; + +public class VisualEditorPanelDemo +{ + /* + * DEMO METHODS. + */ + + private static InputTriggerConfig getDemoConfig() + { + final StringReader reader = new StringReader( "---\n" + + "- !mapping" + "\n" + + " action: fluke" + "\n" + + " contexts: [all]" + "\n" + + " triggers: [F]" + "\n" + + "- !mapping" + "\n" + + " action: drag1" + "\n" + + " contexts: [all]" + "\n" + + " triggers: [button1, win G]" + "\n" + + "- !mapping" + "\n" + + " action: scroll1" + "\n" + + " contexts: [all]" + "\n" + + " triggers: [scroll]" + "\n" + + "- !mapping" + "\n" + + " action: scroll1" + "\n" + + " contexts: [trackscheme, mamut]" + "\n" + + " triggers: [shift D]" + "\n" + + "- !mapping" + "\n" + + " action: destroy the world" + "\n" + + " contexts: [unknown context, mamut]" + "\n" + + " triggers: [control A]" + "\n" + + "" ); + final List< InputTriggerDescription > triggers = YamlConfigIO.read( reader ); + final InputTriggerConfig config = new InputTriggerConfig( triggers ); + return config; + } + + private static Map< String, String > getDemoActions() + { + final Map< String, String > actions = new HashMap<>(); + actions.put( "drag1", "Move an item around the editor." ); + actions.put( "scroll1", null ); + actions.put( "destroy the world", "Make a disgusting coffee for breakfast. \n" + + "For this one, you are by yourself. Good luck and know that we are with you. This is a long line. Hopefully long engouh.\n" + + "Hey, what about we add:\n" + + "tabulation1\ttabulation2\n" + + "lalallala\ttrollololo." ); + actions.put( "ride the dragon", "Go to work by bike." ); + actions.put( "make some coffee", null ); + return actions; + } + + private static Set< String > getDemoContexts() + { + final Set< String > contexts = new HashSet<>(); + contexts.add( "all" ); + contexts.add( "mamut" ); + contexts.add( "trackscheme" ); + return contexts; + } + + /** + * Launch the application. + * + * @param args + * + * @throws UnsupportedLookAndFeelException + * @throws IllegalAccessException + * @throws InstantiationException + * @throws ClassNotFoundException + */ + public static void main( final String[] args ) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException + { + UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() ); + EventQueue.invokeLater( new Runnable() + { + @Override + public void run() + { + try + { + final JFrame frame = new JFrame( "Behaviour Key bindings editor" ); + final VisualEditorPanel editorPanel = new VisualEditorPanel( getDemoConfig(), getDemoActions(), getDemoContexts() ); + SwingUtilities.updateComponentTreeUI( VisualEditorPanel.fileChooser ); + frame.getContentPane().add( editorPanel ); + frame.pack(); + frame.setVisible( true ); + } + catch ( final Exception e ) + { + e.printStackTrace(); + } + } + } ); + } +} From ce631e083113ffce1af69003d278a37c0dd63d66 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Fri, 3 Nov 2017 11:46:31 +0100 Subject: [PATCH 064/184] Do not expose actionInputMaps field through InputTriggerDescriptionsBuilder --- .../ui/behaviour/io/InputTriggerDescriptionsBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java index f9281c3..7a313b4 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java @@ -111,7 +111,7 @@ public Set< String > getContexts() public Set< String > getBehaviourNames() { - return config.actionToInputsMap.keySet(); + return new LinkedHashSet<>( config.actionToInputsMap.keySet() ); } public void addMap( final InputTriggerMap map, final String context ) From 35b379d06989da369572e8c24f5e60e161621488 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Fri, 3 Nov 2017 15:38:08 +0100 Subject: [PATCH 065/184] Add KeyStrokeAdder.put(String, InputTrigger...) so that "not mapped" can be specified for Actions --- .../scijava/ui/behaviour/KeyStrokeAdder.java | 3 ++ .../ui/behaviour/io/InputTriggerConfig.java | 46 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java index 5584050..cc33d0d 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java @@ -39,8 +39,11 @@ public interface Factory public KeyStrokeAdder keyStrokeAdder( InputMap map, final String ... contexts ); } + @Deprecated public void put( final String actionName, final KeyStroke... defaultKeyStrokes ); + public void put( final String actionName, final InputTrigger... defaultKeyStrokes ); + public void put( final String actionName, final String... defaultKeyStrokes ); public void put( final String actionName ); diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index e2beb66..72a101a 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -229,13 +229,55 @@ public void put( final String actionName, final KeyStroke... defaultKeyStrokes ) } } + @Override + public void put( final String actionName, final InputTrigger... defaultKeyStrokes ) + { + final Set< InputTrigger > triggers = config.getInputs( actionName, contexts ); + if ( triggers.contains( InputTrigger.NOT_MAPPED ) ) + return; + + boolean configKeyAdded = false; + for ( final InputTrigger trigger : triggers ) + { + if ( trigger.isKeyStroke() ) + { + map.put( trigger.getKeyStroke(), actionName ); + configKeyAdded = true; + } + } + if ( configKeyAdded ) + return; + + if ( defaultKeyStrokes.length > 0 ) + { + if ( defaultKeyStrokes[ 0 ].equals( InputTrigger.NOT_MAPPED ) ) + { + config.add( InputTrigger.NOT_MAPPED, actionName, contexts ); + return; + } + + for ( final InputTrigger trigger : triggers ) + { + if ( trigger.isKeyStroke() ) + { + config.add( trigger, actionName, contexts ); + map.put( trigger.getKeyStroke(), actionName ); + configKeyAdded = true; + } + } + } + + if ( !configKeyAdded ) + System.err.println( "Could not assign KeyStroke for \"" + actionName + "\". Nothing defined in InputTriggerConfig, and no default given." ); + } + @Override public void put( final String actionName, final String... defaultKeyStrokes ) { - final KeyStroke[] keyStrokes = new KeyStroke[ defaultKeyStrokes.length ]; + final InputTrigger[] keyStrokes = new InputTrigger[ defaultKeyStrokes.length ]; int i = 0; for ( final String s : defaultKeyStrokes ) - keyStrokes[ i++ ] = KeyStroke.getKeyStroke( s ); + keyStrokes[ i++ ] = InputTrigger.getFromString( s ); put( actionName, keyStrokes ); } From f2d54b64abc5a934ed2d344e0f03b3f49f388176 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Fri, 3 Nov 2017 23:29:49 +0100 Subject: [PATCH 066/184] VisualEditor: clear the description text when noting is selected. --- src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 0d80fec..348206e 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -532,6 +532,7 @@ private void updateEditors() labelCommandName.setText( "" ); keybindingEditor.setInputTrigger( InputTrigger.NOT_MAPPED ); contextsEditor.setTags( Collections.emptyList() ); + textAreaDescription.setText( "" ); return; } From 8aa5b485377077fb58877b0b0eb72c7e8a03b738 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 12 Nov 2017 17:15:15 +0100 Subject: [PATCH 067/184] Specify commands as map -> map of contexts -> description. A pair (name, context) specifies an action. So, actually, (name, context) is the real name of the action. Even if the command name might be the same across two contexts, they might not share the same description. We add a utility class to conveniently build this 2 layers map. --- .../ui/behaviour/io/VisualEditorPanel.java | 67 ++++++++++++++----- .../io/gui/CommandDescriptionBuilder.java | 51 ++++++++++++++ .../behaviour/io/VisualEditorPanelDemo.java | 43 +++++------- 3 files changed, 119 insertions(+), 42 deletions(-) create mode 100644 src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 348206e..0754ff7 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -18,10 +18,12 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; + import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; @@ -44,8 +46,10 @@ import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableRowSorter; + import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.io.InputTriggerConfig.Input; +import org.scijava.ui.behaviour.io.gui.CommandDescriptionBuilder; import org.scijava.ui.behaviour.io.gui.InputTriggerPanelEditor; import org.scijava.ui.behaviour.io.gui.TagPanelEditor; @@ -89,7 +93,7 @@ public boolean accept( final File f ) private final InputTriggerConfig config; - private final Map< String, String > actionDescriptions; + private final Map< String, Map< String, String > > actionDescriptions; private final Set< String > contexts; @@ -108,21 +112,28 @@ public boolean accept( final File f ) * @param config * the {@link InputTriggerConfig} object to modify. * @param commandDescriptions - * The commands available. They are specified as a map from - * command name to their description. Use null as - * value to not specify a description. - * @param contexts - * The contexts available. + * The commands available. They are specified as a map from map + * of commands -> map of contexts -> description of what the + * command do in a context. Use null as value to not + * specify a description. + * @see CommandDescriptionBuilder */ - public VisualEditorPanel( final InputTriggerConfig config, final Map< String, String > commandDescriptions, final Set< String > contexts ) + public VisualEditorPanel( final InputTriggerConfig config, final Map< String, Map< String, String > > commandDescriptions ) { + + this.config = config; + this.actionDescriptions = commandDescriptions; + this.contexts = new HashSet<>(); + for ( final String command : commandDescriptions.keySet() ) + { + final Map< String, String > contextMap = commandDescriptions.get( command ); + contexts.addAll( contextMap.keySet() ); + } + /* * GUI */ - this.config = config; - this.actionDescriptions = commandDescriptions; - this.contexts = contexts; setLayout( new BorderLayout( 0, 0 ) ); final JPanel panelFilter = new JPanel(); @@ -333,7 +344,8 @@ public void valueChanged( final ListSelectionEvent e ) tableBindings.setFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null ); tableBindings.setFocusTraversalKeys( KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null ); - // Listen to changes in the keybinding editor and forward to table model. + // Listen to changes in the keybinding editor and forward to table + // model. keybindingEditor.addInputTriggerChangeListener( () -> keybindingsChanged( keybindingEditor.getInputTrigger() == null ? keybindingEditor.getLastValidInputTrigger() @@ -385,7 +397,7 @@ private void lookForConflicts() } } - public void setButtonPanelVisible( boolean visible ) + public void setButtonPanelVisible( final boolean visible ) { panelEditor.remove( panelButtons ); if ( visible ) @@ -406,11 +418,12 @@ public void modelToConfig() config.add( inputTrigger, action, cs ); } - // fill in InputTrigger.NOT_MAPPED for any action that doesn't have any input - for ( String context : contexts ) + // fill in InputTrigger.NOT_MAPPED for any action that doesn't have any + // input + for ( final String context : contexts ) { final Set< String > cs = Collections.singleton( context ); - for ( String action : actionDescriptions.keySet() ) + for ( final String action : actionDescriptions.keySet() ) if ( config.getInputs( action, cs ).isEmpty() ) config.add( InputTrigger.NOT_MAPPED, action, cs ); } @@ -540,12 +553,32 @@ private void updateEditors() final String action = tableModel.commands.get( modelRow ); final InputTrigger trigger = tableModel.bindings.get( modelRow ); final List< String > contexts = new ArrayList<>( tableModel.contexts.get( modelRow ) ); - final String description = actionDescriptions.get( action ); + + final Map< String, String > contextMap = actionDescriptions.get( action ); + final String description; + if ( null == contextMap || contextMap.isEmpty() ) + description = ""; + else if ( contextMap.size() == 1 ) + description = contextMap.get( contextMap.keySet().iterator().next() ); + else + { + final StringBuilder str = new StringBuilder(); + final Iterator< String > cs = contextMap.keySet().iterator(); + while ( cs.hasNext() ) + { + final String c = cs.next(); + final String d = contextMap.get( c ); + if ( d != null ) + str.append( "\n\nIn " + c + ":\n" + d ); + } + str.delete( 0, 2 ); + description = str.toString(); + } labelCommandName.setText( action ); keybindingEditor.setInputTrigger( trigger ); contextsEditor.setTags( contexts ); - textAreaDescription.setText( ( null == description ) ? "" : description ); + textAreaDescription.setText( description ); textAreaDescription.setCaretPosition( 0 ); lookForConflicts(); diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java new file mode 100644 index 0000000..aa112ea --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java @@ -0,0 +1,51 @@ +package org.scijava.ui.behaviour.io.gui; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Utility class that is used to build a 2-level map of existing contexts -> + * commands and their description. + * + * @author Jean-Yves Tinevez + * + */ +public class CommandDescriptionBuilder +{ + + /** + * The map of commands -> map of contexts -> description of what the command + * do in a context. + */ + private HashMap< String, Map< String, String > > map; + + public CommandDescriptionBuilder() + { + this.map = new HashMap<>(); + } + + public CommandDescriptionBuilder addCommand( final String command, final String context, final String description ) + { + Map< String, String > contextMap = map.get( command ); + if ( contextMap == null ) + { + contextMap = new HashMap<>(); + map.put( command, contextMap ); + } + contextMap.put( context, description ); + return this; + } + + /** + * Returns the map of commands -> map of contexts -> description of what the + * command does in a context. + * + * @return a new immutable map + */ + public Map< String, Map< String, String > > get() + { + return Collections.unmodifiableMap( map ); + } + +} diff --git a/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java index 7f78caf..e81d0db 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java @@ -2,15 +2,15 @@ import java.awt.EventQueue; import java.io.StringReader; -import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; + import javax.swing.JFrame; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; + +import org.scijava.ui.behaviour.io.gui.CommandDescriptionBuilder; import org.scijava.ui.behaviour.io.yaml.YamlConfigIO; public class VisualEditorPanelDemo @@ -48,28 +48,21 @@ private static InputTriggerConfig getDemoConfig() return config; } - private static Map< String, String > getDemoActions() - { - final Map< String, String > actions = new HashMap<>(); - actions.put( "drag1", "Move an item around the editor." ); - actions.put( "scroll1", null ); - actions.put( "destroy the world", "Make a disgusting coffee for breakfast. \n" - + "For this one, you are by yourself. Good luck and know that we are with you. This is a long line. Hopefully long engouh.\n" - + "Hey, what about we add:\n" - + "tabulation1\ttabulation2\n" - + "lalallala\ttrollololo." ); - actions.put( "ride the dragon", "Go to work by bike." ); - actions.put( "make some coffee", null ); - return actions; - } - - private static Set< String > getDemoContexts() + private static Map< String, Map< String, String > > getDemoCommands() { - final Set< String > contexts = new HashSet<>(); - contexts.add( "all" ); - contexts.add( "mamut" ); - contexts.add( "trackscheme" ); - return contexts; + return new CommandDescriptionBuilder() + .addCommand( "drag1", "mamut", "Move an item around the editor." ) + .addCommand( "drag1", "trackscheme", "Move an item around the editor." ) + .addCommand( "scroll1", "mamut", null ) + .addCommand( "destroy the world", "all", "Make a disgusting coffee for breakfast. \n" + + "For this one, you are by yourself. Good luck and know that we are with you. This is a long line. Hopefully long engouh.\n" + + "Hey, what about we add:\n" + + "tabulation1\ttabulation2\n" + + "lalallala\ttrollololo." ) + .addCommand( "ride the dragon", "all", "Go to work by bike." ) + .addCommand( "make some coffee", "mamut", null ) + .addCommand( "make some coffee", "trackscheme", "Make a decent coffee." ) + .get(); } /** @@ -93,7 +86,7 @@ public void run() try { final JFrame frame = new JFrame( "Behaviour Key bindings editor" ); - final VisualEditorPanel editorPanel = new VisualEditorPanel( getDemoConfig(), getDemoActions(), getDemoContexts() ); + final VisualEditorPanel editorPanel = new VisualEditorPanel( getDemoConfig(), getDemoCommands() ); SwingUtilities.updateComponentTreeUI( VisualEditorPanel.fileChooser ); frame.getContentPane().add( editorPanel ); frame.pack(); From 02623a007ab2440d36893042b91bbe0afa720017 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Mon, 13 Nov 2017 22:59:27 +0100 Subject: [PATCH 068/184] The TagPanelEditor can change its acceptable tags. --- .../org/scijava/ui/behaviour/io/gui/TagPanelEditor.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java index afa18e5..e230d92 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java @@ -133,6 +133,14 @@ public void setTags( final Collection< String > tags ) repaint(); } + public void setAcceptableTags( final Collection< String > acceptableTags ) + { + tags.clear(); + tags.addAll( acceptableTags ); + tags.sort( null ); + repaint(); + } + protected void addTag( final String tag ) { final TagPanel tagp = new TagPanel( tag, this.tags.contains( tag ) ); From 05769004986fe04cd4f5f230d830e07dd7487cfd Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Mon, 13 Nov 2017 23:02:26 +0100 Subject: [PATCH 069/184] Contexts that are undefined for a command are shown in red. If the commands 'add' and 'delete' are defined for context 'trackscheme', and if only 'add' is defined for context 'mamut', them 'mamut' will be shown in red for the 'delete' command, even if the 'mamut' context exists for other commands. --- .../ui/behaviour/io/VisualEditorPanel.java | 57 +++++++++++++++---- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 0754ff7..d99c663 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -431,7 +431,7 @@ public void modelToConfig() public void configToModel() { - tableModel = new MyTableModel( actionDescriptions.keySet(), config.actionToInputsMap ); + tableModel = new MyTableModel( actionDescriptions, config.actionToInputsMap ); tableBindings.setModel( tableModel ); // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); @@ -531,7 +531,8 @@ private void unbindAllCommand() if ( tableModel.commands.get( i ).equals( action ) ) { tableModel.bindings.set( i, InputTrigger.NOT_MAPPED ); - tableModel.contexts.set( i, Collections.emptyList() ); + final List< String > cs = new ArrayList<>( actionDescriptions.get( action ).keySet() ); + tableModel.contexts.set( i, cs ); } } removeDuplicates(); @@ -554,9 +555,11 @@ private void updateEditors() final InputTrigger trigger = tableModel.bindings.get( modelRow ); final List< String > contexts = new ArrayList<>( tableModel.contexts.get( modelRow ) ); - final Map< String, String > contextMap = actionDescriptions.get( action ); + Map< String, String > contextMap = actionDescriptions.get( action ); + if ( null == contextMap ) + contextMap = Collections.emptyMap(); final String description; - if ( null == contextMap || contextMap.isEmpty() ) + if ( contextMap.isEmpty() ) description = ""; else if ( contextMap.size() == 1 ) description = contextMap.get( contextMap.keySet().iterator().next() ); @@ -577,6 +580,7 @@ else if ( contextMap.size() == 1 ) labelCommandName.setText( action ); keybindingEditor.setInputTrigger( trigger ); + contextsEditor.setAcceptableTags( contextMap.keySet() ); contextsEditor.setTags( contexts ); textAreaDescription.setText( description ); textAreaDescription.setCaretPosition( 0 ); @@ -648,18 +652,21 @@ private void copyCommand() final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); final String action = tableModel.commands.get( modelRow ); + final List< String > cs = tableModel.contexts.get( modelRow ); // Check whether there is already a line in the table without a binding. for ( int i = 0; i < tableModel.commands.size(); i++ ) { // Brute force. - if ( tableModel.commands.get( i ).equals( action ) && tableModel.bindings.get( i ) == InputTrigger.NOT_MAPPED ) + if ( tableModel.commands.get( i ).equals( action ) + && new HashSet<>( cs ).equals( new HashSet<>( tableModel.contexts.get( i ) ) ) + && tableModel.bindings.get( i ) == InputTrigger.NOT_MAPPED ) return; } // Create one then. tableModel.commands.add( modelRow + 1, action ); tableModel.bindings.add( modelRow + 1, InputTrigger.NOT_MAPPED ); - tableModel.contexts.add( modelRow + 1, Collections.emptyList() ); + tableModel.contexts.add( modelRow + 1, cs ); tableModel.fireTableRowsInserted( modelRow, modelRow ); } @@ -690,7 +697,7 @@ private void contextsChanged( final List< String > selectedContexts ) * INNER CLASSES */ - private static final class MyContextsRenderer extends TagPanelEditor implements TableCellRenderer + private final class MyContextsRenderer extends TagPanelEditor implements TableCellRenderer { private static final long serialVersionUID = 1L; @@ -706,6 +713,12 @@ public Component getTableCellRendererComponent( final JTable table, final Object { setForeground( isSelected ? table.getSelectionForeground() : table.getForeground() ); setBackground( isSelected ? table.getSelectionBackground() : table.getBackground() ); + final int modelRow = tableBindings.convertRowIndexToModel( row ); + final String command = tableModel.commands.get( modelRow ); + Map< String, String > contextMap = actionDescriptions.get( command ); + if ( null == contextMap ) + contextMap = Collections.emptyMap(); + setAcceptableTags( contextMap.keySet() ); @SuppressWarnings( "unchecked" ) final List< String > contexts = ( List< String > ) value; @@ -761,31 +774,40 @@ private static class MyTableModel extends AbstractTableModel private final List< List< String > > contexts; - public MyTableModel( final Set< String > baseCommands, final Map< String, Set< Input > > actionToInputsMap ) + public MyTableModel( final Map< String, Map< String, String > > actionDescriptions, final Map< String, Set< Input > > actionToInputsMap ) { this.commands = new ArrayList<>(); this.bindings = new ArrayList<>(); this.contexts = new ArrayList<>(); final Set< String > allCommands = new HashSet<>(); - allCommands.addAll( baseCommands ); + allCommands.addAll( actionDescriptions.keySet() ); allCommands.addAll( actionToInputsMap.keySet() ); final List< String > sortedCommands = new ArrayList<>( allCommands ); sortedCommands.sort( null ); final InputComparator inputComparator = new InputComparator(); for ( final String command : sortedCommands ) { + Map< String, String > contextMap = actionDescriptions.get( command ); + if ( null == contextMap ) + contextMap = Collections.emptyMap(); + final Set< Input > inputs = actionToInputsMap.get( command ); if ( null == inputs ) { + // Not found in the config. Add command with due contexts. commands.add( command ); bindings.add( InputTrigger.NOT_MAPPED ); - contexts.add( Collections.emptyList() ); + final List< String > cs = new ArrayList<>( contextMap.keySet() ); + cs.sort( null ); + contexts.add( cs ); } else { + // Found in the config. final List< Input > sortedInputs = new ArrayList<>( inputs ); sortedInputs.sort( inputComparator ); + final Set< String > usedContexts = new HashSet<>(); for ( final Input input : sortedInputs ) { commands.add( command ); @@ -793,6 +815,21 @@ public MyTableModel( final Set< String > baseCommands, final Map< String, Set< I final List< String > cs = new ArrayList<>( input.contexts ); cs.sort( null ); contexts.add( cs ); + usedContexts.addAll( cs ); + } + /* + * Check that we have exhausted known contexts. If not, push + * missing ones. + */ + final Set< String > missingContexts = new HashSet<>( contextMap.keySet() ); + missingContexts.removeAll( usedContexts ); + if ( !missingContexts.isEmpty() ) + { + final List< String > sortedMissingContexts = new ArrayList<>( missingContexts ); + sortedMissingContexts.sort( null ); + commands.add( command ); + bindings.add( InputTrigger.NOT_MAPPED ); + contexts.add( sortedMissingContexts ); } } } From c9fdc43da83fb6c1b04759a4b45c867ac54e6587 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Mon, 13 Nov 2017 23:09:45 +0100 Subject: [PATCH 070/184] Reinstate default contexts (all of them) when an action in unbound. --- .../ui/behaviour/io/VisualEditorPanel.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index d99c663..d78f882 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -531,8 +531,13 @@ private void unbindAllCommand() if ( tableModel.commands.get( i ).equals( action ) ) { tableModel.bindings.set( i, InputTrigger.NOT_MAPPED ); - final List< String > cs = new ArrayList<>( actionDescriptions.get( action ).keySet() ); + Map< String, String > contextMap = actionDescriptions.get( action ); + if ( null == contextMap ) + contextMap = Collections.emptyMap(); + final List< String > cs = new ArrayList<>( contextMap.keySet() ); + cs.sort( null ); tableModel.contexts.set( i, cs ); + tableModel.fireTableRowsUpdated( i, i ); } } removeDuplicates(); @@ -599,9 +604,15 @@ private void unbindCommand() if ( inputTrigger == InputTrigger.NOT_MAPPED ) return; - // Update model & + // Update model. keybindingsChanged( InputTrigger.NOT_MAPPED ); - contextsChanged( Collections.emptyList() ); + final String command = tableModel.commands.get( modelRow ); + Map< String, String > contextMap = actionDescriptions.get( command ); + if ( null == contextMap ) + contextMap = Collections.emptyMap(); + final List< String > cs = new ArrayList<>( contextMap.keySet() ); + cs.sort( null ); + contextsChanged( cs ); // Find whether we have two lines with the same action, unbound. removeDuplicates(); From deab0244028fd85da9ae9cc5d1fdd3dcd408063a Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Mon, 13 Nov 2017 23:21:01 +0100 Subject: [PATCH 071/184] Reinstate missing contexts if the user remove one that is defined for a command. Also warn the user when we have no context for a command, painting the context cell in red. This happens e.g. if the config contains a command that is not passed in the actionDescription map. --- .../ui/behaviour/io/VisualEditorPanel.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index d78f882..1969849 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -702,6 +702,29 @@ private void contextsChanged( final List< String > selectedContexts ) tableModel.contexts.set( modelRow, new ArrayList<>( selectedContexts ) ); tableModel.fireTableCellUpdated( modelRow, 2 ); + + // Check whether we have lost some contexts known for this command. + final String command = tableModel.commands.get( modelRow ); + Map< String, String > contextMap = actionDescriptions.get( command ); + if ( null == contextMap ) + contextMap = Collections.emptyMap(); + final Set< String > missingContexts = new HashSet<>( contextMap.keySet() ); + // Brute force + for ( int i = 0; i < tableModel.commands.size(); i++ ) + { + if ( command.equals( tableModel.commands.get( i ) ) ) + missingContexts.removeAll( tableModel.contexts.get( i ) ); + } + // Recreate missing contexts as unbound line. + if ( !missingContexts.isEmpty() ) + { + final List< String > cs = new ArrayList<>( missingContexts ); + cs.sort( null ); + tableModel.commands.add( modelRow + 1, command ); + tableModel.bindings.add( modelRow + 1, InputTrigger.NOT_MAPPED ); + tableModel.contexts.add( modelRow + 1, cs ); + tableModel.fireTableRowsInserted( modelRow + 1, modelRow + 1 ); + } } /* @@ -733,6 +756,8 @@ public Component getTableCellRendererComponent( final JTable table, final Object @SuppressWarnings( "unchecked" ) final List< String > contexts = ( List< String > ) value; + if ( contexts.isEmpty() ) + setBackground( Color.PINK ); setTags( contexts ); setToolTipText( contexts.toString() ); return this; From 909388e84237fd7e753dfc1f38c396dab41049ff Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 15 Nov 2017 22:13:45 +0100 Subject: [PATCH 072/184] Bump to next development cycle Signed-off-by: Tobias Pietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 022894f..80d648b 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.4.1-SNAPSHOT + 1.5.1-SNAPSHOT UI Behaviour Configurable key and mouse event handling From b3d82c6c81680cb34e38b54a46e9a0fffe94ca9d Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 19 Nov 2017 21:01:54 +0100 Subject: [PATCH 073/184] Javadoc for a public method of the visual editor. --- .../java/org/scijava/ui/behaviour/io/VisualEditorPanel.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 1969849..9e1f4da 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -404,6 +404,12 @@ public void setButtonPanelVisible( final boolean visible ) panelEditor.add( panelButtons, BorderLayout.SOUTH ); } + // TODO Change method name to 'apply()'. API breaking change. + /** + * Copies the settings in this editor to the {@link InputTriggerConfig} + * specified at construction. The {@link InputTriggerConfig} is cleared + * before copying. + */ public void modelToConfig() { config.clear(); From b007354cb81dfb23a92fad9d4e45becaf9eb3013 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 19 Nov 2017 21:15:56 +0100 Subject: [PATCH 074/184] Can register listeners to be notified when the visual editor is changed. --- .../ui/behaviour/io/VisualEditorPanel.java | 49 +++++++++++++++++++ .../behaviour/io/VisualEditorPanelDemo.java | 1 + 2 files changed, 50 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 9e1f4da..9b8cd77 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -79,6 +79,19 @@ public boolean accept( final File f ) } ); } + /** + * Interface for listeners notified when settings are changed in the visual + * editor. + */ + @FunctionalInterface + public static interface ConfigChangeListener + { + /** + * Called when settings are changed in the visual editor. + */ + public void configChanged(); + } + private JTextField textFieldFilter; private MyTableModel tableModel; @@ -105,6 +118,8 @@ public boolean accept( final File f ) private final JPanel panelButtons; + private final HashSet< ConfigChangeListener > listeners; + /** * Creates a visual editor for an {@link InputTriggerConfig}. The config * object is directly modified when the user clicks the 'Apply' button. @@ -129,6 +144,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Map< String, Ma final Map< String, String > contextMap = commandDescriptions.get( command ); contexts.addAll( contextMap.keySet() ); } + this.listeners = new HashSet<>(); /* * GUI @@ -443,6 +459,9 @@ public void configToModel() tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); tableBindings.getColumnModel().getColumn( 2 ).setCellRenderer( new MyContextsRenderer( contexts ) ); tableBindings.getSelectionModel().setSelectionInterval( 0, 0 ); + + // Notify listeners. + notifyListeners(); } private void filterRows() @@ -658,7 +677,12 @@ private void removeDuplicates() tableModel.fireTableRowsDeleted( row, row ); } + // Notify listeners. + if ( !toRemove.isEmpty() ) + notifyListeners(); + updateEditors(); + } private void copyCommand() @@ -685,6 +709,9 @@ private void copyCommand() tableModel.bindings.add( modelRow + 1, InputTrigger.NOT_MAPPED ); tableModel.contexts.add( modelRow + 1, cs ); tableModel.fireTableRowsInserted( modelRow, modelRow ); + + // Notify listeners. + notifyListeners(); } private void keybindingsChanged( final InputTrigger inputTrigger ) @@ -697,6 +724,9 @@ private void keybindingsChanged( final InputTrigger inputTrigger ) tableModel.bindings.set( modelRow, inputTrigger ); tableModel.fireTableCellUpdated( modelRow, 1 ); lookForConflicts(); + + // Notify listeners. + notifyListeners(); } private void contextsChanged( final List< String > selectedContexts ) @@ -731,6 +761,25 @@ private void contextsChanged( final List< String > selectedContexts ) tableModel.contexts.add( modelRow + 1, cs ); tableModel.fireTableRowsInserted( modelRow + 1, modelRow + 1 ); } + + // Notify listeners. + notifyListeners(); + } + + private void notifyListeners() + { + for ( final ConfigChangeListener listener : listeners ) + listener.configChanged(); + } + + public void addConfigChangeListener( final ConfigChangeListener listener ) + { + listeners.add( listener ); + } + + public void removeConfigChangeListener( final ConfigChangeListener listener ) + { + listeners.remove( listener ); } /* diff --git a/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java index e81d0db..ca826e5 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java @@ -87,6 +87,7 @@ public void run() { final JFrame frame = new JFrame( "Behaviour Key bindings editor" ); final VisualEditorPanel editorPanel = new VisualEditorPanel( getDemoConfig(), getDemoCommands() ); + editorPanel.addConfigChangeListener( () -> System.out.println( "Config changed @ " + new java.util.Date().toString() ) ); SwingUtilities.updateComponentTreeUI( VisualEditorPanel.fileChooser ); frame.getContentPane().add( editorPanel ); frame.pack(); From e008d51389c15d2e8a38bcac85ee9743330a25ac Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 19 Nov 2017 21:20:02 +0100 Subject: [PATCH 075/184] Always show what contexts exist for a command in the description pane. --- .../java/org/scijava/ui/behaviour/io/VisualEditorPanel.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 9b8cd77..fbb0657 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -591,8 +591,6 @@ private void updateEditors() final String description; if ( contextMap.isEmpty() ) description = ""; - else if ( contextMap.size() == 1 ) - description = contextMap.get( contextMap.keySet().iterator().next() ); else { final StringBuilder str = new StringBuilder(); @@ -603,6 +601,8 @@ else if ( contextMap.size() == 1 ) final String d = contextMap.get( c ); if ( d != null ) str.append( "\n\nIn " + c + ":\n" + d ); + else + str.append( "\n\nIn " + c + " - no description." ); } str.delete( 0, 2 ); description = str.toString(); From 6d4b3504e77217fe9cab7a02d6038037eceb29bb Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 19 Nov 2017 21:31:09 +0100 Subject: [PATCH 076/184] Dis/Enable Restore and Apply buttons if relevant. --- .../ui/behaviour/io/VisualEditorPanel.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index fbb0657..463df36 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -120,6 +120,10 @@ public static interface ConfigChangeListener private final HashSet< ConfigChangeListener > listeners; + private final JButton btnApply; + + private final JButton btnRestore; + /** * Creates a visual editor for an {@link InputTriggerConfig}. The config * object is directly modified when the user clicks the 'Apply' button. @@ -328,11 +332,11 @@ public void changedUpdate( final DocumentEvent e ) final FlowLayout flowLayout = ( FlowLayout ) panelButtons.getLayout(); flowLayout.setAlignment( FlowLayout.TRAILING ); - final JButton btnRestore = new JButton( "Restore" ); + this.btnRestore = new JButton( "Restore" ); btnRestore.setToolTipText( "Re-read the key bindings from the config." ); panelButtons.add( btnRestore ); - final JButton btnApply = new JButton( "Apply" ); + this.btnApply = new JButton( "Apply" ); btnApply.setToolTipText( "Write these key bindings in the config." ); panelButtons.add( btnApply ); @@ -378,6 +382,17 @@ public void valueChanged( final ListSelectionEvent e ) btnRestore.addActionListener( ( e ) -> configToModel() ); btnApply.addActionListener( ( e ) -> modelToConfig() ); + // Buttons re-enabling when model and config are out of sync. + addConfigChangeListener( new ConfigChangeListener() + { + @Override + public void configChanged() + { + btnApply.setEnabled( true ); + btnRestore.setEnabled( true ); + } + } ); + configToModel(); scrollPane.setViewportView( tableBindings ); } @@ -449,6 +464,9 @@ public void modelToConfig() if ( config.getInputs( action, cs ).isEmpty() ) config.add( InputTrigger.NOT_MAPPED, action, cs ); } + + btnApply.setEnabled( false ); + btnRestore.setEnabled( false ); } public void configToModel() @@ -462,6 +480,9 @@ public void configToModel() // Notify listeners. notifyListeners(); + + btnApply.setEnabled( false ); + btnRestore.setEnabled( false ); } private void filterRows() From 4e04ec758b321ecc1f0cbe695934686d760118e9 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Sun, 3 Dec 2017 12:58:40 +0100 Subject: [PATCH 077/184] Fix a bug preventing deafult keystrokes to be used for Actions. This caused numerous Cannot assign key stroke for... in TrackScheme3. --- .../java/org/scijava/ui/behaviour/io/InputTriggerConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 72a101a..5724e5c 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -256,7 +256,7 @@ public void put( final String actionName, final InputTrigger... defaultKeyStroke return; } - for ( final InputTrigger trigger : triggers ) + for ( final InputTrigger trigger : defaultKeyStrokes ) { if ( trigger.isKeyStroke() ) { From 4e7baff378b57ff6404e9cca7b7a91603d9d422d Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Mon, 4 Dec 2017 13:43:50 +0100 Subject: [PATCH 078/184] Bump to next development cycle Signed-off-by: Tobias Pietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 80d648b..8d16756 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.5.1-SNAPSHOT + 1.5.2-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 468de3d6bbb469b258c209936dfd29d3328013c5 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Tue, 5 Dec 2017 19:41:46 +0100 Subject: [PATCH 079/184] Allows for removing NOT_MAPPED bindings if there is another binding for the action. Before this commit, it was possible to have ine the editor an action with a binding AND NOT_MAPPED as a binding. --- .../ui/behaviour/io/VisualEditorPanel.java | 43 ++++++++++++++++--- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 463df36..6c4a7ce 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -646,10 +646,6 @@ private void unbindCommand() return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - final InputTrigger inputTrigger = tableModel.bindings.get( modelRow ); - if ( inputTrigger == InputTrigger.NOT_MAPPED ) - return; - // Update model. keybindingsChanged( InputTrigger.NOT_MAPPED ); final String command = tableModel.commands.get( modelRow ); @@ -666,13 +662,22 @@ private void unbindCommand() private void removeDuplicates() { + // Map of the command to the set of triggers in the table. final Map< String, Set< InputTrigger > > bindings = new HashMap<>(); + // Map of the command to the row the NOT_MAPPED trigger is in the table. + final Map< String, Set< Integer > > notMappedBindings = new HashMap<>(); + + /* + * First round: Simply remove duplicates whatever the bindings are. + */ + final List< Integer > toRemove = new ArrayList<>(); for ( int row = 0; row < tableModel.getRowCount(); row++ ) { final String action = tableModel.commands.get( row ); final InputTrigger trigger = tableModel.bindings.get( row ); + // Detect duplicate. if ( bindings.get( action ) == null ) { final Set< InputTrigger > triggers = new HashSet<>(); @@ -686,8 +691,36 @@ private void removeDuplicates() if ( !notAlreadyPresent ) toRemove.add( Integer.valueOf( row ) ); } + + // Detect NOT_MAPPED. + if (trigger == InputTrigger.NOT_MAPPED) + { + if ( notMappedBindings.get( action ) == null ) + { + final Set< Integer > notMapped = new HashSet<>(); + notMapped.add( Integer.valueOf( row ) ); + notMappedBindings.put( action, notMapped ); + } + else + { + notMappedBindings.get( action ).add( Integer.valueOf( row ) ); + } + } } + /* + * Second pass: We want to remove NOT_MAPPED rows for action that have + * an otherwise trigger. + */ + for ( final String action : notMappedBindings.keySet() ) + if ( bindings.get( action ).size() > 1 ) + for ( final Integer row : notMappedBindings.get( action ) ) + toRemove.add( row ); + + /* + * Remove. + */ + toRemove.sort( Comparator.reverseOrder() ); for ( final Integer rowToRemove : toRemove ) { @@ -916,7 +949,7 @@ public MyTableModel( final Map< String, Map< String, String > > actionDescriptio } else { - // Found in the config. + // Found in the config. final List< Input > sortedInputs = new ArrayList<>( inputs ); sortedInputs.sort( inputComparator ); final Set< String > usedContexts = new HashSet<>(); From 779ce1f3ad351db84d13f2bc21d93bea9dab511b Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 6 Dec 2017 19:33:50 +0100 Subject: [PATCH 080/184] WIP: fixing visual editor --- .../ui/behaviour/io/VisualEditorPanel.java | 544 ++++++++++-------- .../scijava/ui/behaviour/io/gui/Command.java | 52 ++ .../io/gui/CommandDescriptionBuilder.java | 19 +- .../io/gui/InputTriggerPanelEditor.java | 6 + .../behaviour/io/VisualEditorPanelDemo.java | 5 +- 5 files changed, 360 insertions(+), 266 deletions(-) create mode 100644 src/main/java/org/scijava/ui/behaviour/io/gui/Command.java diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 6c4a7ce..a02df4d 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -10,8 +10,6 @@ import java.awt.Insets; import java.awt.KeyboardFocusManager; import java.io.File; -import java.io.FileNotFoundException; -import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -23,13 +21,13 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; +import java.util.stream.Collectors; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JLabel; -import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; @@ -49,6 +47,7 @@ import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.io.InputTriggerConfig.Input; +import org.scijava.ui.behaviour.io.gui.Command; import org.scijava.ui.behaviour.io.gui.CommandDescriptionBuilder; import org.scijava.ui.behaviour.io.gui.InputTriggerPanelEditor; import org.scijava.ui.behaviour.io.gui.TagPanelEditor; @@ -81,7 +80,7 @@ public boolean accept( final File f ) /** * Interface for listeners notified when settings are changed in the visual - * editor. + * editor.`` */ @FunctionalInterface public static interface ConfigChangeListener @@ -106,9 +105,13 @@ public static interface ConfigChangeListener private final InputTriggerConfig config; - private final Map< String, Map< String, String > > actionDescriptions; + private final Set< Command > commands; - private final Set< String > contexts; + private final Map< String, Set< String > > commandNameToAcceptableContexts; + + private final Map< Command, String > actionDescriptions; + + private final Set< String > contexts; // TODO: do we need it? private final JLabel lblConflict; @@ -137,17 +140,16 @@ public static interface ConfigChangeListener * specify a description. * @see CommandDescriptionBuilder */ - public VisualEditorPanel( final InputTriggerConfig config, final Map< String, Map< String, String > > commandDescriptions ) + public VisualEditorPanel( final InputTriggerConfig config, final Map< Command, String > commandDescriptions ) { this.config = config; this.actionDescriptions = commandDescriptions; - this.contexts = new HashSet<>(); - for ( final String command : commandDescriptions.keySet() ) - { - final Map< String, String > contextMap = commandDescriptions.get( command ); - contexts.addAll( contextMap.keySet() ); - } + this.commands = commandDescriptions.keySet(); + commandNameToAcceptableContexts = new HashMap<>(); + for ( final Command command : commands ) + commandNameToAcceptableContexts.computeIfAbsent( command.getName(), k -> new HashSet<>() ).add( command.getContext() ); + this.contexts = commands.stream().map( c -> c.getContext() ).collect( Collectors.toSet() ); // TODO: do we need it? this.listeners = new HashSet<>(); /* @@ -357,7 +359,6 @@ public void valueChanged( final ListSelectionEvent e ) { if ( e.getValueIsAdjusting() ) return; - removeDuplicates(); updateEditors(); } } ); @@ -399,6 +400,10 @@ public void configChanged() private void lookForConflicts() { + lblConflict.setText( "" ); + + // TODO: revise + /* final int viewRow = tableBindings.getSelectedRow(); if ( viewRow < 0 ) return; @@ -426,6 +431,7 @@ private void lookForConflicts() str.append( ", " + conflicts.get( i ) ); lblConflict.setText( str.toString() ); } + */ } public void setButtonPanelVisible( final boolean visible ) @@ -444,25 +450,24 @@ public void setButtonPanelVisible( final boolean visible ) public void modelToConfig() { config.clear(); - for ( int i = 0; i < tableModel.commands.size(); i++ ) + for ( final MyTableRow row : tableModel.rows ) { - final InputTrigger inputTrigger = tableModel.bindings.get( i ); + final InputTrigger inputTrigger = row.getTrigger(); if ( inputTrigger == InputTrigger.NOT_MAPPED ) continue; - final String action = tableModel.commands.get( i ); - final Set< String > cs = new HashSet<>( tableModel.contexts.get( i ) ); + final String action = row.getName(); + final Set< String > cs = new HashSet<>( row.getContexts() ); config.add( inputTrigger, action, cs ); } - // fill in InputTrigger.NOT_MAPPED for any action that doesn't have any - // input - for ( final String context : contexts ) + // fill in InputTrigger.NOT_MAPPED for any action that doesn't have any input + for ( final Command command : commands ) { - final Set< String > cs = Collections.singleton( context ); - for ( final String action : actionDescriptions.keySet() ) - if ( config.getInputs( action, cs ).isEmpty() ) - config.add( InputTrigger.NOT_MAPPED, action, cs ); + final String action = command.getName(); + final Set< String > cs = Collections.singleton( command.getContext() ); + if ( config.getInputs( action, cs ).isEmpty() ) + config.add( InputTrigger.NOT_MAPPED, action, cs ); } btnApply.setEnabled( false ); @@ -471,7 +476,7 @@ public void modelToConfig() public void configToModel() { - tableModel = new MyTableModel( actionDescriptions, config.actionToInputsMap ); + tableModel = new MyTableModel( commands, config.actionToInputsMap ); tableBindings.setModel( tableModel ); // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); @@ -493,7 +498,7 @@ private void filterRows() RowFilter< MyTableModel, Integer > rf = null; try { - final int[] indices = new int[ tableModel.commands.size() ]; + final int[] indices = new int[ tableModel.getRowCount() ]; for ( int i = 0; i < indices.length; i++ ) indices[ i ] = i; rf = RowFilter.regexFilter( textFieldFilter.getText(), 0 ); @@ -509,6 +514,7 @@ private void filterRows() private void exportToCsv() { + /* final int userSignal = fileChooser.showSaveDialog( this ); if ( userSignal != JFileChooser.APPROVE_OPTION ) return; @@ -561,32 +567,7 @@ private void exportToCsv() JOptionPane.showMessageDialog( fileChooser, "Error writing file:\n" + e.getMessage(), "Error writing file.", JOptionPane.ERROR_MESSAGE ); e.printStackTrace(); } - - } - - private void unbindAllCommand() - { - final int viewRow = tableBindings.getSelectedRow(); - if ( viewRow < 0 ) - return; - final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - - final String action = tableModel.commands.get( modelRow ); - for ( int i = 0; i < tableModel.commands.size(); i++ ) - { - if ( tableModel.commands.get( i ).equals( action ) ) - { - tableModel.bindings.set( i, InputTrigger.NOT_MAPPED ); - Map< String, String > contextMap = actionDescriptions.get( action ); - if ( null == contextMap ) - contextMap = Collections.emptyMap(); - final List< String > cs = new ArrayList<>( contextMap.keySet() ); - cs.sort( null ); - tableModel.contexts.set( i, cs ); - tableModel.fireTableRowsUpdated( i, i ); - } - } - removeDuplicates(); + */ } private void updateEditors() @@ -602,28 +583,27 @@ private void updateEditors() } final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - final String action = tableModel.commands.get( modelRow ); - final InputTrigger trigger = tableModel.bindings.get( modelRow ); - final List< String > contexts = new ArrayList<>( tableModel.contexts.get( modelRow ) ); + final MyTableRow row = tableModel.rows.get( modelRow ); + final String action = row.getName(); + final InputTrigger trigger = row.getTrigger(); + final List< String > contexts = new ArrayList<>( row.getContexts() ); - Map< String, String > contextMap = actionDescriptions.get( action ); - if ( null == contextMap ) - contextMap = Collections.emptyMap(); final String description; - if ( contextMap.isEmpty() ) + final Set< String > acceptableContexts = commandNameToAcceptableContexts.get( action ); + if ( acceptableContexts.isEmpty() ) + { description = ""; + } else { final StringBuilder str = new StringBuilder(); - final Iterator< String > cs = contextMap.keySet().iterator(); - while ( cs.hasNext() ) + for ( final String context : acceptableContexts ) { - final String c = cs.next(); - final String d = contextMap.get( c ); + final String d = actionDescriptions.get( new Command( action, context ) ); if ( d != null ) - str.append( "\n\nIn " + c + ":\n" + d ); + str.append( "\n\nIn " + context + ":\n" + d ); else - str.append( "\n\nIn " + c + " - no description." ); + str.append( "\n\nIn " + context + " - no description." ); } str.delete( 0, 2 ); description = str.toString(); @@ -631,7 +611,7 @@ private void updateEditors() labelCommandName.setText( action ); keybindingEditor.setInputTrigger( trigger ); - contextsEditor.setAcceptableTags( contextMap.keySet() ); + contextsEditor.setAcceptableTags( acceptableContexts ); contextsEditor.setTags( contexts ); textAreaDescription.setText( description ); textAreaDescription.setCaretPosition( 0 ); @@ -645,98 +625,69 @@ private void unbindCommand() if ( viewRow < 0 ) return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); + final MyTableRow removedRow = tableModel.rows.remove( modelRow ); - // Update model. - keybindingsChanged( InputTrigger.NOT_MAPPED ); - final String command = tableModel.commands.get( modelRow ); - Map< String, String > contextMap = actionDescriptions.get( command ); - if ( null == contextMap ) - contextMap = Collections.emptyMap(); - final List< String > cs = new ArrayList<>( contextMap.keySet() ); - cs.sort( null ); - contextsChanged( cs ); - - // Find whether we have two lines with the same action, unbound. - removeDuplicates(); - } + final Set< String > contextsStillPresent = new HashSet<>(); + for ( final MyTableRow row : tableModel.rows ) + if ( row.getName().equals( removedRow.getName() ) ) + contextsStillPresent.addAll( row.getContexts() ); - private void removeDuplicates() - { - // Map of the command to the set of triggers in the table. - final Map< String, Set< InputTrigger > > bindings = new HashMap<>(); - // Map of the command to the row the NOT_MAPPED trigger is in the table. - final Map< String, Set< Integer > > notMappedBindings = new HashMap<>(); + final Set< String > contextsToAddBack = new HashSet<>( removedRow.getContexts() ); + contextsToAddBack.removeAll( contextsStillPresent ); - /* - * First round: Simply remove duplicates whatever the bindings are. - */ - - final List< Integer > toRemove = new ArrayList<>(); - for ( int row = 0; row < tableModel.getRowCount(); row++ ) + if ( !contextsToAddBack.isEmpty() ) { - final String action = tableModel.commands.get( row ); - final InputTrigger trigger = tableModel.bindings.get( row ); + final MyTableRow newRow = new MyTableRow( removedRow.getName(), InputTrigger.NOT_MAPPED, new ArrayList<>( contextsToAddBack ) ); + tableModel.rows.add( modelRow, newRow ); +// tableModel.fireTableRowsUpdated( modelRow, modelRow ); +// } +// else +// { +// tableModel.fireTableRowsDeleted( modelRow, modelRow ); + } - // Detect duplicate. - if ( bindings.get( action ) == null ) - { - final Set< InputTrigger > triggers = new HashSet<>(); - triggers.add( trigger ); - bindings.put( action, triggers ); - } - else - { - final Set< InputTrigger > triggers = bindings.get( action ); - final boolean notAlreadyPresent = triggers.add( trigger ); - if ( !notAlreadyPresent ) - toRemove.add( Integer.valueOf( row ) ); - } + tableModel.mergeRows(); - // Detect NOT_MAPPED. - if (trigger == InputTrigger.NOT_MAPPED) + final int rowToSelect = Math.min( tableBindings.convertRowIndexToView( modelRow ), tableModel.getRowCount() - 1); + tableBindings.getSelectionModel().setSelectionInterval( rowToSelect, rowToSelect ); + } + + private void unbindAllCommand() + { + final int viewRow = tableBindings.getSelectedRow(); + if ( viewRow < 0 ) + return; + final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); + final MyTableRow removedRow = tableModel.rows.remove( modelRow ); + final HashSet< String > contextsToAddBack = new HashSet<>( removedRow.getContexts() ); + + final Iterator< MyTableRow > iter = tableModel.rows.iterator(); + while( iter.hasNext() ) + { + final MyTableRow row = iter.next(); + if ( row.getName().equals( removedRow.getName() ) ) { - if ( notMappedBindings.get( action ) == null ) - { - final Set< Integer > notMapped = new HashSet<>(); - notMapped.add( Integer.valueOf( row ) ); - notMappedBindings.put( action, notMapped ); - } - else - { - notMappedBindings.get( action ).add( Integer.valueOf( row ) ); - } + contextsToAddBack.addAll( row.getContexts() ); + iter.remove(); } } - /* - * Second pass: We want to remove NOT_MAPPED rows for action that have - * an otherwise trigger. - */ - for ( final String action : notMappedBindings.keySet() ) - if ( bindings.get( action ).size() > 1 ) - for ( final Integer row : notMappedBindings.get( action ) ) - toRemove.add( row ); + final Set< String > contextsStillPresent = new HashSet<>(); + for ( final MyTableRow row : tableModel.rows ) + if ( row.getName().equals( removedRow.getName() ) ) + contextsStillPresent.addAll( row.getContexts() ); - /* - * Remove. - */ - - toRemove.sort( Comparator.reverseOrder() ); - for ( final Integer rowToRemove : toRemove ) + contextsToAddBack.removeAll( contextsStillPresent ); + if ( !contextsToAddBack.isEmpty() ) { - final int row = rowToRemove.intValue(); - tableModel.commands.remove( row ); - tableModel.bindings.remove( row ); - tableModel.contexts.remove( row ); - tableModel.fireTableRowsDeleted( row, row ); + final MyTableRow newRow = new MyTableRow( removedRow.getName(), InputTrigger.NOT_MAPPED, new ArrayList<>( contextsToAddBack ) ); + tableModel.rows.add( modelRow, newRow ); } - // Notify listeners. - if ( !toRemove.isEmpty() ) - notifyListeners(); - - updateEditors(); + tableModel.mergeRows(); + final int rowToSelect = Math.min( tableBindings.convertRowIndexToView( modelRow ), tableModel.getRowCount() - 1 ); + tableBindings.getSelectionModel().setSelectionInterval( rowToSelect, rowToSelect ); } private void copyCommand() @@ -745,27 +696,51 @@ private void copyCommand() if ( viewRow < 0 ) return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); + final MyTableRow row = tableModel.rows.get( modelRow ); + + final String action = row.getName(); + final List< String > cs = row.getContexts(); + final MyTableRow copiedRow = new MyTableRow( action, InputTrigger.NOT_MAPPED, new ArrayList<>( cs ) ); + tableModel.rows.add( modelRow + 1, copiedRow ); + tableModel.mergeRows(); + + // Find the row we just added if any. + final int modelRowToSelect = Collections.binarySearch( tableModel.rows, copiedRow, new MyTableRowComparator() ); + final int rowToSelect; + if ( modelRowToSelect < 0 ) + rowToSelect = tableBindings.convertRowIndexToView( modelRow ); + else + rowToSelect = tableBindings.convertRowIndexToView( modelRowToSelect ); + tableBindings.getSelectionModel().setSelectionInterval( rowToSelect, rowToSelect ); - final String action = tableModel.commands.get( modelRow ); - final List< String > cs = tableModel.contexts.get( modelRow ); - // Check whether there is already a line in the table without a binding. - for ( int i = 0; i < tableModel.commands.size(); i++ ) + // Notify listeners. + notifyListeners(); + + // Listener to avoid having duplicates with NOT_MAPPED. If the user don't edit it, we remove it. + final ListSelectionListener lsl = new ListSelectionListener() { - // Brute force. - if ( tableModel.commands.get( i ).equals( action ) - && new HashSet<>( cs ).equals( new HashSet<>( tableModel.contexts.get( i ) ) ) - && tableModel.bindings.get( i ) == InputTrigger.NOT_MAPPED ) - return; - } + @Override + public void valueChanged( final ListSelectionEvent e ) + { + if ( e.getValueIsAdjusting() ) + return; - // Create one then. - tableModel.commands.add( modelRow + 1, action ); - tableModel.bindings.add( modelRow + 1, InputTrigger.NOT_MAPPED ); - tableModel.contexts.add( modelRow + 1, cs ); - tableModel.fireTableRowsInserted( modelRow, modelRow ); + tableBindings.getSelectionModel().removeListSelectionListener( this ); + final MyTableRow selectedRowToRestore = tableModel.rows.get( e.getFirstIndex() ); + final int modelRowToRemove = Collections.binarySearch( tableModel.rows, copiedRow, new MyTableRowComparator() ); + if ( modelRowToRemove >= 0 ) + { + tableModel.rows.remove( modelRowToRemove ); + tableModel.addMissingRows(); + } - // Notify listeners. - notifyListeners(); + final int bs = Collections.binarySearch( tableModel.rows, selectedRowToRestore, new MyTableRowComparator() ); + final int vbs = tableBindings.convertRowIndexToView( bs ); + tableBindings.getSelectionModel().setSelectionInterval( vbs, vbs ); + } + }; + tableBindings.getSelectionModel().addListSelectionListener( lsl ); + keybindingEditor.requestFocusInWindow(); } private void keybindingsChanged( final InputTrigger inputTrigger ) @@ -774,11 +749,21 @@ private void keybindingsChanged( final InputTrigger inputTrigger ) if ( viewRow < 0 ) return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); + final MyTableRow row = tableModel.rows.get( modelRow ); - tableModel.bindings.set( modelRow, inputTrigger ); - tableModel.fireTableCellUpdated( modelRow, 1 ); + final MyTableRow updatedRow = new MyTableRow( row.getName(), inputTrigger, row.getContexts() ); + tableModel.rows.set( modelRow, updatedRow ); + tableModel.mergeRows(); lookForConflicts(); + final int modelRowToSelect = Collections.binarySearch( tableModel.rows, updatedRow, new MyTableRowComparator() ); + final int rowToSelect; + if (modelRowToSelect < 0) + rowToSelect = tableBindings.convertRowIndexToView( modelRow ); + else + rowToSelect = tableBindings.convertRowIndexToView( modelRowToSelect ); + tableBindings.getSelectionModel().setSelectionInterval( rowToSelect, rowToSelect ); + // Notify listeners. notifyListeners(); } @@ -789,32 +774,11 @@ private void contextsChanged( final List< String > selectedContexts ) if ( viewRow < 0 ) return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); + final MyTableRow row = tableModel.rows.get( modelRow ); - tableModel.contexts.set( modelRow, new ArrayList<>( selectedContexts ) ); - tableModel.fireTableCellUpdated( modelRow, 2 ); - - // Check whether we have lost some contexts known for this command. - final String command = tableModel.commands.get( modelRow ); - Map< String, String > contextMap = actionDescriptions.get( command ); - if ( null == contextMap ) - contextMap = Collections.emptyMap(); - final Set< String > missingContexts = new HashSet<>( contextMap.keySet() ); - // Brute force - for ( int i = 0; i < tableModel.commands.size(); i++ ) - { - if ( command.equals( tableModel.commands.get( i ) ) ) - missingContexts.removeAll( tableModel.contexts.get( i ) ); - } - // Recreate missing contexts as unbound line. - if ( !missingContexts.isEmpty() ) - { - final List< String > cs = new ArrayList<>( missingContexts ); - cs.sort( null ); - tableModel.commands.add( modelRow + 1, command ); - tableModel.bindings.add( modelRow + 1, InputTrigger.NOT_MAPPED ); - tableModel.contexts.add( modelRow + 1, cs ); - tableModel.fireTableRowsInserted( modelRow + 1, modelRow + 1 ); - } + tableModel.rows.set( modelRow, new MyTableRow( row.getName(), row.getTrigger(), new ArrayList<>( selectedContexts ) ) ); + tableModel.addMissingRows(); + tableBindings.getSelectionModel().setSelectionInterval( modelRow, modelRow ); // Notify listeners. notifyListeners(); @@ -857,11 +821,8 @@ public Component getTableCellRendererComponent( final JTable table, final Object setForeground( isSelected ? table.getSelectionForeground() : table.getForeground() ); setBackground( isSelected ? table.getSelectionBackground() : table.getBackground() ); final int modelRow = tableBindings.convertRowIndexToModel( row ); - final String command = tableModel.commands.get( modelRow ); - Map< String, String > contextMap = actionDescriptions.get( command ); - if ( null == contextMap ) - contextMap = Collections.emptyMap(); - setAcceptableTags( contextMap.keySet() ); + final String name = tableModel.rows.get( modelRow ).getName(); + setAcceptableTags( commandNameToAcceptableContexts.get( name ) ); @SuppressWarnings( "unchecked" ) final List< String > contexts = ( List< String > ) value; @@ -906,6 +867,47 @@ public Component getTableCellRendererComponent( final JTable table, final Object } } + private static class MyTableRow + { + private final String name; + + private final InputTrigger trigger; + + private final List< String > contexts; + + public MyTableRow( final String name, final InputTrigger trigger, final List< String > contexts ) + { + this.name = name; + this.trigger = trigger; + this.contexts = contexts; + } + + public String getName() + { + return name; + } + + public InputTrigger getTrigger() + { + return trigger; + } + + public List< String > getContexts() + { + return contexts; + } + + @Override + public String toString() + { + return "MyTableRow{" + + "name='" + name + '\'' + + ", trigger=" + trigger + + ", contexts=" + contexts + + '}'; + } + } + private static class MyTableModel extends AbstractTableModel { @@ -913,77 +915,89 @@ private static class MyTableModel extends AbstractTableModel private static final String[] TABLE_HEADERS = new String[] { "Command", "Binding", "Contexts" }; - private final List< String > commands; + private final List< MyTableRow > rows; - private final List< InputTrigger > bindings; + private final Set< Command > allCommands; - private final List< List< String > > contexts; - - public MyTableModel( final Map< String, Map< String, String > > actionDescriptions, final Map< String, Set< Input > > actionToInputsMap ) + public MyTableModel( final Set< Command > commands, final Map< String, Set< Input > > actionToInputsMap ) { - this.commands = new ArrayList<>(); - this.bindings = new ArrayList<>(); - this.contexts = new ArrayList<>(); - - final Set< String > allCommands = new HashSet<>(); - allCommands.addAll( actionDescriptions.keySet() ); - allCommands.addAll( actionToInputsMap.keySet() ); - final List< String > sortedCommands = new ArrayList<>( allCommands ); - sortedCommands.sort( null ); - final InputComparator inputComparator = new InputComparator(); - for ( final String command : sortedCommands ) + rows = new ArrayList<>(); + allCommands = commands; + for ( final Command command : commands ) { - Map< String, String > contextMap = actionDescriptions.get( command ); - if ( null == contextMap ) - contextMap = Collections.emptyMap(); - - final Set< Input > inputs = actionToInputsMap.get( command ); - if ( null == inputs ) + final Set< Input > inputs = actionToInputsMap.get( command.getName() ); + if ( null != inputs ) { - // Not found in the config. Add command with due contexts. - commands.add( command ); - bindings.add( InputTrigger.NOT_MAPPED ); - final List< String > cs = new ArrayList<>( contextMap.keySet() ); - cs.sort( null ); - contexts.add( cs ); + for ( final Input input : inputs ) + if ( input.contexts.contains( command.getContext() ) ) + rows.add( new MyTableRow( command.getName(), input.trigger, Collections.singletonList( command.getContext() ) ) ); } - else + } + addMissingRows(); + } + + /** + * Find and merge rows with the same action name and trigger, but different + * contexts. + */ + private void mergeRows() + { + final List< MyTableRow > rowsUnmerged = new ArrayList<>( rows ); + rows.clear(); + + final MyTableRowComparator comparator = new MyTableRowComparator(); + rowsUnmerged.sort( comparator ); + + for ( int i = 0; i < rowsUnmerged.size(); ) + { + final MyTableRow rowA = rowsUnmerged.get( i ); + int j = i + 1; + while ( j < rowsUnmerged.size() && comparator.compare( rowsUnmerged.get( j ), rowA ) == 0 ) + ++j; + + final Set< String > cs = new HashSet<>(); + for ( int k = i; k < j; ++k ) + cs.addAll( rowsUnmerged.get( k ).getContexts() ); + + rows.add( new MyTableRow( rowA.getName(), rowA.getTrigger(), new ArrayList<>( cs ) ) ); + + i = j; + } + + this.fireTableDataChanged(); + } + + /** + * Add missing + */ + private void addMissingRows() + { + final ArrayList< Command > missingCommands = new ArrayList<>(); + for ( final Command command : allCommands ) + { + boolean found = false; + for ( final MyTableRow row : rows ) { - // Found in the config. - final List< Input > sortedInputs = new ArrayList<>( inputs ); - sortedInputs.sort( inputComparator ); - final Set< String > usedContexts = new HashSet<>(); - for ( final Input input : sortedInputs ) - { - commands.add( command ); - bindings.add( input.trigger ); - final List< String > cs = new ArrayList<>( input.contexts ); - cs.sort( null ); - contexts.add( cs ); - usedContexts.addAll( cs ); - } - /* - * Check that we have exhausted known contexts. If not, push - * missing ones. - */ - final Set< String > missingContexts = new HashSet<>( contextMap.keySet() ); - missingContexts.removeAll( usedContexts ); - if ( !missingContexts.isEmpty() ) + if ( row.getName().equals( command.getName() ) && row.getContexts().contains( command.getContext() ) ) { - final List< String > sortedMissingContexts = new ArrayList<>( missingContexts ); - sortedMissingContexts.sort( null ); - commands.add( command ); - bindings.add( InputTrigger.NOT_MAPPED ); - contexts.add( sortedMissingContexts ); + found = true; + break; } } + if ( !found ) + missingCommands.add( command ); } + + for ( final Command command : missingCommands ) + rows.add( new MyTableRow( command.getName(), InputTrigger.NOT_MAPPED, Collections.singletonList( command.getContext() ) ) ); + + mergeRows(); } @Override public int getRowCount() { - return commands.size(); + return rows.size(); } @Override @@ -998,11 +1012,11 @@ public Object getValueAt( final int rowIndex, final int columnIndex ) switch ( columnIndex ) { case 0: - return commands.get( rowIndex ); + return rows.get( rowIndex ).getName(); case 1: - return bindings.get( rowIndex ); + return rows.get( rowIndex ).getTrigger(); case 2: - return contexts.get( rowIndex ); + return rows.get( rowIndex ).getContexts(); default: throw new NoSuchElementException( "Cannot access column " + columnIndex + " in this model." ); } @@ -1015,9 +1029,34 @@ public String getColumnName( final int column ) } } - private static final class InputComparator implements Comparator< Input > + private static final class MyTableRowComparator implements Comparator< MyTableRow > { + @Override + public int compare( final MyTableRow o1, final MyTableRow o2 ) + { + final int cn = o1.name.compareTo( o2.name ); + if ( cn != 0 ) + return cn; + + final int ct = compare( o1.trigger, o2.trigger ); +// if ( ct != 0 ) // TODO: remove + return ct; + } + + private int compare( final InputTrigger o1, final InputTrigger o2 ) + { + if ( o1 == InputTrigger.NOT_MAPPED ) + return o2 == InputTrigger.NOT_MAPPED ? 0 : 1; + if ( o2 == InputTrigger.NOT_MAPPED ) + return -1; + return o1.toString().compareTo( o2.toString() ); + } + } + + // TODO: trash? + private static final class InputComparator implements Comparator< Input > + { @Override public int compare( final Input o1, final Input o2 ) { @@ -1029,6 +1068,7 @@ public int compare( final Input o1, final Input o2 ) } } + // TODO: trash? private static final class InputTriggerComparator implements Comparator< InputTrigger > { diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java b/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java new file mode 100644 index 0000000..bf50f44 --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java @@ -0,0 +1,52 @@ +package org.scijava.ui.behaviour.io.gui; + +/** + * Behaviour or action name in a context. + */ +public class Command +{ + private final String name; + + private final String context; + + public Command( final String name, final String context ) + { + if ( name == null || context == null ) + throw new IllegalArgumentException(); + this.name = name; + this.context = context; + } + + public String getName() + { + return name; + } + + public String getContext() + { + return context; + } + + @Override + public boolean equals( final Object o ) + { + if ( this == o ) + return true; + if ( o == null || getClass() != o.getClass() ) + return false; + + final Command command = ( Command ) o; + + if ( !name.equals( command.name ) ) + return false; + return context.equals( command.context ); + } + + @Override + public int hashCode() + { + int result = name.hashCode(); + result = 31 * result + context.hashCode(); + return result; + } +} diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java index aa112ea..e4f41f2 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java @@ -7,7 +7,7 @@ /** * Utility class that is used to build a 2-level map of existing contexts -> * commands and their description. - * + * * @author Jean-Yves Tinevez * */ @@ -18,32 +18,27 @@ public class CommandDescriptionBuilder * The map of commands -> map of contexts -> description of what the command * do in a context. */ - private HashMap< String, Map< String, String > > map; + private HashMap< Command, String > map; public CommandDescriptionBuilder() { this.map = new HashMap<>(); } - public CommandDescriptionBuilder addCommand( final String command, final String context, final String description ) + public CommandDescriptionBuilder addCommand( final String name, final String context, final String description ) { - Map< String, String > contextMap = map.get( command ); - if ( contextMap == null ) - { - contextMap = new HashMap<>(); - map.put( command, contextMap ); - } - contextMap.put( context, description ); + final Command command = new Command( name, context ); + map.put( command, description ); return this; } /** * Returns the map of commands -> map of contexts -> description of what the * command does in a context. - * + * * @return a new immutable map */ - public Map< String, Map< String, String > > get() + public Map< Command, String > get() { return Collections.unmodifiableMap( map ); } diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index 0fdc74f..e704716 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -274,6 +274,12 @@ private void regenKeyPanels() repaint(); } + @Override + public boolean requestFocusInWindow() + { + return textField.requestFocusInWindow(); + } + /* * INNER CLASSES */ diff --git a/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java index ca826e5..29cb665 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java @@ -10,6 +10,7 @@ import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; +import org.scijava.ui.behaviour.io.gui.Command; import org.scijava.ui.behaviour.io.gui.CommandDescriptionBuilder; import org.scijava.ui.behaviour.io.yaml.YamlConfigIO; @@ -40,7 +41,7 @@ private static InputTriggerConfig getDemoConfig() " triggers: [shift D]" + "\n" + "- !mapping" + "\n" + " action: destroy the world" + "\n" + - " contexts: [unknown context, mamut]" + "\n" + + " contexts: [mamut]" + "\n" + " triggers: [control A]" + "\n" + "" ); final List< InputTriggerDescription > triggers = YamlConfigIO.read( reader ); @@ -48,7 +49,7 @@ private static InputTriggerConfig getDemoConfig() return config; } - private static Map< String, Map< String, String > > getDemoCommands() + private static Map< Command, String > getDemoCommands() { return new CommandDescriptionBuilder() .addCommand( "drag1", "mamut", "Move an item around the editor." ) From abbc6f3f079a78b2bbc4c97e1a8f5f8e4ebbb7d6 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 6 Dec 2017 21:17:00 +0100 Subject: [PATCH 081/184] WIP: fixing visual editor --- .../ui/behaviour/io/VisualEditorPanel.java | 192 ++++++++++++++---- 1 file changed, 153 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index a02df4d..d1991e3 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -95,6 +95,8 @@ public static interface ConfigChangeListener private MyTableModel tableModel; + private boolean blockRemoveNotMapped = false; + private final InputTriggerPanelEditor keybindingEditor; private final TagPanelEditor contextsEditor; @@ -362,6 +364,29 @@ public void valueChanged( final ListSelectionEvent e ) updateEditors(); } } ); + tableBindings.getSelectionModel().addListSelectionListener( new ListSelectionListener() + { + @Override + public void valueChanged( final ListSelectionEvent e ) + { + if ( e.getValueIsAdjusting() ) + return; + + if ( blockRemoveNotMapped ) + { + blockRemoveNotMapped = false; + return; + } + + final MyTableRow selectedRowToRestore = tableModel.rows.get( e.getFirstIndex() ); + if ( !tableModel.removeSuperfluousNotMapped() ) + return; + + final int bs = Collections.binarySearch( tableModel.rows, selectedRowToRestore, new MyTableRowComparator() ); + final int vbs = tableBindings.convertRowIndexToView( bs ); + tableBindings.getSelectionModel().setSelectionInterval( vbs, vbs ); + } + } ); tableBindings.setFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null ); tableBindings.setFocusTraversalKeys( KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null ); @@ -639,11 +664,11 @@ private void unbindCommand() { final MyTableRow newRow = new MyTableRow( removedRow.getName(), InputTrigger.NOT_MAPPED, new ArrayList<>( contextsToAddBack ) ); tableModel.rows.add( modelRow, newRow ); -// tableModel.fireTableRowsUpdated( modelRow, modelRow ); -// } -// else -// { -// tableModel.fireTableRowsDeleted( modelRow, modelRow ); + tableModel.fireTableRowsUpdated( modelRow, modelRow ); + } + else + { + tableModel.fireTableRowsDeleted( modelRow, modelRow ); } tableModel.mergeRows(); @@ -702,8 +727,11 @@ private void copyCommand() final List< String > cs = row.getContexts(); final MyTableRow copiedRow = new MyTableRow( action, InputTrigger.NOT_MAPPED, new ArrayList<>( cs ) ); tableModel.rows.add( modelRow + 1, copiedRow ); - tableModel.mergeRows(); + blockRemoveNotMapped = true; + if ( !tableModel.mergeRows() ) + tableModel.fireTableRowsInserted( modelRow + 1, modelRow + 1 ); + blockRemoveNotMapped = true; // Find the row we just added if any. final int modelRowToSelect = Collections.binarySearch( tableModel.rows, copiedRow, new MyTableRowComparator() ); final int rowToSelect; @@ -716,30 +744,6 @@ private void copyCommand() // Notify listeners. notifyListeners(); - // Listener to avoid having duplicates with NOT_MAPPED. If the user don't edit it, we remove it. - final ListSelectionListener lsl = new ListSelectionListener() - { - @Override - public void valueChanged( final ListSelectionEvent e ) - { - if ( e.getValueIsAdjusting() ) - return; - - tableBindings.getSelectionModel().removeListSelectionListener( this ); - final MyTableRow selectedRowToRestore = tableModel.rows.get( e.getFirstIndex() ); - final int modelRowToRemove = Collections.binarySearch( tableModel.rows, copiedRow, new MyTableRowComparator() ); - if ( modelRowToRemove >= 0 ) - { - tableModel.rows.remove( modelRowToRemove ); - tableModel.addMissingRows(); - } - - final int bs = Collections.binarySearch( tableModel.rows, selectedRowToRestore, new MyTableRowComparator() ); - final int vbs = tableBindings.convertRowIndexToView( bs ); - tableBindings.getSelectionModel().setSelectionInterval( vbs, vbs ); - } - }; - tableBindings.getSelectionModel().addListSelectionListener( lsl ); keybindingEditor.requestFocusInWindow(); } @@ -753,7 +757,8 @@ private void keybindingsChanged( final InputTrigger inputTrigger ) final MyTableRow updatedRow = new MyTableRow( row.getName(), inputTrigger, row.getContexts() ); tableModel.rows.set( modelRow, updatedRow ); - tableModel.mergeRows(); + if ( !tableModel.mergeRows() ) + tableModel.fireTableRowsUpdated( modelRow, modelRow ); lookForConflicts(); final int modelRowToSelect = Collections.binarySearch( tableModel.rows, updatedRow, new MyTableRowComparator() ); @@ -777,7 +782,8 @@ private void contextsChanged( final List< String > selectedContexts ) final MyTableRow row = tableModel.rows.get( modelRow ); tableModel.rows.set( modelRow, new MyTableRow( row.getName(), row.getTrigger(), new ArrayList<>( selectedContexts ) ) ); - tableModel.addMissingRows(); + if ( !tableModel.addMissingRows() ) + tableModel.fireTableRowsUpdated( modelRow, modelRow ); tableBindings.getSelectionModel().setSelectionInterval( modelRow, modelRow ); // Notify listeners. @@ -897,6 +903,32 @@ public List< String > getContexts() return contexts; } + @Override + public boolean equals( final Object o ) + { + if ( this == o ) + return true; + if ( o == null || getClass() != o.getClass() ) + return false; + + final MyTableRow that = ( MyTableRow ) o; + + if ( !name.equals( that.name ) ) + return false; + if ( !trigger.equals( that.trigger ) ) + return false; + return contexts.equals( that.contexts ); + } + + @Override + public int hashCode() + { + int result = name.hashCode(); + result = 31 * result + trigger.hashCode(); + result = 31 * result + contexts.hashCode(); + return result; + } + @Override public String toString() { @@ -937,10 +969,68 @@ public MyTableModel( final Set< Command > commands, final Map< String, Set< Inpu } /** - * Find and merge rows with the same action name and trigger, but different - * contexts. + * Find and remove rows with trigger NOT_MAPPED. + */ + public void removeAllNotMapped( final List< MyTableRow > rows ) + { + final Iterator< MyTableRow > iter = rows.iterator(); + while ( iter.hasNext() ) + { + final MyTableRow row = iter.next(); + if ( row.getTrigger().equals( InputTrigger.NOT_MAPPED ) ) + iter.remove(); + } + } + + /** + * Find and remove table rows with trigger {@code NOT_MAPPED}, whose + * name and contexts are covered by other rows (that map to other + * triggers). + * + * If any changes are made, {@code fireTableDataChanged} is fired. + * + * @return true, if changes were made. + */ + public boolean removeSuperfluousNotMapped() + { + final ArrayList< MyTableRow > copy = new ArrayList<>( rows ); + removeAllNotMapped( rows ); + addMissingRows( rows ); + if ( !copy.equals( rows ) ) + { + this.fireTableDataChanged(); + return true; + } + return false; + } + + /** + * Find and merge table rows with the same action name and trigger, but + * different contexts. + * + * If any changes are made, {@code fireTableDataChanged} is fired. + * + * @return true, if changes were made. */ - private void mergeRows() + private boolean mergeRows() + { + final ArrayList< MyTableRow > copy = new ArrayList<>( rows ); + mergeRows( rows ); + if ( !copy.equals( rows ) ) + { + this.fireTableDataChanged(); + return true; + } + return false; + } + + /** + * In the given list of {@code rows}, find and merge rows with the same + * action name and trigger, but different contexts. + * + * @param rows list of rows to modify. + */ + private void mergeRows( final List< MyTableRow > rows ) { final List< MyTableRow > rowsUnmerged = new ArrayList<>( rows ); rows.clear(); @@ -963,14 +1053,38 @@ private void mergeRows() i = j; } + } - this.fireTableDataChanged(); + /** + * Add {@code NOT_MAPPED} rows for (name, context) pairs in + * {@link #allCommands} that are not otherwise covered. Then + * {@link #mergeRows()}. + * + * If any changes are made, {@code fireTableDataChanged} is fired. + * + * @return true, if changes were made. + */ + private boolean addMissingRows() + { + final ArrayList< MyTableRow > copy = new ArrayList<>( rows ); + addMissingRows( rows ); + if ( !copy.equals( rows ) ) + { + this.fireTableDataChanged(); + return true; + } + return false; } /** - * Add missing + * In the given list of {@code rows}, add {@code NOT_MAPPED} rows for + * (name, context) pairs in {@link #allCommands} that are not otherwise + * covered. Then {@link #mergeRows(List)}. + * + * @param rows + * list of rows to modify. */ - private void addMissingRows() + private void addMissingRows( final List< MyTableRow > rows ) { final ArrayList< Command > missingCommands = new ArrayList<>(); for ( final Command command : allCommands ) @@ -991,7 +1105,7 @@ private void addMissingRows() for ( final Command command : missingCommands ) rows.add( new MyTableRow( command.getName(), InputTrigger.NOT_MAPPED, Collections.singletonList( command.getContext() ) ) ); - mergeRows(); + mergeRows( rows ); } @Override From fa5a702a7c3f9b09b1f895520b359db74a69a2f2 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 6 Dec 2017 21:52:26 +0100 Subject: [PATCH 082/184] WIP: visual editor bugfixing --- .../scijava/ui/behaviour/io/VisualEditorPanel.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index d1991e3..80c8d97 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -378,11 +378,16 @@ public void valueChanged( final ListSelectionEvent e ) return; } - final MyTableRow selectedRowToRestore = tableModel.rows.get( e.getFirstIndex() ); + final int selIndex = tableBindings.getSelectionModel().getMinSelectionIndex(); + if ( selIndex < 0 ) + return; + final MyTableRow selectedRowToRestore = tableModel.rows.get( selIndex ); if ( !tableModel.removeSuperfluousNotMapped() ) return; final int bs = Collections.binarySearch( tableModel.rows, selectedRowToRestore, new MyTableRowComparator() ); + if ( bs < 0 ) + return; final int vbs = tableBindings.convertRowIndexToView( bs ); tableBindings.getSelectionModel().setSelectionInterval( vbs, vbs ); } @@ -763,8 +768,8 @@ private void keybindingsChanged( final InputTrigger inputTrigger ) final int modelRowToSelect = Collections.binarySearch( tableModel.rows, updatedRow, new MyTableRowComparator() ); final int rowToSelect; - if (modelRowToSelect < 0) - rowToSelect = tableBindings.convertRowIndexToView( modelRow ); + if ( modelRowToSelect < 0 ) + rowToSelect = tableBindings.convertRowIndexToView( modelRow ); else rowToSelect = tableBindings.convertRowIndexToView( modelRowToSelect ); tableBindings.getSelectionModel().setSelectionInterval( rowToSelect, rowToSelect ); From e5ec9dae8f111cd78311cefa4e541d3edf096e66 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 6 Dec 2017 22:13:55 +0100 Subject: [PATCH 083/184] more bugfixes --- .../ui/behaviour/io/VisualEditorPanel.java | 55 +++---------------- 1 file changed, 7 insertions(+), 48 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 80c8d97..817720b 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -655,31 +655,9 @@ private void unbindCommand() if ( viewRow < 0 ) return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - final MyTableRow removedRow = tableModel.rows.remove( modelRow ); - - final Set< String > contextsStillPresent = new HashSet<>(); - for ( final MyTableRow row : tableModel.rows ) - if ( row.getName().equals( removedRow.getName() ) ) - contextsStillPresent.addAll( row.getContexts() ); - - final Set< String > contextsToAddBack = new HashSet<>( removedRow.getContexts() ); - contextsToAddBack.removeAll( contextsStillPresent ); - - if ( !contextsToAddBack.isEmpty() ) - { - final MyTableRow newRow = new MyTableRow( removedRow.getName(), InputTrigger.NOT_MAPPED, new ArrayList<>( contextsToAddBack ) ); - tableModel.rows.add( modelRow, newRow ); - tableModel.fireTableRowsUpdated( modelRow, modelRow ); - } - else - { + tableModel.rows.remove( modelRow ); + if ( !tableModel.addMissingRows() ) tableModel.fireTableRowsDeleted( modelRow, modelRow ); - } - - tableModel.mergeRows(); - - final int rowToSelect = Math.min( tableBindings.convertRowIndexToView( modelRow ), tableModel.getRowCount() - 1); - tableBindings.getSelectionModel().setSelectionInterval( rowToSelect, rowToSelect ); } private void unbindAllCommand() @@ -688,36 +666,16 @@ private void unbindAllCommand() if ( viewRow < 0 ) return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); - final MyTableRow removedRow = tableModel.rows.remove( modelRow ); - final HashSet< String > contextsToAddBack = new HashSet<>( removedRow.getContexts() ); - + final String removeName = tableModel.rows.get( modelRow ).getName(); final Iterator< MyTableRow > iter = tableModel.rows.iterator(); while( iter.hasNext() ) { final MyTableRow row = iter.next(); - if ( row.getName().equals( removedRow.getName() ) ) - { - contextsToAddBack.addAll( row.getContexts() ); + if ( row.getName().equals( removeName ) ) iter.remove(); - } } - - final Set< String > contextsStillPresent = new HashSet<>(); - for ( final MyTableRow row : tableModel.rows ) - if ( row.getName().equals( removedRow.getName() ) ) - contextsStillPresent.addAll( row.getContexts() ); - - contextsToAddBack.removeAll( contextsStillPresent ); - if ( !contextsToAddBack.isEmpty() ) - { - final MyTableRow newRow = new MyTableRow( removedRow.getName(), InputTrigger.NOT_MAPPED, new ArrayList<>( contextsToAddBack ) ); - tableModel.rows.add( modelRow, newRow ); - } - - tableModel.mergeRows(); - - final int rowToSelect = Math.min( tableBindings.convertRowIndexToView( modelRow ), tableModel.getRowCount() - 1 ); - tableBindings.getSelectionModel().setSelectionInterval( rowToSelect, rowToSelect ); + if ( !tableModel.addMissingRows() ) + tableModel.fireTableDataChanged(); } private void copyCommand() @@ -772,6 +730,7 @@ private void keybindingsChanged( final InputTrigger inputTrigger ) rowToSelect = tableBindings.convertRowIndexToView( modelRow ); else rowToSelect = tableBindings.convertRowIndexToView( modelRowToSelect ); + blockRemoveNotMapped = true; tableBindings.getSelectionModel().setSelectionInterval( rowToSelect, rowToSelect ); // Notify listeners. From b183d573b84ddcde8c53b428e341a352fda19405 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Thu, 7 Dec 2017 10:33:18 +0100 Subject: [PATCH 084/184] Remove unused fields and classes. --- .../ui/behaviour/io/VisualEditorPanel.java | 26 +++---------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 817720b..c814af9 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -21,7 +21,6 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; -import java.util.stream.Collectors; import javax.swing.Box; import javax.swing.BoxLayout; @@ -80,7 +79,7 @@ public boolean accept( final File f ) /** * Interface for listeners notified when settings are changed in the visual - * editor.`` + * editor. */ @FunctionalInterface public static interface ConfigChangeListener @@ -113,8 +112,6 @@ public static interface ConfigChangeListener private final Map< Command, String > actionDescriptions; - private final Set< String > contexts; // TODO: do we need it? - private final JLabel lblConflict; private JTextArea textAreaDescription; @@ -151,7 +148,6 @@ public VisualEditorPanel( final InputTriggerConfig config, final Map< Command, S commandNameToAcceptableContexts = new HashMap<>(); for ( final Command command : commands ) commandNameToAcceptableContexts.computeIfAbsent( command.getName(), k -> new HashSet<>() ).add( command.getContext() ); - this.contexts = commands.stream().map( c -> c.getContext() ).collect( Collectors.toSet() ); // TODO: do we need it? this.listeners = new HashSet<>(); /* @@ -276,7 +272,7 @@ public void changedUpdate( final DocumentEvent e ) gbc_lblContext.gridy = 2; panelCommandEditor.add( lblContext, gbc_lblContext ); - this.contextsEditor = new TagPanelEditor( contexts ); + this.contextsEditor = new TagPanelEditor( Collections.emptyList() ); final GridBagConstraints gbc_comboBoxContext = new GridBagConstraints(); gbc_comboBoxContext.insets = new Insets( 5, 5, 5, 5 ); gbc_comboBoxContext.fill = GridBagConstraints.BOTH; @@ -510,7 +506,7 @@ public void configToModel() tableBindings.setModel( tableModel ); // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); - tableBindings.getColumnModel().getColumn( 2 ).setCellRenderer( new MyContextsRenderer( contexts ) ); + tableBindings.getColumnModel().getColumn( 2 ).setCellRenderer( new MyContextsRenderer( Collections.emptyList() ) ); tableBindings.getSelectionModel().setSelectionInterval( 0, 0 ); // Notify listeners. @@ -1131,22 +1127,6 @@ private int compare( final InputTrigger o1, final InputTrigger o2 ) } } - - // TODO: trash? - private static final class InputComparator implements Comparator< Input > - { - @Override - public int compare( final Input o1, final Input o2 ) - { - if ( o1.trigger == InputTrigger.NOT_MAPPED ) - return 1; - if ( o2.trigger == InputTrigger.NOT_MAPPED ) - return -1; - return o1.trigger.toString().compareTo( o2.trigger.toString() ); - } - } - - // TODO: trash? private static final class InputTriggerComparator implements Comparator< InputTrigger > { From 8f69c1ab75a2d2ecf02f6dd7511f561f140d3ea9 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Thu, 7 Dec 2017 10:33:35 +0100 Subject: [PATCH 085/184] Put back the CSV export. Let's not even discuss whether it is useful. --- .../ui/behaviour/io/VisualEditorPanel.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index c814af9..faa3576 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -10,6 +10,8 @@ import java.awt.Insets; import java.awt.KeyboardFocusManager; import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -27,6 +29,7 @@ import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; @@ -540,7 +543,6 @@ private void filterRows() private void exportToCsv() { - /* final int userSignal = fileChooser.showSaveDialog( this ); if ( userSignal != JFileChooser.APPROVE_OPTION ) return; @@ -566,13 +568,13 @@ private void exportToCsv() sb.append( MyTableModel.TABLE_HEADERS[ 2 ] ); sb.append( '\n' ); - for ( int i = 0; i < tableModel.commands.size(); i++ ) + for ( int i = 0; i < tableModel.getRowCount(); i++ ) { - sb.append( tableModel.commands.get( i ) ); + sb.append( tableModel.rows.get( i ).getName() ); sb.append( CSV_SEPARATOR + '\t' ); - sb.append( tableModel.bindings.get( i ).toString() ); + sb.append( tableModel.rows.get( i ).getTrigger().toString() ); sb.append( CSV_SEPARATOR + '\t' ); - final List< String > contexts = tableModel.contexts.get( i ); + final List< String > contexts = tableModel.rows.get( i ).getContexts(); if ( !contexts.isEmpty() ) { sb.append( contexts.get( 0 ) ); @@ -593,7 +595,6 @@ private void exportToCsv() JOptionPane.showMessageDialog( fileChooser, "Error writing file:\n" + e.getMessage(), "Error writing file.", JOptionPane.ERROR_MESSAGE ); e.printStackTrace(); } - */ } private void updateEditors() @@ -1112,9 +1113,7 @@ public int compare( final MyTableRow o1, final MyTableRow o2 ) if ( cn != 0 ) return cn; - final int ct = compare( o1.trigger, o2.trigger ); -// if ( ct != 0 ) // TODO: remove - return ct; + return compare( o1.trigger, o2.trigger ); } private int compare( final InputTrigger o1, final InputTrigger o2 ) From 827b3011170252f856e00f55617f52ec87b2f60f Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Thu, 7 Dec 2017 10:47:32 +0100 Subject: [PATCH 086/184] Revise conflicts detection. --- .../ui/behaviour/io/VisualEditorPanel.java | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index faa3576..00ce4ca 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -431,36 +431,48 @@ private void lookForConflicts() { lblConflict.setText( "" ); - // TODO: revise - /* final int viewRow = tableBindings.getSelectedRow(); if ( viewRow < 0 ) return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); lblConflict.setText( "" ); - final InputTrigger inputTrigger = tableModel.bindings.get( modelRow ); + final InputTrigger inputTrigger = tableModel.rows.get( modelRow ).getTrigger(); if ( inputTrigger == InputTrigger.NOT_MAPPED ) return; + final List< String > contexts = tableModel.rows.get( modelRow ).getContexts(); final ArrayList< String > conflicts = new ArrayList<>(); - for ( int i = 0; i < tableModel.commands.size(); i++ ) + for ( int i = 0; i < tableModel.getRowCount(); i++ ) { if ( i == modelRow ) continue; - if ( tableModel.bindings.get( i ).equals( inputTrigger ) ) - conflicts.add( tableModel.commands.get( i ) ); + if ( tableModel.rows.get( i ).getTrigger().equals( inputTrigger ) ) + { + // Same trigger. Check if contexts overlap. + final List< String > overlappingContexts = new ArrayList<>( tableModel.rows.get( i ).getContexts() ); + overlappingContexts.retainAll( contexts ); + if ( !overlappingContexts.isEmpty() ) + { + final StringBuilder str = new StringBuilder(); + str.append( tableModel.rows.get( i ).getName() ); + str.append( " in " + overlappingContexts.get( 0 ) ); + for ( int j = 1; j < overlappingContexts.size(); j++ ) + str.append( ", " + overlappingContexts.get( j ) ); + + conflicts.add( str.toString() ); + } + } } if ( !conflicts.isEmpty() ) { final StringBuilder str = new StringBuilder( conflicts.get( 0 ) ); for ( int i = 1; i < conflicts.size(); i++ ) - str.append( ", " + conflicts.get( i ) ); + str.append( "; " + conflicts.get( i ) ); lblConflict.setText( str.toString() ); } - */ } public void setButtonPanelVisible( final boolean visible ) From aa6b26d0ae9824233d8717ee355e580c1755b3fc Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 7 Dec 2017 11:41:28 +0100 Subject: [PATCH 087/184] javadoc --- .../io/gui/CommandDescriptionBuilder.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java index e4f41f2..02422eb 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java @@ -5,20 +5,18 @@ import java.util.Map; /** - * Utility class that is used to build a 2-level map of existing contexts -> - * commands and their description. + * Utility class that is used to build a map of {@link Command}s to their + * description. * * @author Jean-Yves Tinevez - * */ public class CommandDescriptionBuilder { /** - * The map of commands -> map of contexts -> description of what the command - * do in a context. + * The map of {@link Command} to description of what the command does. */ - private HashMap< Command, String > map; + private final HashMap< Command, String > map; public CommandDescriptionBuilder() { @@ -33,8 +31,8 @@ public CommandDescriptionBuilder addCommand( final String name, final String con } /** - * Returns the map of commands -> map of contexts -> description of what the - * command does in a context. + * Returns the map of {@link Command} to description of what the command + * does. * * @return a new immutable map */ From 9fc66689b6c5d47566579f3d45404726da3be87a Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Thu, 7 Dec 2017 11:45:28 +0100 Subject: [PATCH 088/184] Columns can now be sorted on a click on the header. --- .../ui/behaviour/io/VisualEditorPanel.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 00ce4ca..6ad450b 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -129,6 +129,8 @@ public static interface ConfigChangeListener private final JButton btnRestore; + private TableRowSorter< MyTableModel > tableRowSorter; + /** * Creates a visual editor for an {@link InputTriggerConfig}. The config * object is directly modified when the user clicks the 'Apply' button. @@ -425,6 +427,10 @@ public void configChanged() configToModel(); scrollPane.setViewportView( tableBindings ); + + this.tableRowSorter = new TableRowSorter<>( tableModel ); + tableRowSorter.setComparator( 1, new InputTriggerComparator() ); + tableBindings.setRowSorter( tableRowSorter ); } private void lookForConflicts() @@ -533,9 +539,6 @@ public void configToModel() private void filterRows() { - final TableRowSorter< MyTableModel > tableRowSorter = new TableRowSorter<>( tableModel ); - tableRowSorter.setComparator( 1, new InputTriggerComparator() ); - tableBindings.setRowSorter( tableRowSorter ); RowFilter< MyTableModel, Integer > rf = null; try { @@ -754,13 +757,20 @@ private void contextsChanged( final List< String > selectedContexts ) final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); final MyTableRow row = tableModel.rows.get( modelRow ); - tableModel.rows.set( modelRow, new MyTableRow( row.getName(), row.getTrigger(), new ArrayList<>( selectedContexts ) ) ); + final List< String > newContexts = new ArrayList<>( selectedContexts ); + newContexts.sort( null ); + tableModel.rows.set( modelRow, new MyTableRow( row.getName(), row.getTrigger(), newContexts ) ); if ( !tableModel.addMissingRows() ) tableModel.fireTableRowsUpdated( modelRow, modelRow ); - tableBindings.getSelectionModel().setSelectionInterval( modelRow, modelRow ); // Notify listeners. notifyListeners(); + + // Select proper row again (might have sorted differently now). + final int viewRowToSelect = tableBindings.convertRowIndexToView( modelRow ); + if ( viewRowToSelect < 0 ) + return; + tableBindings.getSelectionModel().setSelectionInterval( viewRowToSelect, viewRowToSelect ); } private void notifyListeners() From 860f3baa4d80f383febf19bff933410b8d16c2d4 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 7 Dec 2017 11:58:12 +0100 Subject: [PATCH 089/184] Do not use InputTriggerConfig.Input class --- .../ui/behaviour/io/VisualEditorPanel.java | 31 +++---------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index 817720b..ea9639f 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -46,7 +46,6 @@ import javax.swing.table.TableRowSorter; import org.scijava.ui.behaviour.InputTrigger; -import org.scijava.ui.behaviour.io.InputTriggerConfig.Input; import org.scijava.ui.behaviour.io.gui.Command; import org.scijava.ui.behaviour.io.gui.CommandDescriptionBuilder; import org.scijava.ui.behaviour.io.gui.InputTriggerPanelEditor; @@ -506,7 +505,7 @@ public void modelToConfig() public void configToModel() { - tableModel = new MyTableModel( commands, config.actionToInputsMap ); + tableModel = new MyTableModel( commands, config ); tableBindings.setModel( tableModel ); // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); @@ -915,19 +914,15 @@ private static class MyTableModel extends AbstractTableModel private final Set< Command > allCommands; - public MyTableModel( final Set< Command > commands, final Map< String, Set< Input > > actionToInputsMap ) + public MyTableModel( final Set< Command > commands, final InputTriggerConfig config ) { rows = new ArrayList<>(); allCommands = commands; for ( final Command command : commands ) { - final Set< Input > inputs = actionToInputsMap.get( command.getName() ); - if ( null != inputs ) - { - for ( final Input input : inputs ) - if ( input.contexts.contains( command.getContext() ) ) - rows.add( new MyTableRow( command.getName(), input.trigger, Collections.singletonList( command.getContext() ) ) ); - } + final Set< InputTrigger > inputs = config.getInputs( command.getName(), Collections.singleton( command.getContext() ) ); + for ( final InputTrigger input : inputs ) + rows.add( new MyTableRow( command.getName(), input, Collections.singletonList( command.getContext() ) ) ); } addMissingRows(); } @@ -1131,25 +1126,9 @@ private int compare( final InputTrigger o1, final InputTrigger o2 ) } } - - // TODO: trash? - private static final class InputComparator implements Comparator< Input > - { - @Override - public int compare( final Input o1, final Input o2 ) - { - if ( o1.trigger == InputTrigger.NOT_MAPPED ) - return 1; - if ( o2.trigger == InputTrigger.NOT_MAPPED ) - return -1; - return o1.trigger.toString().compareTo( o2.trigger.toString() ); - } - } - // TODO: trash? private static final class InputTriggerComparator implements Comparator< InputTrigger > { - @Override public int compare( final InputTrigger o1, final InputTrigger o2 ) { From 88874588e7e1869b4a8bbc3e4aaef75e4fb8525a Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 7 Dec 2017 12:14:02 +0100 Subject: [PATCH 090/184] Clean up API: * Use Collection over Set/List where it makes sense. * Make copies inside constructors rather then outside. * Accept single argument and wrap as singleton set/list where convenient. --- .../ui/behaviour/io/InputTriggerConfig.java | 45 +++++++++++-------- .../ui/behaviour/io/VisualEditorPanel.java | 37 +++++++-------- 2 files changed, 45 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 5724e5c..a85bb45 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -37,8 +37,10 @@ import java.util.LinkedHashSet; import java.util.Map.Entry; import java.util.Set; + import javax.swing.InputMap; import javax.swing.KeyStroke; + import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.InputTriggerAdder; import org.scijava.ui.behaviour.InputTriggerMap; @@ -71,7 +73,7 @@ public InputTriggerConfig( final Collection< InputTriggerDescription > keyMappin final InputTrigger trigger = InputTrigger.getFromString( triggerStr ); final Input input = new Input( trigger, behaviour, contexts ); - Set< Input > inputs = actionToInputsMap.computeIfAbsent( input.behaviour, k -> new LinkedHashSet<>() ); + final Set< Input > inputs = actionToInputsMap.computeIfAbsent( input.behaviour, k -> new LinkedHashSet<>() ); inputs.add( input ); } } @@ -89,6 +91,24 @@ public KeyStrokeAdder keyStrokeAdder( final InputMap map, final String ... conte return new KeyStrokeAdderImp( map, this, contexts ); } + public Set< InputTrigger > getInputs( final String behaviourName, final String context ) + { + return getInputs( behaviourName, Collections.singleton( context ) ); + } + + public Set< InputTrigger > getInputs( final String behaviourName, final Set< String > contexts ) + { + final Set< Input > inputs = actionToInputsMap.get( behaviourName ); + final Set< InputTrigger > triggers = new LinkedHashSet<>(); + if ( inputs != null ) + { + for ( final Input input : inputs ) + if ( ! Collections.disjoint( contexts, input.contexts ) ) + triggers.add( input.trigger ); + } + return triggers; + } + public static class InputTriggerAdderImp implements InputTriggerAdder { private final InputTriggerMap map; @@ -303,7 +323,7 @@ static class Input Input( final InputTrigger trigger, final String behaviour, - final Set< String > contexts ) + final Collection< String > contexts ) { this.trigger = trigger; this.behaviour = behaviour; @@ -335,19 +355,6 @@ InputTriggerDescription getDescription() } } - public Set< InputTrigger > getInputs( final String behaviourName, final Set< String > contexts ) - { - final Set< Input > inputs = actionToInputsMap.get( behaviourName ); - final Set< InputTrigger > triggers = new LinkedHashSet<>(); - if ( inputs != null ) - { - for ( final Input input : inputs ) - if ( ! Collections.disjoint( contexts, input.contexts ) ) - triggers.add( input.trigger ); - } - return triggers; - } - void clear() { actionToInputsMap.clear(); @@ -363,9 +370,9 @@ void add( final InputTrigger trigger, final String behaviourName, final String c add( trigger, behaviourName, Collections.singleton( context ) ); } - synchronized void add( final InputTrigger trigger, final String behaviourName, final Set< String > contexts ) + synchronized void add( final InputTrigger trigger, final String behaviourName, final Collection< String > contexts ) { - Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); + final Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); for ( final Input input : inputs ) { if ( input.trigger.equals( trigger ) ) @@ -399,7 +406,7 @@ void addMap( final InputTriggerMap map, final String context ) for ( final String behaviourName : behaviours ) { - Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); + final Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); boolean added = false; for ( final Input input : inputs ) @@ -435,7 +442,7 @@ void addMap( final InputMap map, final String context ) final InputTrigger trigger = InputTrigger.getFromString( key.toString() ); final String behaviourName = map.get( key ).toString(); - Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); + final Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); boolean added = false; for ( final Input input : inputs ) diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java index ea9639f..651ddb7 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java @@ -486,17 +486,15 @@ public void modelToConfig() continue; final String action = row.getName(); - final Set< String > cs = new HashSet<>( row.getContexts() ); - config.add( inputTrigger, action, cs ); + config.add( inputTrigger, action, row.getContexts() ); } // fill in InputTrigger.NOT_MAPPED for any action that doesn't have any input for ( final Command command : commands ) { final String action = command.getName(); - final Set< String > cs = Collections.singleton( command.getContext() ); - if ( config.getInputs( action, cs ).isEmpty() ) - config.add( InputTrigger.NOT_MAPPED, action, cs ); + if ( config.getInputs( action, command.getContext() ).isEmpty() ) + config.add( InputTrigger.NOT_MAPPED, action, command.getContext() ); } btnApply.setEnabled( false ); @@ -615,7 +613,7 @@ private void updateEditors() final MyTableRow row = tableModel.rows.get( modelRow ); final String action = row.getName(); final InputTrigger trigger = row.getTrigger(); - final List< String > contexts = new ArrayList<>( row.getContexts() ); + final List< String > contexts = row.getContexts(); final String description; final Set< String > acceptableContexts = commandNameToAcceptableContexts.get( action ); @@ -685,9 +683,7 @@ private void copyCommand() final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); final MyTableRow row = tableModel.rows.get( modelRow ); - final String action = row.getName(); - final List< String > cs = row.getContexts(); - final MyTableRow copiedRow = new MyTableRow( action, InputTrigger.NOT_MAPPED, new ArrayList<>( cs ) ); + final MyTableRow copiedRow = new MyTableRow( row.getName(), InputTrigger.NOT_MAPPED, row.getContexts() ); tableModel.rows.add( modelRow + 1, copiedRow ); blockRemoveNotMapped = true; if ( !tableModel.mergeRows() ) @@ -744,7 +740,7 @@ private void contextsChanged( final List< String > selectedContexts ) final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); final MyTableRow row = tableModel.rows.get( modelRow ); - tableModel.rows.set( modelRow, new MyTableRow( row.getName(), row.getTrigger(), new ArrayList<>( selectedContexts ) ) ); + tableModel.rows.set( modelRow, new MyTableRow( row.getName(), row.getTrigger(), selectedContexts ) ); if ( !tableModel.addMissingRows() ) tableModel.fireTableRowsUpdated( modelRow, modelRow ); tableBindings.getSelectionModel().setSelectionInterval( modelRow, modelRow ); @@ -844,11 +840,16 @@ private static class MyTableRow private final List< String > contexts; - public MyTableRow( final String name, final InputTrigger trigger, final List< String > contexts ) + public MyTableRow( final String name, final InputTrigger trigger, final String context ) + { + this( name, trigger, Collections.singletonList( context ) ); + } + + public MyTableRow( final String name, final InputTrigger trigger, final Collection< String > contexts ) { this.name = name; this.trigger = trigger; - this.contexts = contexts; + this.contexts = new ArrayList<>( contexts ); } public String getName() @@ -920,9 +921,9 @@ public MyTableModel( final Set< Command > commands, final InputTriggerConfig con allCommands = commands; for ( final Command command : commands ) { - final Set< InputTrigger > inputs = config.getInputs( command.getName(), Collections.singleton( command.getContext() ) ); + final Set< InputTrigger > inputs = config.getInputs( command.getName(), command.getContext() ); for ( final InputTrigger input : inputs ) - rows.add( new MyTableRow( command.getName(), input, Collections.singletonList( command.getContext() ) ) ); + rows.add( new MyTableRow( command.getName(), input, command.getContext() ) ); } addMissingRows(); } @@ -1004,11 +1005,11 @@ private void mergeRows( final List< MyTableRow > rows ) while ( j < rowsUnmerged.size() && comparator.compare( rowsUnmerged.get( j ), rowA ) == 0 ) ++j; - final Set< String > cs = new HashSet<>(); + final Set< String > contexts = new HashSet<>(); for ( int k = i; k < j; ++k ) - cs.addAll( rowsUnmerged.get( k ).getContexts() ); + contexts.addAll( rowsUnmerged.get( k ).getContexts() ); - rows.add( new MyTableRow( rowA.getName(), rowA.getTrigger(), new ArrayList<>( cs ) ) ); + rows.add( new MyTableRow( rowA.getName(), rowA.getTrigger(), contexts ) ); i = j; } @@ -1062,7 +1063,7 @@ private void addMissingRows( final List< MyTableRow > rows ) } for ( final Command command : missingCommands ) - rows.add( new MyTableRow( command.getName(), InputTrigger.NOT_MAPPED, Collections.singletonList( command.getContext() ) ) ); + rows.add( new MyTableRow( command.getName(), InputTrigger.NOT_MAPPED, command.getContext() ) ); mergeRows( rows ); } From 45970b3bfee7377859e6bd2243ad51a8b5141d29 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 7 Dec 2017 12:31:35 +0100 Subject: [PATCH 091/184] Make InputTriggerConfig clear/add public, move VisualEditorPanel to gui package --- .../ui/behaviour/io/InputTriggerConfig.java | 76 +++++++++---------- .../io/{ => gui}/VisualEditorPanel.java | 7 +- .../io/{ => gui}/VisualEditorPanelDemo.java | 5 +- 3 files changed, 44 insertions(+), 44 deletions(-) rename src/main/java/org/scijava/ui/behaviour/io/{ => gui}/VisualEditorPanel.java (99%) rename src/test/java/org/scijava/ui/behaviour/io/{ => gui}/VisualEditorPanelDemo.java (94%) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index a85bb45..4ccfbfb 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -109,6 +109,44 @@ public Set< InputTrigger > getInputs( final String behaviourName, final Set< Str return triggers; } + public void clear() + { + actionToInputsMap.clear(); + } + + public void add( final String trigger, final String behaviourName, final String context ) + { + add( InputTrigger.getFromString( trigger ), behaviourName, context ); + } + + public void add( final InputTrigger trigger, final String behaviourName, final String context ) + { + add( trigger, behaviourName, Collections.singleton( context ) ); + } + + public synchronized void add( final InputTrigger trigger, final String behaviourName, final Collection< String > contexts ) + { + final Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); + for ( final Input input : inputs ) + { + if ( input.trigger.equals( trigger ) ) + { + /* + * the trigger -> behaviour binding already exists. + * just add the new context + */ + input.contexts.addAll( contexts ); + return; + } + } + + /* + * the trigger -> behaviour binding does not exist. + * add it + */ + inputs.add( new Input( trigger, behaviourName, contexts ) ); + } + public static class InputTriggerAdderImp implements InputTriggerAdder { private final InputTriggerMap map; @@ -355,44 +393,6 @@ InputTriggerDescription getDescription() } } - void clear() - { - actionToInputsMap.clear(); - } - - void add( final String trigger, final String behaviourName, final String context ) - { - add( InputTrigger.getFromString( trigger ), behaviourName, context ); - } - - void add( final InputTrigger trigger, final String behaviourName, final String context ) - { - add( trigger, behaviourName, Collections.singleton( context ) ); - } - - synchronized void add( final InputTrigger trigger, final String behaviourName, final Collection< String > contexts ) - { - final Set< Input > inputs = actionToInputsMap.computeIfAbsent( behaviourName, k -> new LinkedHashSet<>() ); - for ( final Input input : inputs ) - { - if ( input.trigger.equals( trigger ) ) - { - /* - * the trigger -> behaviour binding already exists. - * just add the new context - */ - input.contexts.addAll( contexts ); - return; - } - } - - /* - * the trigger -> behaviour binding does not exist. - * add it - */ - inputs.add( new Input( trigger, behaviourName, contexts ) ); - } - /* * creating InputTriggerConfig from InputTriggerMaps and InputMaps */ diff --git a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java similarity index 99% rename from src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java rename to src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 08e61db..bc71fab 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -1,4 +1,4 @@ -package org.scijava.ui.behaviour.io; +package org.scijava.ui.behaviour.io.gui; import java.awt.BorderLayout; import java.awt.Color; @@ -48,10 +48,7 @@ import javax.swing.table.TableRowSorter; import org.scijava.ui.behaviour.InputTrigger; -import org.scijava.ui.behaviour.io.gui.Command; -import org.scijava.ui.behaviour.io.gui.CommandDescriptionBuilder; -import org.scijava.ui.behaviour.io.gui.InputTriggerPanelEditor; -import org.scijava.ui.behaviour.io.gui.TagPanelEditor; +import org.scijava.ui.behaviour.io.InputTriggerConfig; public class VisualEditorPanel extends JPanel { diff --git a/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java similarity index 94% rename from src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java rename to src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java index 29cb665..663a363 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java @@ -1,4 +1,4 @@ -package org.scijava.ui.behaviour.io; +package org.scijava.ui.behaviour.io.gui; import java.awt.EventQueue; import java.io.StringReader; @@ -10,8 +10,11 @@ import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; +import org.scijava.ui.behaviour.io.InputTriggerConfig; +import org.scijava.ui.behaviour.io.InputTriggerDescription; import org.scijava.ui.behaviour.io.gui.Command; import org.scijava.ui.behaviour.io.gui.CommandDescriptionBuilder; +import org.scijava.ui.behaviour.io.gui.VisualEditorPanel; import org.scijava.ui.behaviour.io.yaml.YamlConfigIO; public class VisualEditorPanelDemo From 9fd3b722e70b688d25082af2af9d1a4aead1168b Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 7 Dec 2017 13:05:18 +0100 Subject: [PATCH 092/184] clean up --- .../scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java index 7a313b4..4d38c19 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java @@ -37,7 +37,6 @@ import java.util.Map.Entry; import java.util.Set; -import java.util.stream.Collectors; import javax.swing.InputMap; import org.scijava.ui.behaviour.InputTriggerMap; From 6cb191c4563ea3461677576ef964251795b8e691 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 7 Dec 2017 13:06:42 +0100 Subject: [PATCH 093/184] Make InputTriggerComparator and MyTableRowComparator singleton objects --- .../behaviour/io/gui/VisualEditorPanel.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index bc71fab..a7e832c 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -382,7 +382,7 @@ public void valueChanged( final ListSelectionEvent e ) if ( !tableModel.removeSuperfluousNotMapped() ) return; - final int bs = Collections.binarySearch( tableModel.rows, selectedRowToRestore, new MyTableRowComparator() ); + final int bs = Collections.binarySearch( tableModel.rows, selectedRowToRestore, MyTableRowComparator ); if ( bs < 0 ) return; final int vbs = tableBindings.convertRowIndexToView( bs ); @@ -425,7 +425,7 @@ public void configChanged() scrollPane.setViewportView( tableBindings ); this.tableRowSorter = new TableRowSorter<>( tableModel ); - tableRowSorter.setComparator( 1, new InputTriggerComparator() ); + tableRowSorter.setComparator( 1, InputTriggerComparator ); tableBindings.setRowSorter( tableRowSorter ); } @@ -700,7 +700,7 @@ private void copyCommand() blockRemoveNotMapped = true; // Find the row we just added if any. - final int modelRowToSelect = Collections.binarySearch( tableModel.rows, copiedRow, new MyTableRowComparator() ); + final int modelRowToSelect = Collections.binarySearch( tableModel.rows, copiedRow, MyTableRowComparator ); final int rowToSelect; if ( modelRowToSelect < 0 ) rowToSelect = tableBindings.convertRowIndexToView( modelRow ); @@ -728,7 +728,7 @@ private void keybindingsChanged( final InputTrigger inputTrigger ) tableModel.fireTableRowsUpdated( modelRow, modelRow ); lookForConflicts(); - final int modelRowToSelect = Collections.binarySearch( tableModel.rows, updatedRow, new MyTableRowComparator() ); + final int modelRowToSelect = Collections.binarySearch( tableModel.rows, updatedRow, MyTableRowComparator ); final int rowToSelect; if ( modelRowToSelect < 0 ) rowToSelect = tableBindings.convertRowIndexToView( modelRow ); @@ -1011,14 +1011,13 @@ private void mergeRows( final List< MyTableRow > rows ) final List< MyTableRow > rowsUnmerged = new ArrayList<>( rows ); rows.clear(); - final MyTableRowComparator comparator = new MyTableRowComparator(); - rowsUnmerged.sort( comparator ); + rowsUnmerged.sort( MyTableRowComparator ); for ( int i = 0; i < rowsUnmerged.size(); ) { final MyTableRow rowA = rowsUnmerged.get( i ); int j = i + 1; - while ( j < rowsUnmerged.size() && comparator.compare( rowsUnmerged.get( j ), rowA ) == 0 ) + while ( j < rowsUnmerged.size() && MyTableRowComparator.compare( rowsUnmerged.get( j ), rowA ) == 0 ) ++j; final Set< String > contexts = new HashSet<>(); @@ -1119,7 +1118,7 @@ public String getColumnName( final int column ) } } - private static final class MyTableRowComparator implements Comparator< MyTableRow > + private static final Comparator< MyTableRow > MyTableRowComparator = new Comparator< MyTableRow >() { @Override public int compare( final MyTableRow o1, final MyTableRow o2 ) @@ -1139,9 +1138,9 @@ private int compare( final InputTrigger o1, final InputTrigger o2 ) return -1; return o1.toString().compareTo( o2.toString() ); } - } + }; - private static final class InputTriggerComparator implements Comparator< InputTrigger > + private static final Comparator< InputTrigger > InputTriggerComparator = new Comparator< InputTrigger >() { @Override public int compare( final InputTrigger o1, final InputTrigger o2 ) @@ -1152,5 +1151,5 @@ public int compare( final InputTrigger o1, final InputTrigger o2 ) return -1; return o1.toString().compareTo( o2.toString() ); } - } + }; } From 13cbbe2aeb3f43271d6b8729d0a4f35d842788d2 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 7 Dec 2017 13:07:10 +0100 Subject: [PATCH 094/184] Add convenience constructor with only InputTriggerConfig (no descriptions) --- .../behaviour/io/gui/VisualEditorPanel.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index a7e832c..369c885 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -19,6 +19,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.NoSuchElementException; @@ -49,6 +50,8 @@ import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.io.InputTriggerConfig; +import org.scijava.ui.behaviour.io.InputTriggerDescription; +import org.scijava.ui.behaviour.io.InputTriggerDescriptionsBuilder; public class VisualEditorPanel extends JPanel { @@ -127,6 +130,18 @@ public static interface ConfigChangeListener private TableRowSorter< MyTableModel > tableRowSorter; + /** + * Creates a visual editor for an {@link InputTriggerConfig}. The config + * object is directly modified when the user clicks the 'Apply' button. + * + * @param config + * the {@link InputTriggerConfig} object to modify. + */ + public VisualEditorPanel( final InputTriggerConfig config ) + { + this( config, extractEmptyCommandDescriptions( config ) ); + } + /** * Creates a visual editor for an {@link InputTriggerConfig}. The config * object is directly modified when the user clicks the 'Apply' button. @@ -771,6 +786,18 @@ private void notifyListeners() listener.configChanged(); } + private static Map< Command, String > extractEmptyCommandDescriptions( final InputTriggerConfig keyconf ) + { + final List< InputTriggerDescription > descriptions = new InputTriggerDescriptionsBuilder( keyconf ).getDescriptions(); + final Set< Command > commands = new LinkedHashSet<>(); + for ( final InputTriggerDescription desc : descriptions ) + for( final String context : desc.getContexts() ) + commands.add( new Command( desc.getAction(), context ) ); + final Map< Command, String > commandDescriptions = new HashMap<>(); + commands.forEach( command -> commandDescriptions.put( command, null ) ); + return commandDescriptions; + } + public void addConfigChangeListener( final ConfigChangeListener listener ) { listeners.add( listener ); From 8a8bfa9e3e572dbb90315dcf78050eed2f4e918c Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Fri, 8 Dec 2017 13:31:51 +0100 Subject: [PATCH 095/184] Fix javadoc errors --- .../org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 369c885..03eecf7 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -149,9 +149,8 @@ public VisualEditorPanel( final InputTriggerConfig config ) * @param config * the {@link InputTriggerConfig} object to modify. * @param commandDescriptions - * The commands available. They are specified as a map from map - * of commands -> map of contexts -> description of what the - * command do in a context. Use null as value to not + * The commands available. They are specified as a map from + * command to description. Use null as value to not * specify a description. * @see CommandDescriptionBuilder */ From d6d412e8876d44998eb18d85e36e28397565ce45 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Fri, 8 Dec 2017 13:32:54 +0100 Subject: [PATCH 096/184] Bump to next development cycle Signed-off-by: Tobias Pietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8d16756..cd0ad7a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.5.2-SNAPSHOT + 1.6.1-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 37b663ac242da37e2538ab614fe3130bb7efb3f6 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Mon, 22 Jan 2018 16:39:23 +0100 Subject: [PATCH 097/184] Set values from one InputTriggerConfig to another --- .../ui/behaviour/io/InputTriggerConfig.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 4ccfbfb..b6980b0 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -114,6 +114,18 @@ public void clear() actionToInputsMap.clear(); } + public void set( InputTriggerConfig config ) + { + actionToInputsMap.clear(); + for ( Entry< String, Set< Input > > entry : actionToInputsMap.entrySet() ) + { + final String behaviourName = entry.getKey(); + final Set< Input > inputs = new LinkedHashSet<>(); + entry.getValue().forEach( i -> inputs.add( i.copy() ) ); + actionToInputsMap.put( behaviourName, inputs ); + } + } + public void add( final String trigger, final String behaviourName, final String context ) { add( InputTrigger.getFromString( trigger ), behaviourName, context ); @@ -368,6 +380,18 @@ static class Input this.contexts = new HashSet<>( contexts ); } + Input( Input input ) + { + this.trigger = input.trigger; + this.behaviour = input.behaviour; + this.contexts = new HashSet<>( input.contexts ); + } + + Input copy() + { + return new Input( this ); + } + @Override public int hashCode() { From f4e3f3d573fcc7d216b83d97b4dd0cdadda77e3a Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Mon, 22 Jan 2018 16:40:18 +0100 Subject: [PATCH 098/184] Let RunnableAction implement Runnable --- .../org/scijava/ui/behaviour/util/RunnableAction.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java index 0acf65c..716ffb2 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java @@ -31,7 +31,7 @@ import java.awt.event.ActionEvent; -public class RunnableAction extends AbstractNamedAction +public class RunnableAction extends AbstractNamedAction implements Runnable { private final Runnable action; @@ -47,5 +47,11 @@ public void actionPerformed( final ActionEvent e ) action.run(); } + @Override + public void run() + { + action.run(); + } + private static final long serialVersionUID = 1L; } From 7a801f0d13f50f8594bdc51bb25772a5da9a92e6 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Mon, 22 Jan 2018 21:42:21 +0100 Subject: [PATCH 099/184] bugfix --- .../java/org/scijava/ui/behaviour/io/InputTriggerConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index b6980b0..9175abf 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -117,7 +117,7 @@ public void clear() public void set( InputTriggerConfig config ) { actionToInputsMap.clear(); - for ( Entry< String, Set< Input > > entry : actionToInputsMap.entrySet() ) + for ( Entry< String, Set< Input > > entry : config.actionToInputsMap.entrySet() ) { final String behaviourName = entry.getKey(); final Set< Input > inputs = new LinkedHashSet<>(); From 6ec5aeaec6f65f618f6349896b0c490fb32ca372 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 23 Jan 2018 03:00:05 +0100 Subject: [PATCH 100/184] Do not notifyListeners when copying a command (Notification will be sent when a new key is assigned) --- .../org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 03eecf7..0af11c9 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -722,9 +722,6 @@ private void copyCommand() rowToSelect = tableBindings.convertRowIndexToView( modelRowToSelect ); tableBindings.getSelectionModel().setSelectionInterval( rowToSelect, rowToSelect ); - // Notify listeners. - notifyListeners(); - keybindingEditor.requestFocusInWindow(); } From 1f6ba8c613312283f45e007648b8e4698fb9d64f Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 23 Jan 2018 03:00:34 +0100 Subject: [PATCH 101/184] Do notifyListeners when unbinding commands --- .../org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 0af11c9..cd3d7dd 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -678,6 +678,9 @@ private void unbindCommand() tableModel.rows.remove( modelRow ); if ( !tableModel.addMissingRows() ) tableModel.fireTableRowsDeleted( modelRow, modelRow ); + + // Notify listeners. + notifyListeners(); } private void unbindAllCommand() @@ -696,6 +699,9 @@ private void unbindAllCommand() } if ( !tableModel.addMissingRows() ) tableModel.fireTableDataChanged(); + + // Notify listeners. + notifyListeners(); } private void copyCommand() From a0c5b170f92e2fc6db55e4bbded39c51574c9d5a Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Tue, 23 Jan 2018 12:23:48 +0100 Subject: [PATCH 102/184] Do not try to select a line in the vidual editor if there are no lines. Fixes #13. --- .../org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 03eecf7..005e650 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -536,7 +536,9 @@ public void configToModel() // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); tableBindings.getColumnModel().getColumn( 2 ).setCellRenderer( new MyContextsRenderer( Collections.emptyList() ) ); - tableBindings.getSelectionModel().setSelectionInterval( 0, 0 ); + + if (tableBindings.getRowCount() > 0) + tableBindings.getSelectionModel().setSelectionInterval( 0, 0 ); // Notify listeners. notifyListeners(); From c2bec556650bbb8e37c3779fc43849ca29387761 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 23 Jan 2018 13:18:15 +0100 Subject: [PATCH 103/184] Bugfix: need to make a new TableRowSorter when making a new TableModel --- .../ui/behaviour/io/gui/VisualEditorPanel.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index cd3d7dd..7c7dfc9 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -96,6 +96,8 @@ public static interface ConfigChangeListener private MyTableModel tableModel; + private TableRowSorter< MyTableModel > tableRowSorter; + private boolean blockRemoveNotMapped = false; private final InputTriggerPanelEditor keybindingEditor; @@ -116,7 +118,7 @@ public static interface ConfigChangeListener private final JLabel lblConflict; - private JTextArea textAreaDescription; + private final JTextArea textAreaDescription; private final JPanel panelEditor; @@ -128,8 +130,6 @@ public static interface ConfigChangeListener private final JButton btnRestore; - private TableRowSorter< MyTableModel > tableRowSorter; - /** * Creates a visual editor for an {@link InputTriggerConfig}. The config * object is directly modified when the user clicks the 'Apply' button. @@ -437,10 +437,6 @@ public void configChanged() configToModel(); scrollPane.setViewportView( tableBindings ); - - this.tableRowSorter = new TableRowSorter<>( tableModel ); - tableRowSorter.setComparator( 1, InputTriggerComparator ); - tableBindings.setRowSorter( tableRowSorter ); } private void lookForConflicts() @@ -533,6 +529,12 @@ public void configToModel() { tableModel = new MyTableModel( commands, config ); tableBindings.setModel( tableModel ); + + tableRowSorter = new TableRowSorter<>( tableModel ); + tableRowSorter.setComparator( 1, InputTriggerComparator ); + tableBindings.setRowSorter( tableRowSorter ); + filterRows(); + // Renderers. tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); tableBindings.getColumnModel().getColumn( 2 ).setCellRenderer( new MyContextsRenderer( Collections.emptyList() ) ); From df41be9b10731c8f94236ca204fde53ea5935e07 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 23 Jan 2018 13:18:40 +0100 Subject: [PATCH 104/184] Remove unused code --- .../org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 7c7dfc9..b9246e9 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -552,9 +552,6 @@ private void filterRows() RowFilter< MyTableModel, Integer > rf = null; try { - final int[] indices = new int[ tableModel.getRowCount() ]; - for ( int i = 0; i < indices.length; i++ ) - indices[ i ] = i; rf = RowFilter.regexFilter( textFieldFilter.getText(), 0 ); } catch ( final java.util.regex.PatternSyntaxException pse ) From d56465cca7beba5ce3482b02e53ffa6f35e54905 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 23 Jan 2018 16:32:52 +0100 Subject: [PATCH 105/184] InputActionBindings.add[Input|Action]Map() variants with insertion index --- .../behaviour/util/InputActionBindings.java | 71 ++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java index 597712c..f81bb1a 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java @@ -108,6 +108,23 @@ public void addActionMap( final String id, final ActionMap actionMap ) updateTheActionMap(); } + /** + * Add as {@link ActionMap} with the specified id at the specified position + * in the list (overrides maps at lower positions). If the specified id + * already exists in the list, remove the corresponding earlier + * {@link ActionMap}. + */ + public void addActionMap( final int index, final String id, final ActionMap actionMap ) + { + removeId( actions, id ); + if ( actionMap != null ) + { + final int i = Math.max( 0, Math.min( actions.size(), index ) ); + actions.add( i, new Actions( id, actionMap ) ); + } + updateTheActionMap(); + } + /** * Remove the {@link ActionMap} with the given id from the list. */ @@ -118,7 +135,7 @@ public void removeActionMap( final String id ) } /** - * Add as {@link InputMap} with the specified id to the end of the list + * Adds a {@link InputMap} with the specified id to the end of the list * (overrides maps that were added earlier). If the specified id already * exists in the list, remove the corresponding earlier {@link InputMap}. *

@@ -138,7 +155,7 @@ public void addInputMap( final String id, final InputMap inputMap, final String. } /** - * Add as {@link InputMap} with the specified id to the end of the list + * Adds a {@link InputMap} with the specified id to the end of the list * (overrides maps that were added earlier). If the specified id already * exists in the list, remove the corresponding earlier {@link InputMap}. *

@@ -160,6 +177,56 @@ public void addInputMap( final String id, final InputMap inputMap, final Collect updateTheInputMap(); } + /** + * Inserts a {@link InputMap} with the specified id at the specified + * position in the list (overrides maps at lower positions). If the + * specified id already exists in the list, remove the corresponding earlier + * {@link InputMap}. + *

+ * If {@code idsToBlock} are given, {@link InputMap}s with these ids earlier + * in the chain that should be disabled. The special id "all" blocks all + * earlier {@link InputMap}s. + * + * @param index + * @param id + * @param inputMap + * @param idsToBlock + * ids of {@link InputMap}s earlier in the chain that should be + * disabled. + */ + public void addInputMap( final int index, final String id, final InputMap inputMap, final String... idsToBlock ) + { + addInputMap( index, id, inputMap, Arrays.asList( idsToBlock ) ); + } + + /** + * Inserts a {@link InputMap} with the specified id at the specified + * position in the list (overrides maps at lower positions). If the + * specified id already exists in the list, remove the corresponding earlier + * {@link InputMap}. + *

+ * If {@code idsToBlock} are given, {@link InputMap}s with these ids earlier + * in the chain that should be disabled. The special id "all" blocks all + * earlier {@link InputMap}s. + * + * @param index + * @param id + * @param inputMap + * @param idsToBlock + * ids of {@link InputMap}s earlier in the chain that should be + * disabled. + */ + public void addInputMap( final int index, final String id, final InputMap inputMap, final Collection< String > idsToBlock ) + { + removeId( inputs, id ); + if ( inputMap != null ) + { + final int i = Math.max( 0, Math.min( inputs.size(), index ) ); + inputs.add( i, new Keys( id, inputMap, idsToBlock ) ); + } + updateTheInputMap(); + } + /** * Remove the {@link InputMap} with the given id from the list. */ From 1d1b9b4aa51912d01e2b62507910d3e25b9bfaca Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Tue, 23 Jan 2018 16:46:40 +0100 Subject: [PATCH 106/184] Update visual editor example with proper case commands. --- .../scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java index 663a363..75b8338 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java @@ -12,9 +12,6 @@ import org.scijava.ui.behaviour.io.InputTriggerConfig; import org.scijava.ui.behaviour.io.InputTriggerDescription; -import org.scijava.ui.behaviour.io.gui.Command; -import org.scijava.ui.behaviour.io.gui.CommandDescriptionBuilder; -import org.scijava.ui.behaviour.io.gui.VisualEditorPanel; import org.scijava.ui.behaviour.io.yaml.YamlConfigIO; public class VisualEditorPanelDemo @@ -57,6 +54,8 @@ private static Map< Command, String > getDemoCommands() return new CommandDescriptionBuilder() .addCommand( "drag1", "mamut", "Move an item around the editor." ) .addCommand( "drag1", "trackscheme", "Move an item around the editor." ) + .addCommand( "drag1", "other", "Move an item around the editor." ) + .addCommand( "Elude", "other", "Refuse to answer the question." ) .addCommand( "scroll1", "mamut", null ) .addCommand( "destroy the world", "all", "Make a disgusting coffee for breakfast. \n" + "For this one, you are by yourself. Good luck and know that we are with you. This is a long line. Hopefully long engouh.\n" @@ -64,6 +63,7 @@ private static Map< Command, String > getDemoCommands() + "tabulation1\ttabulation2\n" + "lalallala\ttrollololo." ) .addCommand( "ride the dragon", "all", "Go to work by bike." ) + .addCommand( "Punish", "all", "Go to work by parisian metro." ) .addCommand( "make some coffee", "mamut", null ) .addCommand( "make some coffee", "trackscheme", "Make a decent coffee." ) .get(); From 02155094a1bcbe0a53fca4f90236b5aaf1d8ca22 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Tue, 23 Jan 2018 16:47:02 +0100 Subject: [PATCH 107/184] Sorting in the visual editor is now case-insensitive. --- .../behaviour/io/gui/VisualEditorPanel.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index dbe9350..1a04f68 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -24,6 +24,8 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.swing.Box; import javax.swing.BoxLayout; @@ -551,15 +553,24 @@ public void configToModel() private void filterRows() { - RowFilter< MyTableModel, Integer > rf = null; - try + final String regex = textFieldFilter.getText(); + final Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE ); + final Matcher matcher = pattern.matcher( "" ); + final RowFilter< MyTableModel, Integer > rf = new RowFilter< MyTableModel, Integer >() { - rf = RowFilter.regexFilter( textFieldFilter.getText(), 0 ); - } - catch ( final java.util.regex.PatternSyntaxException pse ) - { - return; - } + + @Override + public boolean include( final Entry< ? extends MyTableModel, ? extends Integer > entry ) + { + int count = entry.getValueCount(); + while ( --count >= 0 ) + { + matcher.reset( entry.getStringValue( count ) ); + if ( matcher.find() ) { return true; } + } + return false; + } + }; tableRowSorter.setRowFilter( rf ); } From 5149f6f6fecdfba409390d1a0e956042b286424b Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Tue, 23 Jan 2018 17:33:08 +0100 Subject: [PATCH 108/184] Sort by command names (case-unsensitive) in the visual editor. Also at startup. --- .../org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 1a04f68..283a5ca 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -438,6 +438,10 @@ public void configChanged() } ); configToModel(); + tableBindings.getRowSorter().toggleSortOrder( 0 ); + if ( tableBindings.getRowCount() > 0 ) + tableBindings.getSelectionModel().setSelectionInterval( 0, 0); + scrollPane.setViewportView( tableBindings ); } @@ -541,9 +545,6 @@ public void configToModel() tableBindings.getColumnModel().getColumn( 1 ).setCellRenderer( new MyBindingsRenderer() ); tableBindings.getColumnModel().getColumn( 2 ).setCellRenderer( new MyContextsRenderer( Collections.emptyList() ) ); - if (tableBindings.getRowCount() > 0) - tableBindings.getSelectionModel().setSelectionInterval( 0, 0 ); - // Notify listeners. notifyListeners(); From 832def57f36477c48640bb362ecd43fa0c017979 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 24 Jan 2018 23:35:24 +0100 Subject: [PATCH 109/184] Bump to next development cycle Signed-off-by: Tobias Pietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cd0ad7a..e6c71d4 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.6.1-SNAPSHOT + 1.7.1-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 99c8324856740853a9878b7730c4bb7e21d67b44 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 20 Feb 2018 22:16:49 +0100 Subject: [PATCH 110/184] javadoc --- .../behaviour/util/TriggerBehaviourBindings.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java index 1a7d7cc..f4d20f4 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java @@ -7,13 +7,13 @@ * %% * 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 @@ -37,9 +37,6 @@ import java.util.ListIterator; import java.util.Set; -import javax.swing.ActionMap; -import javax.swing.InputMap; - import org.scijava.ui.behaviour.BehaviourMap; import org.scijava.ui.behaviour.InputTriggerMap; @@ -104,6 +101,10 @@ public void removeBehaviourMap( final String id ) * list (overrides maps that were added earlier). If the specified id * already exists in the list, remove the corresponding earlier * {@link InputTriggerMap}. + *

+ * If {@code idsToBlock} are given, {@link InputTriggerMap}s with these ids + * earlier in the chain that should be disabled. The special id "all" blocks + * all earlier {@link InputTriggerMap}s. * * @param id * @param inputTriggerMap @@ -121,6 +122,10 @@ public void addInputTriggerMap( final String id, final InputTriggerMap inputTrig * list (overrides maps that were added earlier). If the specified id * already exists in the list, remove the corresponding earlier * {@link InputTriggerMap}. + *

+ * If {@code idsToBlock} are given, {@link InputTriggerMap}s with these ids + * earlier in the chain that should be disabled. The special id "all" blocks + * all earlier {@link InputTriggerMap}s. * * @param id * @param inputTriggerMap From 5a63ecf6d7fbdf386becdc813a7a9a665a442464 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Tue, 20 Feb 2018 23:10:40 +0100 Subject: [PATCH 111/184] Bump to next development cycle Signed-off-by: Tobias Pietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e6c71d4..93b9c19 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.7.1-SNAPSHOT + 1.7.2-SNAPSHOT UI Behaviour Configurable key and mouse event handling From f4e8d0ae2870a849053a43553faea8ddf157c4db Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Sat, 24 Feb 2018 22:19:03 +0100 Subject: [PATCH 112/184] Guard against cyclic getParent() calls A StackOverflow could happen in root.setParent() -> modCount() then looping getParent().modCount(). --- .../org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java index f4d20f4..e22e53e 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java @@ -253,6 +253,7 @@ private void updateTheBehaviourMap() final BehaviourMap map = iter.previous().getBehaviourMap(); if ( map != null ) { + map.setParent( null ); root.setParent( map ); root = map; } @@ -275,6 +276,7 @@ private void updateTheInputTriggerMap() final InputTriggerMap map = keys.getInputTriggerMap(); if ( map != null ) { + map.setParent( null ); root.setParent( map ); root = map; } From 3854ec2f8a4856ca1086fdf3353e541c350abe79 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 4 Apr 2018 12:39:15 +0200 Subject: [PATCH 113/184] Bugfix: ActionMap.keys() may be null --- src/main/java/org/scijava/ui/behaviour/util/Actions.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index 216cab1..c6ceee1 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -190,7 +190,9 @@ public void updateKeyConfig( final KeyStrokeAdder.Factory keyConfig ) this.keyConfig = keyConfig; keyStrokeAdder = keyConfig.keyStrokeAdder( inputMap, keyConfigContexts ); inputMap.clear(); - for ( final Object o : actionMap.keys() ) - keyStrokeAdder.put( ( String ) o ); + final Object[] keys = actionMap.keys(); + if ( keys != null ) + for ( final Object o : keys ) + keyStrokeAdder.put( ( String ) o ); } } From 6769d2c2ae03dade7d2fe29d49331be34be040e9 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Wed, 4 Apr 2018 12:51:30 +0200 Subject: [PATCH 114/184] Bump to next development cycle Signed-off-by: Tobias Pietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 93b9c19..cfea08a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.7.2-SNAPSHOT + 1.7.3-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 12f5bc7151104802d90659bd1985c6e143a5125d Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 5 Apr 2018 15:32:53 +0200 Subject: [PATCH 115/184] Add InputTriggerMap.getBindings() that returns only bindings in this map (not parent) --- .../scijava/ui/behaviour/InputTriggerMap.java | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java index 9013d35..0babb2e 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java @@ -177,11 +177,15 @@ public synchronized void clear() } /** - * Get all bindings defined in this map and its parents. Note the returned - * map not backed by the {@link InputTriggerMap}, i.e., it will not - * reflect changes to the {@link InputTriggerMap}. + * Get all bindings defined in this map and its parents. Note that the + * returned map is not backed by the {@link InputTriggerMap}, i.e., + * it will not reflect changes to the {@link InputTriggerMap}. + *

+ * This differs from {@code getBindings()} in that this method includes the + * bindings defined in the parent. * - * @return all bindings defined in this map and its parents. + * @return all bindings (trigger to set of behaviour keys) defined in this + * map and its parents. */ public synchronized Map< InputTrigger, Set< String > > getAllBindings() { @@ -191,22 +195,42 @@ public synchronized Map< InputTrigger, Set< String > > getAllBindings() else allBindings = new HashMap<>(); + addBindings( allBindings ); + + return allBindings; + } + + /** + * Get all bindings defined in this map. Note that the returned map is + * not backed by the {@link InputTriggerMap}, i.e., it will not + * reflect changes to the {@link InputTriggerMap}. + * + * @return all bindings (trigger to set of behaviour keys) defined in this + * map. + */ + public synchronized Map< InputTrigger, Set< String > > getBindings() + { + final Map< InputTrigger, Set< String > > bindings = new HashMap<>(); + addBindings( bindings ); + return bindings; + } + + private void addBindings( final Map< InputTrigger, Set< String > > bindings ) + { for ( final Entry< InputTrigger, Set< String > > entry : triggerToKeys.entrySet() ) { final InputTrigger inputTrigger = entry.getKey(); if ( entry.getValue() == null || entry.getValue().isEmpty() ) continue; - Set< String > behaviourKeys = allBindings.get( inputTrigger ); + Set< String > behaviourKeys = bindings.get( inputTrigger ); if ( behaviourKeys == null ) { behaviourKeys = new HashSet<>(); - allBindings.put( inputTrigger, behaviourKeys ); + bindings.put( inputTrigger, behaviourKeys ); } behaviourKeys.addAll( entry.getValue() ); } - - return allBindings; } public int modCount() From 167632e2def148d9e12e315f2cc87280644d63fe Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Thu, 5 Apr 2018 15:35:17 +0200 Subject: [PATCH 116/184] Add possibility to retain bindings of undefined actions in updateKeyConfig (undefined: not occurring in InputTriggerConfig) --- .../scijava/ui/behaviour/util/Actions.java | 48 ++++++++++++++++- .../scijava/ui/behaviour/util/Behaviours.java | 51 ++++++++++++++++++- 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index c6ceee1..f1c5d4e 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -29,8 +29,16 @@ */ package org.scijava.ui.behaviour.util; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + import javax.swing.ActionMap; import javax.swing.InputMap; +import javax.swing.KeyStroke; import org.scijava.ui.behaviour.KeyStrokeAdder; import org.scijava.ui.behaviour.io.InputTriggerConfig; @@ -185,14 +193,52 @@ public void namedAction( final AbstractNamedAction action, final String... defau * @param keyConfig * the new keyConfig */ - public void updateKeyConfig( final KeyStrokeAdder.Factory keyConfig ) + public void updateKeyConfig( final InputTriggerConfig keyConfig ) + { + updateKeyConfig( keyConfig, true ); + } + + /** + * Clears the {@link InputMap} and re-adds all ({@code String}) action keys + * from {@link ActionMap} using the provided {@code keyConfig}. + *

+ * Actions that are currently in the {@code InputMap} but are not defined in + * the {@code keyConfig} retain their current keystrokes (note that + * {@code keyConfig} can map actions to "not mapped"). + * + * @param keyConfig + * the new keyConfig + * @param clearAll + * whether to clear all bindings (also of actions that are + * undefined in {@code keyConfig}) + */ + public void updateKeyConfig( final InputTriggerConfig keyConfig, final boolean clearAll ) { this.keyConfig = keyConfig; + + final Map< Object, List< KeyStroke > > unassigned = new HashMap<>(); + if ( !clearAll ) + { + final KeyStroke[] inputs = inputMap.keys(); + if ( inputs != null ) + { + final HashSet< String > contexts = new HashSet<>( Arrays.asList( keyConfigContexts ) ); + for ( final KeyStroke input : inputs ) + { + final Object actionKey = inputMap.get( input ); + if ( ( !( actionKey instanceof String ) ) || keyConfig.getInputs( ( String ) actionKey, contexts ).isEmpty() ) + unassigned.computeIfAbsent( actionKey, k -> new ArrayList<>() ).add( input ); + } + } + } + keyStrokeAdder = keyConfig.keyStrokeAdder( inputMap, keyConfigContexts ); inputMap.clear(); final Object[] keys = actionMap.keys(); if ( keys != null ) for ( final Object o : keys ) keyStrokeAdder.put( ( String ) o ); + + unassigned.forEach( ( actionMapKey, keyStrokes ) -> keyStrokes.forEach( keyStroke -> inputMap.put( keyStroke, actionMapKey ) ) ); } } diff --git a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java index 2b32d2e..f0c8286 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java @@ -29,8 +29,18 @@ */ package org.scijava.ui.behaviour.util; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + import org.scijava.ui.behaviour.Behaviour; import org.scijava.ui.behaviour.BehaviourMap; +import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.InputTriggerAdder; import org.scijava.ui.behaviour.InputTriggerMap; import org.scijava.ui.behaviour.io.InputTriggerConfig; @@ -164,12 +174,51 @@ public void namedBehaviour( final AbstractNamedBehaviour behaviour, final String * @param keyConfig * the new keyConfig */ - public void updateKeyConfig( final InputTriggerAdder.Factory keyConfig ) + public void updateKeyConfig( final InputTriggerConfig keyConfig ) + { + updateKeyConfig( keyConfig, true ); + } + + /** + * Clears the {@link InputTriggerMap} and re-adds all behaviour keys from + * {@link BehaviourMap} using the provided {@code keyConfig}. + *

+ * If {@code clearAll==false}, then behaviours that are currently in the + * {@code InputTriggerMap} but are not defined in the {@code keyConfig} + * retain their current keystrokes (note that {@code keyConfig} can map + * behaviours to "not mapped"). + * + * @param keyConfig + * the new keyConfig + * @param clearAll + * whether to clear all bindings (also of behaviours that are + * undefined in {@code keyConfig}) + */ + public void updateKeyConfig( final InputTriggerConfig keyConfig, final boolean clearAll ) { this.keyConfig = keyConfig; + + final Map< String, List< InputTrigger > > unassigned = new HashMap<>(); + if ( !clearAll ) + { + final Map< InputTrigger, Set< String > > bindings = inputTriggerMap.getBindings(); + final HashSet< String > contexts = new HashSet<>( Arrays.asList( keyConfigContexts ) ); + for ( final Entry< InputTrigger, Set< String > > entry : bindings.entrySet() ) + { + final InputTrigger trigger = entry.getKey(); + for ( final String behaviourKey : entry.getValue() ) + { + if ( keyConfig.getInputs( behaviourKey, contexts ).isEmpty() ) + unassigned.computeIfAbsent( behaviourKey, k -> new ArrayList<>() ).add( trigger ); + } + } + } + inputTriggerAdder = keyConfig.inputTriggerAdder( inputTriggerMap, keyConfigContexts ); inputTriggerMap.clear(); for ( final String behaviourName : behaviourMap.keys() ) inputTriggerAdder.put( behaviourName ); + + unassigned.forEach( ( behaviourKey, triggers ) -> triggers.forEach( trigger -> inputTriggerMap.put( trigger, behaviourKey ) ) ); } } From fc1ad27943f324efab34ee89ea69aabf55f0c9f3 Mon Sep 17 00:00:00 2001 From: Tobias Pietzsch Date: Fri, 13 Apr 2018 13:44:56 +0200 Subject: [PATCH 117/184] Bump to next development cycle Signed-off-by: Tobias Pietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cfea08a..3af0206 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.7.3-SNAPSHOT + 1.7.4-SNAPSHOT UI Behaviour Configurable key and mouse event handling From c7597f32e0c5dfd7bc323a2dd84aaaaed213ca49 Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Thu, 2 Aug 2018 15:36:31 +0200 Subject: [PATCH 118/184] Impose the order in which key tags are displayed in the GUI. --- .../io/gui/InputTriggerPanelEditor.java | 75 ++++++++++++++----- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index e704716..4176def 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -200,6 +201,9 @@ private void removeLastKeyItem() if ( tokens.length == 0 ) return; + // We have to sort tokens as they are displayed. + sortTokens( tokens ); + final StringBuilder strBlder = new StringBuilder(); for ( int i = 0; i < tokens.length - 1; i++ ) strBlder.append( tokens[ i ] + " " ); @@ -262,6 +266,7 @@ private void regenKeyPanels() } else { + sortTokens( tokens ); for ( final String key : tokens ) { final KeyItem tagp = new KeyItem( key, valid ); @@ -333,9 +338,9 @@ public void insertUpdate( final DocumentEvent ev ) final String prefix = content.substring( w + 1 ); // We search on the lower case list. final int n = Collections.binarySearch( INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS, prefix.toLowerCase() ); - if ( n < 0 && -n <= INPUT_TRIGGER_SYNTAX_TAGS.size() ) + if ( n < 0 && -n <= INPUT_TRIGGER_SYNTAX_TAGS_SORTED.size() ) { - final String match = INPUT_TRIGGER_SYNTAX_TAGS.get( -n - 1 ); + final String match = INPUT_TRIGGER_SYNTAX_TAGS_SORTED.get( -n - 1 ); if ( match.toLowerCase().startsWith( prefix.toLowerCase() ) ) { // A completion is found @@ -432,23 +437,29 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l listeners.remove( listener ); } + /** Contains the tags in the order we want them to appear in the panel. */ private static final List< String > INPUT_TRIGGER_SYNTAX_TAGS = new ArrayList<>(); + /** Contains the tags sorted so that they can be searched by the autocomplete process. */ + private static final List< String > INPUT_TRIGGER_SYNTAX_TAGS_SORTED = new ArrayList<>(); + /** Small-caps version of INPUT_TRIGGER_SYNTAX_TAGS_SORTED. */ private static final List< String > INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS; + /** Visual replacement for some tags. */ private static final Map< String, String > TRIGGER_SYMBOLS = new HashMap<>(); private static final Map INPUT_TRIGGER_SYNTAX_TAG_REMAP = new HashMap<>(); static { - for ( int i = 0; i < 26; i++ ) - INPUT_TRIGGER_SYNTAX_TAGS.add( String.valueOf( ( char ) ( 'A' + i ) ) ); - for ( int i = 0; i < 10; i++ ) - INPUT_TRIGGER_SYNTAX_TAGS.add( "" + i ); - for ( int i = 1; i <= 24; i++ ) - INPUT_TRIGGER_SYNTAX_TAGS.add( "F" + i ); - INPUT_TRIGGER_SYNTAX_TAGS.addAll( Arrays.asList( new String[] { "all", + "ctrl", + "alt", + "altGraph", + "shift", + "meta", + "command", + "cmd", + "win", "ENTER", "BACK_SPACE", "TAB", @@ -495,14 +506,6 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l "DELETE", "NUM_LOCK", "SCROLL_LOCK", - "ctrl", - "alt", - "altGraph", - "shift", - "meta", - "command", - "cmd", - "win", "double-click", "button1", "button2", @@ -510,9 +513,17 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l "scroll", "|" } ) ); - INPUT_TRIGGER_SYNTAX_TAGS.sort( String.CASE_INSENSITIVE_ORDER ); - INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS = new ArrayList<>(INPUT_TRIGGER_SYNTAX_TAGS.size()); - for ( final String tag : INPUT_TRIGGER_SYNTAX_TAGS ) + for ( int i = 0; i < 26; i++ ) + INPUT_TRIGGER_SYNTAX_TAGS.add( String.valueOf( ( char ) ( 'A' + i ) ) ); + for ( int i = 0; i < 10; i++ ) + INPUT_TRIGGER_SYNTAX_TAGS.add( "" + i ); + for ( int i = 1; i <= 24; i++ ) + INPUT_TRIGGER_SYNTAX_TAGS.add( "F" + i ); + + INPUT_TRIGGER_SYNTAX_TAGS_SORTED.addAll( INPUT_TRIGGER_SYNTAX_TAGS ); + INPUT_TRIGGER_SYNTAX_TAGS_SORTED.sort( String.CASE_INSENSITIVE_ORDER ); + INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS = new ArrayList<>( INPUT_TRIGGER_SYNTAX_TAGS_SORTED.size() ); + for ( final String tag : INPUT_TRIGGER_SYNTAX_TAGS_SORTED ) INPUT_TRIGGER_SYNTAX_TAGS_SMALL_CAPS.add( tag.toLowerCase() ); INPUT_TRIGGER_SYNTAX_TAG_REMAP.put( "cmd", "meta" ); @@ -565,6 +576,30 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l TRIGGER_SYMBOLS.put( "|", " | " ); } + /** + * Sort tokens in a visually pleasing way. Makes sure we do not mess with + * the '|' syntax. + */ + private static final void sortTokens( final String[] tokens ) + { + int vbarIndex = -1; + for ( int i = 0; i < tokens.length; i++ ) + { + if ( tokens[ i ].equals( "|" ) ) + { + vbarIndex = i; + break; + } + } + if ( vbarIndex >= 0 ) + { + Arrays.sort( tokens, 0, vbarIndex, Comparator.comparingInt( INPUT_TRIGGER_SYNTAX_TAGS::indexOf ) ); + Arrays.sort( tokens, vbarIndex + 1, tokens.length, Comparator.comparingInt( INPUT_TRIGGER_SYNTAX_TAGS::indexOf ) ); + } + else + Arrays.sort( tokens, Comparator.comparingInt( INPUT_TRIGGER_SYNTAX_TAGS::indexOf ) ); + } + private static boolean isMac() { final String OS = System.getProperty( "os.name", "generic" ).toLowerCase( Locale.ENGLISH ); From c7b998830831dca2b09cdbbbe4b767f34e610d1d Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Thu, 2 Aug 2018 16:01:39 +0200 Subject: [PATCH 119/184] Fix the look of some key tags on windows. Fixes #17. --- .../scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index 4176def..beab283 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -533,8 +533,8 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l TRIGGER_SYMBOLS.put( "ENTER", "\u23CE" ); TRIGGER_SYMBOLS.put( "BACK_SPACE", "\u232B" ); TRIGGER_SYMBOLS.put( "DELETE", "\u2326" ); - TRIGGER_SYMBOLS.put( "TAB", "\u2B7E" ); - TRIGGER_SYMBOLS.put( "PAUSE", "\u23F8" ); + TRIGGER_SYMBOLS.put( "TAB", "\u21E5" ); + TRIGGER_SYMBOLS.put( "PAUSE", "||" ); TRIGGER_SYMBOLS.put( "CAPS_LOCK", "\u21EA" ); TRIGGER_SYMBOLS.put( "PAGE_UP", "\u21DE" ); TRIGGER_SYMBOLS.put( "PAGE_DOWN", "\u21DF" ); From 0d8e15bb9a26b7022cb0d3a229b7b7825b2e34ef Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sat, 10 Nov 2018 23:50:15 +0100 Subject: [PATCH 120/184] Bugfix mouseX, mouseY coordinates were not updated during drag, leading to incorrect coordinates for subsequent key-click (without moving mouse) --- .../java/org/scijava/ui/behaviour/MouseAndKeyHandler.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java index f963564..1d084ab 100644 --- a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java @@ -331,11 +331,11 @@ public void mouseDragged( final MouseEvent e ) // System.out.println( e ); update(); - final int x = e.getX(); - final int y = e.getY(); + mouseX = e.getX(); + mouseY = e.getY(); for ( final BehaviourEntry< DragBehaviour > drag : activeButtonDrags ) - drag.behaviour.drag( x, y ); + drag.behaviour.drag( mouseX, mouseY ); } @Override From d06b7adc46bee12e95b419f01e72f518e796856e Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sun, 11 Nov 2018 00:03:52 +0100 Subject: [PATCH 121/184] Update UsageExample to use Behaviours class --- .../scijava/ui/behaviour/UsageExample.java | 48 ++++++++----------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/src/test/java/org/scijava/ui/behaviour/UsageExample.java b/src/test/java/org/scijava/ui/behaviour/UsageExample.java index 7104cbb..b3222dc 100644 --- a/src/test/java/org/scijava/ui/behaviour/UsageExample.java +++ b/src/test/java/org/scijava/ui/behaviour/UsageExample.java @@ -39,66 +39,62 @@ import org.scijava.ui.behaviour.io.InputTriggerConfig; import org.scijava.ui.behaviour.io.InputTriggerDescription; import org.scijava.ui.behaviour.io.yaml.YamlConfigIO; +import org.scijava.ui.behaviour.util.AbstractNamedBehaviour; +import org.scijava.ui.behaviour.util.Behaviours; public class UsageExample { - static class MyDragBehaviour implements DragBehaviour + static class MyDragBehaviour extends AbstractNamedBehaviour implements DragBehaviour { - private final String name; - public MyDragBehaviour( final String name ) { - this.name = name; + super( name ); } @Override public void init( final int x, final int y ) { - System.out.println( name + ": init(" + x + ", " + y + ")" ); + System.out.println( name() + ": init(" + x + ", " + y + ")" ); } @Override public void drag( final int x, final int y ) { - System.out.println( name + ": drag(" + x + ", " + y + ")" ); + System.out.println( name() + ": drag(" + x + ", " + y + ")" ); } @Override public void end( final int x, final int y ) { - System.out.println( name + ": end(" + x + ", " + y + ")" ); + System.out.println( name() + ": end(" + x + ", " + y + ")" ); } } - static class MyClickBehaviour implements ClickBehaviour + static class MyClickBehaviour extends AbstractNamedBehaviour implements ClickBehaviour { - private final String name; - public MyClickBehaviour( final String name ) { - this.name = name; + super( name ); } @Override public void click( final int x, final int y ) { - System.out.println( name + ": click(" + x + ", " + y + ")" ); + System.out.println( name() + ": click(" + x + ", " + y + ")" ); } } - static class MyScrollBehaviour implements ScrollBehaviour + static class MyScrollBehaviour extends AbstractNamedBehaviour implements ScrollBehaviour { - private final String name; - public MyScrollBehaviour( final String name ) { - this.name = name; + super( name ); } @Override public void scroll( final double wheelRotation, final boolean isHorizontal, final int x, final int y ) { - System.out.println( name + ": scroll(" + wheelRotation + ", " + isHorizontal + ", " + x + ", " + y + ")" ); + System.out.println( name() + ": scroll(" + wheelRotation + ", " + isHorizontal + ", " + x + ", " + y + ")" ); } } @@ -153,16 +149,14 @@ public static void main( final String[] args ) /* * Create behaviours and input mappings. */ - behaviourMap.put( "drag1", new MyDragBehaviour( "drag1" ) ); - behaviourMap.put( "drag2", new MyDragBehaviour( "drag2" ) ); - behaviourMap.put( "scroll1", new MyScrollBehaviour( "scroll1" ) ); - behaviourMap.put( "click1", new MyClickBehaviour( "click1" ) ); - - final InputTriggerAdder adder = config.inputTriggerAdder( inputMap, "all" ); - adder.put( "drag1" ); // put input trigger as defined in config - adder.put( "drag2", "button1", "shift A | G" ); // default triggers if not defined in config - adder.put( "scroll1", "alt scroll" ); - adder.put( "click1", "button3", "B | all" ); + Behaviours behaviours = new Behaviours( inputMap, behaviourMap, config, "all" ); + behaviours.namedBehaviour( new MyDragBehaviour( "drag1" ) ); // put input trigger as defined in config + behaviours.namedBehaviour( new MyDragBehaviour( "drag2" ), + "button1", "shift A | G" ); // default triggers if not defined in config + behaviours.namedBehaviour( new MyScrollBehaviour( "scroll1" ), + "alt scroll" ); + behaviours.namedBehaviour( new MyClickBehaviour( "click1" ), + "button3", "B | all" ); /* * See org.scijava.ui.behaviour.util.InputActionBindings and From 7ba2ae56e2fa8f5dc5397ce9333c552d777cbb07 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sun, 11 Nov 2018 00:07:35 +0100 Subject: [PATCH 122/184] Bump to next development cycle Signed-off-by: tpietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3af0206..9ab9b3e 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.7.4-SNAPSHOT + 1.7.5-SNAPSHOT UI Behaviour Configurable key and mouse event handling From c359f026a55be004155bdb25e4acbfd3e204373e Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sun, 11 Nov 2018 00:16:20 +0100 Subject: [PATCH 123/184] add travis badge to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6ddadbe..02b487a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![](https://travis-ci.org/scijava/ui-behaviour.svg?branch=master)](https://travis-ci.org/scijava/ui-behaviour) + # configurable-keys Simplify making AWT mouse-handlers configurable. Works along the lines of the `InputMap` / `ActionMap` mechanism. From 44bab20edd3fe6a3f532dd42cd56a852d19d276c Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 4 Apr 2019 13:35:52 -0500 Subject: [PATCH 124/184] POM: use HTTPS where feasible --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9ab9b3e..378881b 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ 2015 SciJava - http://www.scijava.org/ + https://scijava.org/ From b55d15efb63d0402847b0ec7371365066a61d131 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 30 Apr 2019 17:04:50 -0500 Subject: [PATCH 125/184] POM: maven.imagej.net -> maven.scijava.org --- pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 378881b..df67dcd 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.scijava pom-scijava - 17.1.1 + 26.0.0 ui-behaviour @@ -100,14 +100,14 @@ Max Planck Institute of Molecular Cell Biology and Genetics. - - deploy-to-imagej + + deploy-to-scijava - imagej.public - https://maven.imagej.net/content/groups/public + scijava.public + https://maven.scijava.org/content/groups/public From e8575dd27ee44b147eed668ca2a446a14700cb9b Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 30 Apr 2019 17:04:50 -0500 Subject: [PATCH 126/184] Travis: build using openjdk8 --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5b37890..961356c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: java -jdk: oraclejdk8 +jdk: openjdk8 branches: only: - master From e88c53f78ecb5e122e4762770d6b75aa08de9699 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 30 Apr 2019 17:04:50 -0500 Subject: [PATCH 127/184] Travis: remove obsolete Maven settings --- .travis/settings.xml | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 .travis/settings.xml diff --git a/.travis/settings.xml b/.travis/settings.xml deleted file mode 100644 index 71a5630..0000000 --- a/.travis/settings.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - imagej.releases - travis - ${env.MAVEN_PASS} - - - imagej.snapshots - travis - ${env.MAVEN_PASS} - - - From 4777909f509cbf209538034efb5ec43cfb759c2a Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 22 Nov 2019 17:45:13 +0100 Subject: [PATCH 128/184] POM: update parent to pom-scijava 27.0.1 --- pom.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index df67dcd..6ce0cc7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.scijava pom-scijava - 26.0.0 + 27.0.1 ui-behaviour @@ -115,7 +115,6 @@ and Genetics. net.sf.trove4j trove4j - 3.0.3 com.google.code.gson @@ -124,7 +123,6 @@ and Genetics. org.yaml snakeyaml - 1.13 From ac1e792ae65bff91075bf334a13b4e5c80e84e01 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 22 Nov 2019 17:46:07 +0100 Subject: [PATCH 129/184] Support extending existing Input/ActionMap of a JComponent --- .../behaviour/util/InputActionBindings.java | 74 ++++++++++++++++++- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java index f81bb1a..9a459b6 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java @@ -41,6 +41,7 @@ import javax.swing.ComponentInputMap; import javax.swing.InputMap; import javax.swing.JComponent; +import javax.swing.SwingUtilities; /** * Maintains lists of {@link ActionMap}s and {@link InputMap}s, which are @@ -50,7 +51,7 @@ * overrides all previous ones. For added {@link InputMap}s it is possible to * block maps that were added earlier. * - * @author Tobias Pietzsch <tobias.pietzsch@gmail.com> + * @author Tobias Pietzsch */ public final class InputActionBindings { @@ -64,6 +65,16 @@ public final class InputActionBindings */ private final ActionMap theActionMap; + /** + * parent for the {@link #getConcatenatedInputMap() concatenated InputMap}. + */ + private InputMap parentInputMap; + + /** + * parent for the {@link #getConcatenatedActionMap()} () concatenated ActionMap}. + */ + private ActionMap parentActionMap; + private final List< Actions > actions; private final List< Keys > inputs; @@ -134,6 +145,16 @@ public void removeActionMap( final String id ) updateTheActionMap(); } + /** + * Set existing parent ActionMap, which is managed outside of this + * InputActionBindings and serves as a parent for the whole chain. + */ + public void setParentActionMap( final ActionMap parent ) + { + parentActionMap = parent; + updateTheActionMap(); + } + /** * Adds a {@link InputMap} with the specified id to the end of the list * (overrides maps that were added earlier). If the specified id already @@ -236,6 +257,16 @@ public void removeInputMap( final String id ) updateTheInputMap(); } + /** + * Set existing parent InputMap, which is managed outside of this + * InputActionBindings and serves as a parent for the whole chain. + */ + public void setParentInputMap( final InputMap parent ) + { + parentInputMap = parent; + updateTheInputMap(); + } + /** * Get the chained {@link InputMap}. This is the leaf map, that has all * {@link #addInputMap(String, InputMap, String...) added} {@link InputMap}s @@ -258,6 +289,38 @@ public ActionMap getConcatenatedActionMap() return theActionMap; } + /** + * Creates a new {@code InputActionBindings} and installs it into + * {@code component}, either augmenting or replacing {@code component}s + * existing {@code InputMap} and {@code ActionMap}. + * + * @param component + * the component whose {@code InputMap} and {@code ActionMap} to set. + * @param condition + * one of {@code JComponent.WHEN_IN_FOCUSED_WINDOW}, + * {@code WHEN_IN_FOCUSED_WINDOW}, + * {@code WHEN_ANCESTOR_OF_FOCUSED_COMPONENT}. + * @param replaceExistingMaps + * if {@code true}, the existing {@code InputMap} and {@code ActionMap} + * will be replaced. If {@code false}, the existing maps will become the + * parents of the new ones. + * @return the new {@code InputActionBindings} + */ + public static InputActionBindings installNewBindings( final JComponent component, final int condition, final boolean replaceExistingMaps ) + { + final InputActionBindings keybindings = new InputActionBindings(); + if ( !replaceExistingMaps ) + { + final ActionMap existingActionMap = component.getActionMap(); + final InputMap existingInputMap = component.getInputMap( condition ); + keybindings.setParentActionMap( existingActionMap.getParent() ); + keybindings.setParentInputMap( existingInputMap.getParent() ); + } + SwingUtilities.replaceUIActionMap( component, keybindings.getConcatenatedActionMap() ); + SwingUtilities.replaceUIInputMap( component, condition, keybindings.getConcatenatedInputMap() ); + return keybindings; + } + private interface WithId { public String getId(); @@ -343,7 +406,7 @@ private void updateTheActionMap() root = map; } } - root.setParent( null ); + root.setParent( parentActionMap ); } private void updateTheInputMap() @@ -367,8 +430,11 @@ private void updateTheInputMap() blocked.addAll( keys.getKeysIdsToBlock() ); if ( blocked.contains( "all" ) ) - break; + { + root.setParent( null ); + return; + } } - root.setParent( null ); + root.setParent( parentInputMap ); } } From 82892762642715c9304f444e05a8c9131149acc4 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 22 Nov 2019 17:50:00 +0100 Subject: [PATCH 130/184] Bump to next development cycle Signed-off-by: tpietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6ce0cc7..1227e34 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.7.5-SNAPSHOT + 1.7.6-SNAPSHOT UI Behaviour Configurable key and mouse event handling From b721e302d1f7f745137edd53b89507aa707938f1 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 27 Nov 2019 00:09:42 +0100 Subject: [PATCH 131/184] Remove unnecessary boxing --- .../scijava/ui/behaviour/InputTrigger.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java index af8ae81..85b0067 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java @@ -522,29 +522,29 @@ private synchronized static Map getModifierKeywords() { final Map< String, Integer > uninitializedMap = new HashMap<>( 8, 1.0f ); uninitializedMap.put( "shift", - Integer.valueOf( InputEvent.SHIFT_DOWN_MASK ) ); + InputEvent.SHIFT_DOWN_MASK ); uninitializedMap.put( "control", - Integer.valueOf( InputEvent.CTRL_DOWN_MASK ) ); + InputEvent.CTRL_DOWN_MASK ); uninitializedMap.put( "ctrl", - Integer.valueOf( InputEvent.CTRL_DOWN_MASK ) ); + InputEvent.CTRL_DOWN_MASK ); uninitializedMap.put( "meta", - Integer.valueOf( InputEvent.META_DOWN_MASK ) ); + InputEvent.META_DOWN_MASK ); uninitializedMap.put( "alt", - Integer.valueOf( InputEvent.ALT_DOWN_MASK ) ); + InputEvent.ALT_DOWN_MASK ); uninitializedMap.put( "altGraph", - Integer.valueOf( InputEvent.ALT_GRAPH_DOWN_MASK ) ); + InputEvent.ALT_GRAPH_DOWN_MASK ); uninitializedMap.put( "button1", - Integer.valueOf( InputEvent.BUTTON1_DOWN_MASK ) ); + InputEvent.BUTTON1_DOWN_MASK ); uninitializedMap.put( "button2", - Integer.valueOf( InputEvent.BUTTON2_DOWN_MASK ) ); + InputEvent.BUTTON2_DOWN_MASK ); uninitializedMap.put( "button3", - Integer.valueOf( InputEvent.BUTTON3_DOWN_MASK ) ); + InputEvent.BUTTON3_DOWN_MASK ); uninitializedMap.put( DOUBLE_CLICK_TEXT, - Integer.valueOf( DOUBLE_CLICK_MASK ) ); + DOUBLE_CLICK_MASK ); uninitializedMap.put( SCROLL_TEXT, - Integer.valueOf( SCROLL_MASK ) ); + SCROLL_MASK ); uninitializedMap.put( WINDOWS_TEXT, - Integer.valueOf( WIN_DOWN_MASK ) ); + WIN_DOWN_MASK ); modifierKeywords = Collections.synchronizedMap( uninitializedMap ); } From 5cd15500b68d71b179e24b848e4fd39e451e2223 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 29 Nov 2019 17:31:43 +0100 Subject: [PATCH 132/184] Replicate InputEvent constants in InputTrigger --- .../scijava/ui/behaviour/InputTrigger.java | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java index 85b0067..f7a1771 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java @@ -53,11 +53,18 @@ */ public class InputTrigger { - public static final int DOUBLE_CLICK_MASK = 1 << 20; - - public static final int SCROLL_MASK = 1 << 21; - - public static final int WIN_DOWN_MASK = 1 << 22; + public static final int SHIFT_DOWN_MASK = 1 << 6; // == InputEvent.SHIFT_DOWN_MASK + public static final int CTRL_DOWN_MASK = 1 << 7; // == InputEvent.CTRL_DOWN_MASK + public static final int META_DOWN_MASK = 1 << 8; // == InputEvent.META_DOWN_MASK + public static final int ALT_DOWN_MASK = 1 << 9; // == InputEvent.ALT_DOWN_MASK + public static final int BUTTON1_DOWN_MASK = 1 << 10; // == InputEvent.BUTTON1_DOWN_MASK + public static final int BUTTON2_DOWN_MASK = 1 << 11; // == InputEvent.BUTTON2_DOWN_MASK + public static final int BUTTON3_DOWN_MASK = 1 << 12; // == InputEvent.BUTTON3_DOWN_MASK + public static final int ALT_GRAPH_DOWN_MASK = 1 << 13; // == InputEvent.ALT_GRAPH_DOWN_MASK + + public static final int DOUBLE_CLICK_MASK = 1 << 20; + public static final int SCROLL_MASK = 1 << 21; + public static final int WIN_DOWN_MASK = 1 << 22; public static final int IGNORE_MASK = -1; @@ -147,7 +154,7 @@ public static InputTrigger getFromString( final String s ) throws IllegalArgumen * TODO: KeyStroke only if no ignore keys are given???? */ KeyStroke keyStroke = null; - if ( ( mask & ( DOUBLE_CLICK_MASK | InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON2_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK ) ) == 0 ) + if ( ( mask & ( DOUBLE_CLICK_MASK | BUTTON1_DOWN_MASK | BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK ) ) == 0 ) { // no mouse keys, no double-click -- pure keystroke // This might still fail if for example "win" modifier is present. @@ -333,7 +340,7 @@ public TIntCollection getPressedKeys() public boolean isKeyTriggered() { - return ( mask & ( InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON2_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK | SCROLL_MASK ) ) == 0; + return ( mask & ( BUTTON1_DOWN_MASK | BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK | SCROLL_MASK ) ) == 0; } public boolean isKeyStroke() @@ -487,14 +494,14 @@ private void addKeys( final TIntSet keys, final StringBuilder buf ) private void addModifierTexts( final int mask, final StringBuilder buf ) { - addModifierText( mask, InputEvent.SHIFT_DOWN_MASK, "shift", buf ); - addModifierText( mask, InputEvent.CTRL_DOWN_MASK, "ctrl", buf ); - addModifierText( mask, InputEvent.META_DOWN_MASK, "meta", buf ); - addModifierText( mask, InputEvent.ALT_DOWN_MASK, "alt", buf ); - addModifierText( mask, InputEvent.ALT_GRAPH_DOWN_MASK, "altGraph", buf ); - addModifierText( mask, InputEvent.BUTTON1_DOWN_MASK, "button1", buf ); - addModifierText( mask, InputEvent.BUTTON2_DOWN_MASK, "button2", buf ); - addModifierText( mask, InputEvent.BUTTON3_DOWN_MASK, "button3", buf ); + addModifierText( mask, SHIFT_DOWN_MASK, "shift", buf ); + addModifierText( mask, CTRL_DOWN_MASK, "ctrl", buf ); + addModifierText( mask, META_DOWN_MASK, "meta", buf ); + addModifierText( mask, ALT_DOWN_MASK, "alt", buf ); + addModifierText( mask, ALT_GRAPH_DOWN_MASK, "altGraph", buf ); + addModifierText( mask, BUTTON1_DOWN_MASK, "button1", buf ); + addModifierText( mask, BUTTON2_DOWN_MASK, "button2", buf ); + addModifierText( mask, BUTTON3_DOWN_MASK, "button3", buf ); addModifierText( mask, DOUBLE_CLICK_MASK, DOUBLE_CLICK_TEXT, buf ); addModifierText( mask, SCROLL_MASK, SCROLL_TEXT, buf ); addModifierText( mask, WIN_DOWN_MASK, WINDOWS_TEXT, buf ); @@ -522,23 +529,23 @@ private synchronized static Map getModifierKeywords() { final Map< String, Integer > uninitializedMap = new HashMap<>( 8, 1.0f ); uninitializedMap.put( "shift", - InputEvent.SHIFT_DOWN_MASK ); + SHIFT_DOWN_MASK ); uninitializedMap.put( "control", - InputEvent.CTRL_DOWN_MASK ); + CTRL_DOWN_MASK ); uninitializedMap.put( "ctrl", - InputEvent.CTRL_DOWN_MASK ); + CTRL_DOWN_MASK ); uninitializedMap.put( "meta", - InputEvent.META_DOWN_MASK ); + META_DOWN_MASK ); uninitializedMap.put( "alt", - InputEvent.ALT_DOWN_MASK ); + ALT_DOWN_MASK ); uninitializedMap.put( "altGraph", - InputEvent.ALT_GRAPH_DOWN_MASK ); + ALT_GRAPH_DOWN_MASK ); uninitializedMap.put( "button1", - InputEvent.BUTTON1_DOWN_MASK ); + BUTTON1_DOWN_MASK ); uninitializedMap.put( "button2", - InputEvent.BUTTON2_DOWN_MASK ); + BUTTON2_DOWN_MASK ); uninitializedMap.put( "button3", - InputEvent.BUTTON3_DOWN_MASK ); + BUTTON3_DOWN_MASK ); uninitializedMap.put( DOUBLE_CLICK_TEXT, DOUBLE_CLICK_MASK ); uninitializedMap.put( SCROLL_TEXT, From 470f6c9a5c63b9aa31f2115b533ab76b9e666ce9 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 29 Nov 2019 17:46:38 +0100 Subject: [PATCH 133/184] Split MouseAndKeyHandler class AbstractMouseAndKeyHandler maintains internal behaviour lists from InputTrigger/Behaviour maps. This is split from the AWT/Swing specific MouseAndKeyHandler, so that it can be shared by other implementations, e.g., for JavaFX. --- .../behaviour/AbstractMouseAndKeyHandler.java | 151 +++++++++++++ .../ui/behaviour/MouseAndKeyHandler.java | 203 +++--------------- 2 files changed, 184 insertions(+), 170 deletions(-) create mode 100644 src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java diff --git a/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java new file mode 100644 index 0000000..e866c73 --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java @@ -0,0 +1,151 @@ +package org.scijava.ui.behaviour; + +import java.awt.Toolkit; +import java.util.ArrayList; +import java.util.Map; +import java.util.Set; + +public abstract class AbstractMouseAndKeyHandler +{ + protected static final int DOUBLE_CLICK_INTERVAL = getDoubleClickInterval(); + + private static int getDoubleClickInterval() + { + final Object prop = Toolkit.getDefaultToolkit().getDesktopProperty( "awt.multiClickInterval" ); + return prop == null ? 200 : ( Integer ) prop; + } + + private InputTriggerMap inputMap; + + private BehaviourMap behaviourMap; + + private int inputMapExpectedModCount; + + private int behaviourMapExpectedModCount; + + public void setInputMap( final InputTriggerMap inputMap ) + { + this.inputMap = inputMap; + inputMapExpectedModCount = inputMap.modCount() - 1; + } + + public void setBehaviourMap( final BehaviourMap behaviourMap ) + { + this.behaviourMap = behaviourMap; + behaviourMapExpectedModCount = behaviourMap.modCount() - 1; + } + + /* + * Managing internal behaviour lists. + * + * The internal lists only contain entries for Behaviours that can be + * actually triggered with the current InputMap, grouped by Behaviour type, + * such that hopefully lookup from the event handlers is fast, + */ + + protected static class BehaviourEntry< T extends Behaviour > + { + private final InputTrigger buttons; + + private final T behaviour; + + public BehaviourEntry( + final InputTrigger buttons, + final T behaviour ) + { + this.buttons = buttons; + this.behaviour = behaviour; + } + + public InputTrigger buttons() + { + return buttons; + } + + public T behaviour() + { + return behaviour; + } + } + + protected final ArrayList< BehaviourEntry< DragBehaviour > > buttonDrags = new ArrayList<>(); + + protected final ArrayList< BehaviourEntry< DragBehaviour > > keyDrags = new ArrayList<>(); + + protected final ArrayList< BehaviourEntry< ClickBehaviour > > buttonClicks = new ArrayList<>(); + + protected final ArrayList< BehaviourEntry< ClickBehaviour > > keyClicks = new ArrayList<>(); + + protected final ArrayList< BehaviourEntry< ScrollBehaviour > > scrolls = new ArrayList<>(); + + /** + * Make sure that the internal behaviour lists are up to date. For this, we + * keep track the modification count of {@link #inputMap} and + * {@link #behaviourMap}. If expected mod counts are not matched, call + * {@link #updateInternalMaps()} to rebuild the internal behaviour lists. + */ + protected synchronized void update() + { + final int imc = inputMap.modCount(); + final int bmc = behaviourMap.modCount(); + if ( imc != inputMapExpectedModCount || bmc != behaviourMapExpectedModCount ) + { + inputMapExpectedModCount = imc; + behaviourMapExpectedModCount = bmc; + updateInternalMaps(); + } + } + + /** + * Build internal lists buttonDrag, keyDrags, etc from of {@link #inputMap} + * and {@link #behaviourMap}. The internal lists only contain entries for + * behaviours that can be actually triggered with the current InputMap, + * grouped by behaviour type, such that hopefully lookup from the event + * handlers is fast. + */ + private void updateInternalMaps() + { + buttonDrags.clear(); + keyDrags.clear(); + buttonClicks.clear(); + keyClicks.clear(); + scrolls.clear(); + + for ( final Map.Entry< InputTrigger, Set< String > > entry : inputMap.getAllBindings().entrySet() ) + { + final InputTrigger buttons = entry.getKey(); + final Set< String > behaviourKeys = entry.getValue(); + if ( behaviourKeys == null ) + continue; + + for ( final String behaviourKey : behaviourKeys ) + { + final Behaviour behaviour = behaviourMap.get( behaviourKey ); + if ( behaviour == null ) + continue; + + if ( behaviour instanceof DragBehaviour ) + { + final BehaviourEntry< DragBehaviour > dragEntry = new BehaviourEntry<>( buttons, ( DragBehaviour ) behaviour ); + if ( buttons.isKeyTriggered() ) + keyDrags.add( dragEntry ); + else + buttonDrags.add( dragEntry ); + } + if ( behaviour instanceof ClickBehaviour ) + { + final BehaviourEntry< ClickBehaviour > clickEntry = new BehaviourEntry<>( buttons, ( ClickBehaviour ) behaviour ); + if ( buttons.isKeyTriggered() ) + keyClicks.add( clickEntry ); + else + buttonClicks.add( clickEntry ); + } + if ( behaviour instanceof ScrollBehaviour ) + { + final BehaviourEntry< ScrollBehaviour > scrollEntry = new BehaviourEntry<>( buttons, ( ScrollBehaviour ) behaviour ); + scrolls.add( scrollEntry ); + } + } + } + } +} diff --git a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java index 1d084ab..1aa4236 100644 --- a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java @@ -7,13 +7,13 @@ * %% * 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 @@ -30,7 +30,6 @@ package org.scijava.ui.behaviour; import java.awt.Component; -import java.awt.Toolkit; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.InputEvent; @@ -42,8 +41,6 @@ import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.util.ArrayList; -import java.util.Map.Entry; -import java.util.Set; import org.scijava.ui.behaviour.KeyPressedManager.KeyPressedReceiver; @@ -51,149 +48,15 @@ import gnu.trove.set.TIntSet; import gnu.trove.set.hash.TIntHashSet; -public class MouseAndKeyHandler +public class MouseAndKeyHandler extends AbstractMouseAndKeyHandler implements KeyListener, MouseListener, MouseWheelListener, MouseMotionListener, FocusListener { - private static final int DOUBLE_CLICK_INTERVAL = getDoubleClickInterval(); - private static final int OSX_META_LEFT_CLICK = InputEvent.BUTTON1_MASK | InputEvent.BUTTON3_MASK | InputEvent.META_MASK; private static final int OSX_ALT_LEFT_CLICK = InputEvent.BUTTON1_MASK | InputEvent.BUTTON2_MASK | InputEvent.ALT_MASK; private static final int OSX_ALT_RIGHT_CLICK = InputEvent.BUTTON3_MASK | InputEvent.BUTTON2_MASK | InputEvent.ALT_MASK | InputEvent.META_MASK; - private static int getDoubleClickInterval() - { - final Object prop = Toolkit.getDefaultToolkit().getDesktopProperty( "awt.multiClickInterval" ); - return prop == null ? 200 : ( Integer ) prop; - } - - private InputTriggerMap inputMap; - - private BehaviourMap behaviourMap; - - private int inputMapExpectedModCount; - - private int behaviourMapExpectedModCount; - - public void setInputMap( final InputTriggerMap inputMap ) - { - this.inputMap = inputMap; - inputMapExpectedModCount = inputMap.modCount() - 1; - } - - public void setBehaviourMap( final BehaviourMap behaviourMap ) - { - this.behaviourMap = behaviourMap; - behaviourMapExpectedModCount = behaviourMap.modCount() - 1; - } - - /* - * Managing internal behaviour lists. - * - * The internal lists only contain entries for Behaviours that can be - * actually triggered with the current InputMap, grouped by Behaviour type, - * such that hopefully lookup from the event handlers is fast, - */ - - static class BehaviourEntry< T extends Behaviour > - { - final InputTrigger buttons; - - final T behaviour; - - BehaviourEntry( - final InputTrigger buttons, - final T behaviour ) - { - this.buttons = buttons; - this.behaviour = behaviour; - } - } - - private final ArrayList< BehaviourEntry< DragBehaviour > > buttonDrags = new ArrayList<>(); - - private final ArrayList< BehaviourEntry< DragBehaviour > > keyDrags = new ArrayList<>(); - - private final ArrayList< BehaviourEntry< ClickBehaviour > > buttonClicks = new ArrayList<>(); - - private final ArrayList< BehaviourEntry< ClickBehaviour > > keyClicks = new ArrayList<>(); - - private final ArrayList< BehaviourEntry< ScrollBehaviour > > scrolls = new ArrayList<>(); - - /** - * Make sure that the internal behaviour lists are up to date. For this, we - * keep track the modification count of {@link #inputMap} and - * {@link #behaviourMap}. If expected mod counts are not matched, call - * {@link #updateInternalMaps()} to rebuild the internal behaviour lists. - */ - private synchronized void update() - { - final int imc = inputMap.modCount(); - final int bmc = behaviourMap.modCount(); - if ( imc != inputMapExpectedModCount || bmc != behaviourMapExpectedModCount ) - { - inputMapExpectedModCount = imc; - behaviourMapExpectedModCount = bmc; - updateInternalMaps(); - } - } - - /** - * Build internal lists buttonDrag, keyDrags, etc from of {@link #inputMap} - * and {@link #behaviourMap}. The internal lists only contain entries for - * behaviours that can be actually triggered with the current InputMap, - * grouped by behaviour type, such that hopefully lookup from the event - * handlers is fast. - */ - private void updateInternalMaps() - { - buttonDrags.clear(); - keyDrags.clear(); - buttonClicks.clear(); - keyClicks.clear(); - scrolls.clear(); - - for ( final Entry< InputTrigger, Set< String > > entry : inputMap.getAllBindings().entrySet() ) - { - final InputTrigger buttons = entry.getKey(); - final Set< String > behaviourKeys = entry.getValue(); - if ( behaviourKeys == null ) - continue; - - for ( final String behaviourKey : behaviourKeys ) - { - final Behaviour behaviour = behaviourMap.get( behaviourKey ); - if ( behaviour == null ) - continue; - - if ( behaviour instanceof DragBehaviour ) - { - final BehaviourEntry< DragBehaviour > dragEntry = new BehaviourEntry<>( buttons, ( DragBehaviour ) behaviour ); - if ( buttons.isKeyTriggered() ) - keyDrags.add( dragEntry ); - else - buttonDrags.add( dragEntry ); - } - if ( behaviour instanceof ClickBehaviour ) - { - final BehaviourEntry< ClickBehaviour > clickEntry = new BehaviourEntry<>( buttons, ( ClickBehaviour ) behaviour ); - if ( buttons.isKeyTriggered() ) - keyClicks.add( clickEntry ); - else - buttonClicks.add( clickEntry ); - } - if ( behaviour instanceof ScrollBehaviour ) - { - final BehaviourEntry< ScrollBehaviour > scrollEntry = new BehaviourEntry<>( buttons, ( ScrollBehaviour ) behaviour ); - scrolls.add( scrollEntry ); - } - } - } - } - - - /* * Event handling. Forwards to registered behaviours. */ @@ -242,9 +105,9 @@ private int getMask( final InputEvent e ) * We keep track of whether the SHIFT key was actually pressed for disambiguation. */ if ( globalKeys.shiftPressed() ) - mask |= InputEvent.SHIFT_DOWN_MASK; + mask |= InputTrigger.SHIFT_DOWN_MASK; else - mask &= ~InputEvent.SHIFT_DOWN_MASK; + mask &= ~InputTrigger.SHIFT_DOWN_MASK; /* * On OS X AWT sets the META_DOWN_MASK to for right clicks. We keep @@ -252,9 +115,9 @@ private int getMask( final InputEvent e ) * disambiguation. */ if ( globalKeys.metaPressed() ) - mask |= InputEvent.META_DOWN_MASK; + mask |= InputTrigger.META_DOWN_MASK; else - mask &= ~InputEvent.META_DOWN_MASK; + mask &= ~InputTrigger.META_DOWN_MASK; if ( globalKeys.winPressed() ) mask |= InputTrigger.WIN_DOWN_MASK; @@ -276,11 +139,11 @@ private int getMask( final InputEvent e ) if ( e.getID() != MouseEvent.MOUSE_WHEEL && e.getID() != MouseEvent.MOUSE_RELEASED ) { if ( ( modifiers & InputEvent.BUTTON1_MASK ) != 0 ) - mask |= InputEvent.BUTTON1_DOWN_MASK; + mask |= InputTrigger.BUTTON1_DOWN_MASK; if ( ( modifiers & InputEvent.BUTTON2_MASK ) != 0 ) - mask |= InputEvent.BUTTON2_DOWN_MASK; + mask |= InputTrigger.BUTTON2_DOWN_MASK; if ( ( modifiers & InputEvent.BUTTON3_MASK ) != 0 ) - mask |= InputEvent.BUTTON3_DOWN_MASK; + mask |= InputTrigger.BUTTON3_DOWN_MASK; } /* @@ -288,21 +151,21 @@ private int getMask( final InputEvent e ) * that. */ if ( modifiers == OSX_META_LEFT_CLICK ) - mask &= ~InputEvent.BUTTON3_DOWN_MASK; + mask &= ~InputTrigger.BUTTON3_DOWN_MASK; /* * On OS X AWT sets the BUTTON2_DOWN_MASK for alt+left clicks. Fix * that. */ if ( modifiers == OSX_ALT_LEFT_CLICK ) - mask &= ~InputEvent.BUTTON2_DOWN_MASK; + mask &= ~InputTrigger.BUTTON2_DOWN_MASK; /* * On OS X AWT sets the BUTTON2_DOWN_MASK for alt+right clicks. Fix * that. */ if ( modifiers == OSX_ALT_RIGHT_CLICK ) - mask &= ~InputEvent.BUTTON2_DOWN_MASK; + mask &= ~InputTrigger.BUTTON2_DOWN_MASK; /* * Deal with mouse double-clicks. @@ -335,7 +198,7 @@ public void mouseDragged( final MouseEvent e ) mouseY = e.getY(); for ( final BehaviourEntry< DragBehaviour > drag : activeButtonDrags ) - drag.behaviour.drag( mouseX, mouseY ); + drag.behaviour().drag( mouseX, mouseY ); } @Override @@ -348,7 +211,7 @@ public void mouseMoved( final MouseEvent e ) mouseY = e.getY(); for ( final BehaviourEntry< DragBehaviour > drag : activeKeyDrags ) - drag.behaviour.drag( mouseX, mouseY ); + drag.behaviour().drag( mouseX, mouseY ); } @Override @@ -370,14 +233,14 @@ public void mouseWheelMoved( final MouseWheelEvent e ) * the SHIFT key is not pressed. With SHIFT pressed, everything is * treated as vertical scrolling. */ - final boolean exShiftMask = ( e.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK ) != 0; + final boolean exShiftMask = ( e.getModifiersEx() & InputTrigger.SHIFT_DOWN_MASK ) != 0; final boolean isHorizontal = !globalKeys.shiftPressed() && exShiftMask; for ( final BehaviourEntry< ScrollBehaviour > scroll : scrolls ) { - if ( scroll.buttons.matches( mask, globalKeys.pressedKeys() ) ) + if ( scroll.buttons().matches( mask, globalKeys.pressedKeys() ) ) { - scroll.behaviour.scroll( wheelRotation, isHorizontal, x, y ); + scroll.behaviour().scroll( wheelRotation, isHorizontal, x, y ); } } } @@ -396,10 +259,10 @@ public void mouseClicked( final MouseEvent e ) final int clickMask = mask & ~InputTrigger.DOUBLE_CLICK_MASK; for ( final BehaviourEntry< ClickBehaviour > click : buttonClicks ) { - if ( click.buttons.matches( mask, pressedKeys ) || - ( clickMask != mask && click.buttons.matches( clickMask, pressedKeys ) ) ) + if ( click.buttons().matches( mask, pressedKeys ) || + ( clickMask != mask && click.buttons().matches( clickMask, pressedKeys ) ) ) { - click.behaviour.click( x, y ); + click.behaviour().click( x, y ); } } } @@ -417,9 +280,9 @@ public void mousePressed( final MouseEvent e ) for ( final BehaviourEntry< DragBehaviour > drag : buttonDrags ) { - if ( drag.buttons.matches( mask, globalKeys.pressedKeys() ) ) + if ( drag.buttons().matches( mask, globalKeys.pressedKeys() ) ) { - drag.behaviour.init( x, y ); + drag.behaviour().init( x, y ); activeButtonDrags.add( drag ); } } @@ -438,9 +301,9 @@ public void mouseReleased( final MouseEvent e ) final ArrayList< BehaviourEntry< ? > > ended = new ArrayList<>(); for ( final BehaviourEntry< DragBehaviour > drag : activeButtonDrags ) - if ( !drag.buttons.matchesSubset( mask, globalKeys.pressedKeys() ) ) + if ( !drag.buttons().matchesSubset( mask, globalKeys.pressedKeys() ) ) { - drag.behaviour.end( x, y ); + drag.behaviour().end( x, y ); ended.add( drag ); } activeButtonDrags.removeAll( ended ); @@ -574,26 +437,26 @@ private boolean handleKeyPressed( final int mask, final boolean doubleClick, fin for ( final BehaviourEntry< DragBehaviour > drag : keyDrags ) { if ( !activeKeyDrags.contains( drag ) && - ( drag.buttons.matches( mask, pressedKeys ) || - ( doubleClick && drag.buttons.matches( doubleClickMask, pressedKeys ) ) ) ) + ( drag.buttons().matches( mask, pressedKeys ) || + ( doubleClick && drag.buttons().matches( doubleClickMask, pressedKeys ) ) ) ) { if ( dryRun ) return true; triggered = true; - drag.behaviour.init( mouseX, mouseY ); + drag.behaviour().init( mouseX, mouseY ); activeKeyDrags.add( drag ); } } for ( final BehaviourEntry< ClickBehaviour > click : keyClicks ) { - if ( click.buttons.matches( mask, pressedKeys ) || - ( doubleClick && click.buttons.matches( doubleClickMask, pressedKeys ) ) ) + if ( click.buttons().matches( mask, pressedKeys ) || + ( doubleClick && click.buttons().matches( doubleClickMask, pressedKeys ) ) ) { if ( dryRun ) return true; triggered = true; - click.behaviour.click( mouseX, mouseY ); + click.behaviour().click( mouseX, mouseY ); } } @@ -620,9 +483,9 @@ public void keyReleased( final KeyEvent e ) final ArrayList< BehaviourEntry< ? > > ended = new ArrayList<>(); for ( final BehaviourEntry< DragBehaviour > drag : activeKeyDrags ) - if ( !drag.buttons.matchesSubset( mask, pressedKeys ) ) + if ( !drag.buttons().matchesSubset( mask, pressedKeys ) ) { - drag.behaviour.end( mouseX, mouseY ); + drag.behaviour().end( mouseX, mouseY ); ended.add( drag ); } activeKeyDrags.removeAll( ended ); From 91e775b7dc8b0191f696fdf7313adec55cac25a9 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 29 Nov 2019 18:09:49 +0100 Subject: [PATCH 134/184] Pass origin of event to KeyPressedReceiver.handleKeyPressed() --- pom.xml | 2 +- .../ui/behaviour/KeyPressedManager.java | 23 ++++++++----------- .../ui/behaviour/MouseAndKeyHandler.java | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/pom.xml b/pom.xml index 1227e34..42e144f 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 1.7.6-SNAPSHOT + 2.0.0-SNAPSHOT UI Behaviour Configurable key and mouse event handling diff --git a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java index e74c66b..1470c6d 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java @@ -7,13 +7,13 @@ * %% * 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 @@ -29,24 +29,21 @@ */ package org.scijava.ui.behaviour; -import java.awt.event.KeyListener; - import gnu.trove.set.TIntSet; /** - * Distributes {@link KeyListener#keyPressed(java.awt.event.KeyEvent)} events - * between windows that share the same {@link KeyPressedManager}. The goal is to - * make keyboard click/drag behaviours work like mouse click/drag: When a - * behaviour is initiated with a key press, the window under the mouse receives - * focus and the behaviour is handled there. + * Distributes KEY_PRESSED events between windows that share the same + * {@link KeyPressedManager}. The goal is to make keyboard click/drag behaviours + * work like mouse click/drag: When a behaviour is initiated with a key press, + * the window under the mouse receives focus and the behaviour is handled there. * - * @author Tobias Pietzsch <tobias.pietzsch@gmail.com> + * @author Tobias Pietzsch */ public class KeyPressedManager { public interface KeyPressedReceiver { - public void handleKeyPressed( final int mask, final boolean doubleClick, final TIntSet pressedKeys ); + void handleKeyPressed( final KeyPressedReceiver origin, final int mask, final boolean doubleClick, final TIntSet pressedKeys ); } private KeyPressedReceiver active = null; @@ -58,9 +55,9 @@ public void handleKeyPressed( final TIntSet pressedKeys ) { if ( active != null ) - active.handleKeyPressed( mask, doubleClick, pressedKeys ); + active.handleKeyPressed( origin, mask, doubleClick, pressedKeys ); else - origin.handleKeyPressed( mask, doubleClick, pressedKeys ); + origin.handleKeyPressed( origin, mask, doubleClick, pressedKeys ); } public void activate( final KeyPressedReceiver handler) diff --git a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java index 1aa4236..c6e1f18 100644 --- a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java @@ -396,7 +396,7 @@ public void setKeypressManager( this.receiver = new KeyPressedReceiver() { @Override - public void handleKeyPressed( final int mask, final boolean doubleClick, final TIntSet pressedKeys ) + public void handleKeyPressed( final KeyPressedReceiver origin, final int mask, final boolean doubleClick, final TIntSet pressedKeys ) { if ( MouseAndKeyHandler.this.handleKeyPressed( mask, doubleClick, pressedKeys, true ) ) focus.run(); From 54d027083a0723ab4b59308f8b5e65d6d57db33f Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 29 Nov 2019 18:26:25 +0100 Subject: [PATCH 135/184] Fix javadoc --- src/main/java/org/scijava/ui/behaviour/InputTrigger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java index f7a1771..3781bff 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java @@ -88,7 +88,7 @@ public class InputTrigger private static final String WINDOWS_TEXT= "win"; /** - * String used to specify a special {@value #NOT_MAPPED} trigger that blocks + * String used to specify a special {@code NOT_MAPPED} trigger that blocks * all triggers for an action. */ private static final String NOT_MAPPED_TEXT = "not mapped"; From 6ed2e856f017b005e737603fac63f135bd504c29 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 29 Nov 2019 18:53:05 +0100 Subject: [PATCH 136/184] Bump to next development cycle Signed-off-by: tpietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 42e144f..3aec2df 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 2.0.0-SNAPSHOT + 2.0.1-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 065c11a452306aa85d09a7d6c2db25531e5b16dd Mon Sep 17 00:00:00 2001 From: Jean-Yves Tinevez Date: Tue, 17 Dec 2019 17:46:14 +0100 Subject: [PATCH 137/184] Add some javafocs. - From the github repo. - From a conversation with Tobias Pietzsch on gitter, 16/12/2019. --- .../scijava/ui/behaviour/package-info.java | 251 ++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 src/main/java/org/scijava/ui/behaviour/package-info.java diff --git a/src/main/java/org/scijava/ui/behaviour/package-info.java b/src/main/java/org/scijava/ui/behaviour/package-info.java new file mode 100644 index 0000000..c4b4bb7 --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/package-info.java @@ -0,0 +1,251 @@ +/** + *

Configurable-keys

Simplify making AWT mouse-handlers configurable. + * + * Works along the lines of the InputMap / ActionMap mechanism. The syntax for + * defining key and mouse "triggers" is described in the InputTrigger-syntax + * wiki page InputTrigger-syntax + * wiki page. They are also repeated below. + * + *

Overview

+ * + * ui-behaviour is a library for binding behaviours by keys or mouse-actions. + * The idea is similar to Swing's InputMap/ActionMap framework. The difference + * is that actions are atomic while behaviours (possibly) stretch over a period + * of time. For example, a DragBehaviour is initialized (e.g., with a mouse + * click) at certain coordinates, goes through a series of coordinate updates, + * and then ends (when the mouse is released). + *

+ * The combination of modifiers, keys, mouse buttons etc. that initiates a + * behaviour is called a "trigger" and is constructed from a string description. + *

+ * The basic syntax for a trigger description is a sequence of modifier and key + * names separated by whitespace. Examples are SPACE, button1, shift alt scroll, + * and ctrl F G. + *

+ * Additionally, one can specify a combination of modifiers, keys, mouse buttons + * etc. that should be ignored when triggering the behaviour. This is a another + * sequence of modifier and key names separated from the trigger description by + * "|". For example, ctrl button1 | shift alt is triggered by pressing the left + * mouse-button while holding the ctrl key. If the shift and/or alt key are + * pressed simultaneously, the trigger still matches. To ignore all other + * modifiers and keys, the special name all is used. So, A | all is a trigger + * that matches when the A key is pressed, regardless which other modifiers, + * keys, or buttons are active at the same time. + * + * + *

Chaining principle.

+ * + * In Swing, a JComponent has an InputMap. Each InputMap can have a parent, and + * if a mapping for a given key is not found in the InputMap, it asks the + * parent. + *

+ * Now, for BDV, I (Tobias Pietzsch speaking in this section) thought that this + * concept is nice for adding InputMap/ActionMap pairs with related actions to + * the viewer. For example one map with navigation shortcuts, then one map for + * bookmarking, and then each user extension could also create its own + * InputMap/ActionMap pair and just chain it to the existing maps. + *

+ * The slight complication with this is, that if you have a situation like this: + * + *

+ * component → map2 → map1
+ * 
+ * + * and you want to add another one, it should look like this: + * + *
+ * component → map3 → map2 → map1
+ * 
+ * + * so you need to insert it between component and map2. + *

+ * The way this is resolved in ui-behaviours InputActionBindings is that there + * is a theInputMap/theActionMap pair that acts as an empty leaf map with + * exchangeable parents. + *

+ * So from the component side it always looks like + * + *

+ * component → theMap
+ * 
+ * + * and then internally the InputActionBindings maintains a list [map1, map2, + * ...] which is then assembled into a new chain whenever something changes. So + * + *
+ * theMap → map2 → map1
+ * 
+ * + * becomes + * + *
+ * theMap → map3 → map2 → map1
+ * 
+ * + * when map3 is added. + *

+ * And the behaviours framework doesn't have to care about the Swing particulars + * (e.g. actually each Jcomponent has 3 different inputmaps for different + * situation, etc). + *

+ * Having this already, InputActionBindings adds a few convenience features on + * top. + *

+ * For every map pair that you append to InputActionBindings you specify a + * unique name that then can be used to remove the map pair again. + *

+ * E.g., if map2 would have the name "bookmarking", then + * + *

+ * InputActionBindings.removeInputMap( "bookmarking" )
+ * 
+ * + * would reassemble + * + *
+ * theMap → map3 → map2 → map1
+ * 
+ * + * to + * + *
+ * theMap → map3 → map1
+ * 
+ * + * Finally, given that all maps have unique names, when you add a map you can + * specify a set of other maps to block. + *

+ * For example, let's say that you want to temporarily add your own specific + * keys that maybe conflict with the bookmarking keys. + *

+ * So the situation is + * + *

+ * theMap → map3 → map2 → map1
+ * 
+ * + * Now you + * + *
+ * InputActionBindings.addInputMap( map4, "myMap", // block these: // "navigation", "bookmarking" )
+ * 
+ * + * then this will result in + * + *
+ * theMap → map4 → map3
+ * 
+ * + * that is, map1 and map2 were blocked. + *

+ * + * However, InputActionsBindings still knows about map1 and map2. Once you + * remove the blocking "myMap", they will be reinstated. + *

+ * As a concrete example: this whole machinery is used for bookmarking in BDV. + * You set a bookmark by pressing "shift B" and then some other key, that is the + * name for the bookmark. For example, you can press "shift B" "1" to set a + * bookmark named "1". + *

+ * After you press "shift B", a temporary inputmap is installed that blocks all + * other inputmaps. So "1" will not trigger switching to bdv source 1. After the + * bookmark name "1" is received, the temporary inputmap is removed again. + *

+ * For Behaviours, the chaining concept is exactly the same + * + * + * + *

Modifier names.

+ * + * The following modifiers can be used: + * + *
    + *
  • ctrl + *
  • alt + *
  • altGraph + *
  • shift + *
  • meta + *
  • win (the windows key) + *
  • double-click (The trigger matches a double-click. This can include + * "double-clicks" on keys, e.g., shift double-click A works as expected.) + *
+ * + *

Mouse buttons and scrolling.

+ * + *
    + *
  • button1 (left mouse button) + *
  • button2 (middle mouse button) + *
  • button3 (right mouse button) + *
  • scroll (The trigger matches scroll events (both horizontal and vertical). + * Additional keys and modifiers may be present, e.g., shift A scroll matches + * when scrolling while pressing the shift and A keys. This modifier can only be + * used to trigger ScrollBehaviours.) + *
+ * + * + *

Key names.

+ * + * Key names are the usual alphanumeric and function keys: + * + *
    + *
  • A ... Z (Note that letter keys are always upper-case.) + *
  • 0 ... 9 + *
  • F1 ... F24 + *
+ * + * Moreover the following special key names are supported (as in the + * AWTKeyStroke.getAWTKeyStroke(String) method): + * + *
    + *
  • ENTER + *
  • BACK_SPACE + *
  • TAB + *
  • CANCEL + *
  • CLEAR + *
  • COMPOSE + *
  • PAUSE + *
  • CAPS_LOCK + *
  • ESCAPE + *
  • SPACE + *
  • PAGE_UP + *
  • PAGE_DOWN + *
  • END + *
  • HOME + *
  • BEGIN + *
  • COMMA + *
  • PERIOD + *
  • SLASH + *
  • SEMICOLON + *
  • EQUALS + *
  • OPEN_BRACKET + *
  • BACK_SLASH + *
  • CLOSE_BRACKET + *
+ * + * These are names for cursor keys: + * + *
    + *
  • LEFT + *
  • UP + *
  • RIGHT + *
  • DOWN + *
+ * + * These are names for the numpad keys: + * + *
    + *
  • NUMPAD0 ... NUMPAD9 + *
  • MULTIPLY + *
  • ADD + *
  • SEPARATOR + *
  • SUBTRACT + *
  • DECIMAL + *
  • DIVIDE + *
  • DELETE + *
  • NUM_LOCK + *
  • SCROLL_LOCK + *
+ * + */ +package org.scijava.ui.behaviour; From 655493576bbdeb3c4c78af60084dabf0b670406a Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 20 Dec 2019 12:15:50 +0100 Subject: [PATCH 138/184] Improve documentation --- .../scijava/ui/behaviour/package-info.java | 94 ++++++++++--------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/package-info.java b/src/main/java/org/scijava/ui/behaviour/package-info.java index c4b4bb7..41d1e80 100644 --- a/src/main/java/org/scijava/ui/behaviour/package-info.java +++ b/src/main/java/org/scijava/ui/behaviour/package-info.java @@ -10,41 +10,42 @@ *

Overview

* * ui-behaviour is a library for binding behaviours by keys or mouse-actions. - * The idea is similar to Swing's InputMap/ActionMap framework. The difference - * is that actions are atomic while behaviours (possibly) stretch over a period - * of time. For example, a DragBehaviour is initialized (e.g., with a mouse - * click) at certain coordinates, goes through a series of coordinate updates, - * and then ends (when the mouse is released). + * The idea is similar to Swing's {@code InputMap/ActionMap} framework. The + * difference is that actions are atomic while behaviours (possibly) stretch + * over a period of time. For example, a {@code DragBehaviour} is initialized + * (e.g., with a mouse click) at certain coordinates, goes through a series of + * coordinate updates, and then ends (when the mouse is released). *

* The combination of modifiers, keys, mouse buttons etc. that initiates a * behaviour is called a "trigger" and is constructed from a string description. *

* The basic syntax for a trigger description is a sequence of modifier and key - * names separated by whitespace. Examples are SPACE, button1, shift alt scroll, - * and ctrl F G. + * names separated by whitespace. Examples are "{@code SPACE}", + * "{@code button1}", "{@code shift alt scroll}", and "{@code ctrl F G}". *

* Additionally, one can specify a combination of modifiers, keys, mouse buttons * etc. that should be ignored when triggering the behaviour. This is a another * sequence of modifier and key names separated from the trigger description by - * "|". For example, ctrl button1 | shift alt is triggered by pressing the left - * mouse-button while holding the ctrl key. If the shift and/or alt key are - * pressed simultaneously, the trigger still matches. To ignore all other - * modifiers and keys, the special name all is used. So, A | all is a trigger - * that matches when the A key is pressed, regardless which other modifiers, - * keys, or buttons are active at the same time. + * "{@code |}". For example, "{@code ctrl button1 | shift alt}" is triggered by + * pressing the left mouse-button while holding the ctrl key. If the shift + * and/or alt key are pressed simultaneously, the trigger still matches. To + * ignore all other modifiers and keys, the special name "{@code all}" is used. + * So, "{@code A | all}" is a trigger that matches when the A key is pressed, + * regardless which other modifiers, keys, or buttons are active at the same + * time. * * - *

Chaining principle.

+ *

Chaining principle

* - * In Swing, a JComponent has an InputMap. Each InputMap can have a parent, and - * if a mapping for a given key is not found in the InputMap, it asks the - * parent. + * In Swing, a {@code JComponent} has an {@code InputMap}. Each InputMap can + * have a parent, and if a mapping for a given key is not found in the InputMap, + * it asks the parent. *

- * Now, for BDV, I (Tobias Pietzsch speaking in this section) thought that this - * concept is nice for adding InputMap/ActionMap pairs with related actions to - * the viewer. For example one map with navigation shortcuts, then one map for - * bookmarking, and then each user extension could also create its own - * InputMap/ActionMap pair and just chain it to the existing maps. + * For BigDataViewer, we thought that this concept is nice for adding + * InputMap/ActionMap pairs with related actions to the viewer. For example one + * map with navigation shortcuts, then one map for bookmarking, and then each + * user extension could also create its own InputMap/ActionMap pair and just + * chain it to the existing maps. *

* The slight complication with this is, that if you have a situation like this: * @@ -52,26 +53,25 @@ * component → map2 → map1 * * - * and you want to add another one, it should look like this: + * and you want to add another one, "map3", it should look like this: * *

  * component → map3 → map2 → map1
  * 
* - * so you need to insert it between component and map2. + * So, "map3" should be inserted between "component" and "map2". *

- * The way this is resolved in ui-behaviours InputActionBindings is that there - * is a theInputMap/theActionMap pair that acts as an empty leaf map with - * exchangeable parents. - *

- * So from the component side it always looks like + * This is resolved in ui-behaviours {@code InputActionBindings} by having a + * {@code theInputMap/theActionMap} pair that acts as an empty leaf map with + * exchangeable parents. From the component side it always looks like * *

  * component → theMap
  * 
* - * and then internally the InputActionBindings maintains a list [map1, map2, - * ...] which is then assembled into a new chain whenever something changes. So + * and then internally the {@code InputActionBindings} maintains a list + * {@code [map1, map2, ...]} which is then assembled into a new chain whenever + * something changes. So * *
  * theMap → map2 → map1
@@ -83,17 +83,18 @@
  * theMap → map3 → map2 → map1
  * 
* - * when map3 is added. + * when "map3" is added. *

* And the behaviours framework doesn't have to care about the Swing particulars - * (e.g. actually each Jcomponent has 3 different inputmaps for different - * situation, etc). - *

- * Having this already, InputActionBindings adds a few convenience features on - * top. + * (e.g., actually each {@code JComponent} has 3 different inputmaps for + * different situations). + * + *

Blocking maps

+ * + * On top of this, InputActionBindings adds a few convenience features. *

- * For every map pair that you append to InputActionBindings you specify a - * unique name that then can be used to remove the map pair again. + * For every map pair that you append to {@code InputActionBindings} you specify + * a unique name that can later be used to remove the map pair again. *

* E.g., if map2 would have the name "bookmarking", then * @@ -119,19 +120,20 @@ * For example, let's say that you want to temporarily add your own specific * keys that maybe conflict with the bookmarking keys. *

- * So the situation is + * Starting from this situation: * *

  * theMap → map3 → map2 → map1
  * 
* - * Now you + * the following * *
- * InputActionBindings.addInputMap( map4, "myMap", // block these: // "navigation", "bookmarking" )
+ * InputActionBindings.addInputMap( map4, "myMap", "navigation", "bookmarking" )
+ * // "myMap" blocks "navigation", "bookmarking"
  * 
* - * then this will result in + * will result in * *
  * theMap → map4 → map3
@@ -140,8 +142,8 @@
  * that is, map1 and map2 were blocked.
  * 

* - * However, InputActionsBindings still knows about map1 and map2. Once you - * remove the blocking "myMap", they will be reinstated. + * However, InputActionsBindings still knows about map1 and map2. Once the + * blocking "myMap" is removed, they will be reinstated. *

* As a concrete example: this whole machinery is used for bookmarking in BDV. * You set a bookmark by pressing "shift B" and then some other key, that is the @@ -152,7 +154,7 @@ * other inputmaps. So "1" will not trigger switching to bdv source 1. After the * bookmark name "1" is received, the temporary inputmap is removed again. *

- * For Behaviours, the chaining concept is exactly the same + * For Behaviours, the chaining and blocking concepts are exactly the same * * * From 3e764b886996a64b33fb24ecac5c23fcd00ca2ab Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Mon, 13 Jan 2020 17:07:50 +0100 Subject: [PATCH 139/184] Rely on globalKeys for matching triggers. Now, the local pressedKeys is only used for detecting key "double-clicks". --- .../org/scijava/ui/behaviour/MouseAndKeyHandler.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java index c6e1f18..6d4020b 100644 --- a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java @@ -259,8 +259,8 @@ public void mouseClicked( final MouseEvent e ) final int clickMask = mask & ~InputTrigger.DOUBLE_CLICK_MASK; for ( final BehaviourEntry< ClickBehaviour > click : buttonClicks ) { - if ( click.buttons().matches( mask, pressedKeys ) || - ( clickMask != mask && click.buttons().matches( clickMask, pressedKeys ) ) ) + if ( click.buttons().matches( mask, globalKeys.pressedKeys() ) || + ( clickMask != mask && click.buttons().matches( clickMask, globalKeys.pressedKeys() ) ) ) { click.behaviour().click( x, y ); } @@ -362,9 +362,9 @@ public void keyPressed( final KeyEvent e ) } if ( keypressManager != null ) - keypressManager.handleKeyPressed( receiver, mask, doubleClick, pressedKeys ); + keypressManager.handleKeyPressed( receiver, mask, doubleClick, globalKeys.pressedKeys() ); else - handleKeyPressed( mask, doubleClick, pressedKeys, false ); + handleKeyPressed( mask, doubleClick, globalKeys.pressedKeys(), false ); } } @@ -483,7 +483,7 @@ public void keyReleased( final KeyEvent e ) final ArrayList< BehaviourEntry< ? > > ended = new ArrayList<>(); for ( final BehaviourEntry< DragBehaviour > drag : activeKeyDrags ) - if ( !drag.buttons().matchesSubset( mask, pressedKeys ) ) + if ( !drag.buttons().matchesSubset( mask, globalKeys.pressedKeys() ) ) { drag.behaviour().end( mouseX, mouseY ); ended.add( drag ); From 73016430da0fad3522f723809793ec5bf98c9c9a Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Tue, 14 Jan 2020 23:33:06 +0100 Subject: [PATCH 140/184] Bump to next development cycle Signed-off-by: tpietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3aec2df..dae8788 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 2.0.1-SNAPSHOT + 2.0.2-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 37d73656381bb698f455182b498b07fac5c4c459 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Tue, 11 Feb 2020 12:12:07 +0100 Subject: [PATCH 141/184] Allow constructing Behaviours and Actions with keyConfig==null --- src/main/java/org/scijava/ui/behaviour/util/Actions.java | 4 ++-- src/main/java/org/scijava/ui/behaviour/util/Behaviours.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index f1c5d4e..dffb4d2 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -112,9 +112,9 @@ public Actions( { this.actionMap = actionMap; this.inputMap = inputMap; - this.keyConfig = keyConfig; + this.keyConfig = keyConfig != null ? keyConfig : new InputTriggerConfig(); this.keyConfigContexts = keyConfigContexts; - keyStrokeAdder = keyConfig.keyStrokeAdder( inputMap, keyConfigContexts ); + keyStrokeAdder = this.keyConfig.keyStrokeAdder( inputMap, keyConfigContexts ); } public InputMap getInputMap() diff --git a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java index f0c8286..c97febf 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java @@ -114,9 +114,9 @@ public Behaviours( { this.inputTriggerMap = inputTriggerMap; this.behaviourMap = behaviourMap; - this.keyConfig = keyConfig; + this.keyConfig = keyConfig != null ? keyConfig : new InputTriggerConfig(); this.keyConfigContexts = keyConfigContexts; - inputTriggerAdder = keyConfig.inputTriggerAdder( inputTriggerMap, keyConfigContexts ); + inputTriggerAdder = this.keyConfig.inputTriggerAdder( inputTriggerMap, keyConfigContexts ); } public InputTriggerMap getInputTriggerMap() From bc226e67513d1771910505e8ee78b291b296d8e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Ulman?= Date: Tue, 7 Jul 2020 23:14:20 +0200 Subject: [PATCH 142/184] ADD: InputTriggerConfig.remove(...) so that config items need not be only add(...)-ed --- .../ui/behaviour/io/InputTriggerConfig.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 9175abf..ee188d9 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -149,6 +149,7 @@ public synchronized void add( final InputTrigger trigger, final String behaviour */ input.contexts.addAll( contexts ); return; + //NB: this assumes that there exists up to one Input record for this (trigger,behaviour) pair } } @@ -159,6 +160,49 @@ public synchronized void add( final InputTrigger trigger, final String behaviour inputs.add( new Input( trigger, behaviourName, contexts ) ); } + public void remove( final String trigger, final String behaviourName, final String context ) + { + remove( InputTrigger.getFromString( trigger ), behaviourName, context ); + } + + public void remove( final InputTrigger trigger, final String behaviourName, final String context ) + { + remove( trigger, behaviourName, Collections.singleton( context ) ); + } + + public synchronized void remove( final InputTrigger trigger, final String behaviourName, final Collection< String > contexts ) + { + final Set< Input > inputs = actionToInputsMap.get( behaviourName ); + if (inputs == null) return; + + //find Input that covers this trigger -> behaviour binding + Input foundRelevantInput = null; + for ( final Input input : inputs ) + { + if ( input.trigger.equals( trigger ) ) + { + foundRelevantInput = input; + break; + //NB: this assumes that there exists up to one Input record for this (trigger,behaviour) pair + } + } + + if (foundRelevantInput != null) + { + //found Input that covers this trigger -> behaviour binding, + //make sure it does not exist for the given context(s) + foundRelevantInput.contexts.removeAll( contexts ); + if (foundRelevantInput.contexts.isEmpty()) + { + //empty context set -> invalid record -> remove it + inputs.remove( foundRelevantInput ); + + if (inputs.isEmpty()) + actionToInputsMap.remove( behaviourName ); + } + } + } + public static class InputTriggerAdderImp implements InputTriggerAdder { private final InputTriggerMap map; From 2c5c90c4397282996c3fe2176093f0ea5b897c22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Ulman?= Date: Tue, 7 Jul 2020 15:12:09 +0200 Subject: [PATCH 143/184] ADD: static InputTriggerConfig.prettyPrintInputs(), e.g., to convert "[X, J]" into "X or J" --- .../ui/behaviour/io/InputTriggerConfig.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 9175abf..4e9748f 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -37,6 +37,7 @@ import java.util.LinkedHashSet; import java.util.Map.Entry; import java.util.Set; +import java.util.Iterator; import javax.swing.InputMap; import javax.swing.KeyStroke; @@ -109,6 +110,22 @@ public Set< InputTrigger > getInputs( final String behaviourName, final Set< Str return triggers; } + /** + * Creates a pretty printed list of keys, useful in conjuction with {@link InputTriggerConfig#getInputs}. + * + * @param triggers Set of triggers to be printed. + * @return String with formatted content. + */ + public static String prettyPrintInputs(final Set triggers) { + final StringBuilder sb = new StringBuilder(); + final Iterator it = triggers.iterator(); + while (it.hasNext()) { + sb.append( it.next() ); + if (it.hasNext()) sb.append(" or "); + } + return sb.toString(); + } + public void clear() { actionToInputsMap.clear(); From b30bef560ce00910231a4bc16208bef1020ab306 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 16 Jul 2020 09:56:45 +0200 Subject: [PATCH 144/184] formatting --- .../ui/behaviour/io/InputTriggerConfig.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 4e9748f..88ded73 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -33,11 +33,11 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map.Entry; import java.util.Set; -import java.util.Iterator; import javax.swing.InputMap; import javax.swing.KeyStroke; @@ -111,17 +111,23 @@ public Set< InputTrigger > getInputs( final String behaviourName, final Set< Str } /** - * Creates a pretty printed list of keys, useful in conjuction with {@link InputTriggerConfig#getInputs}. + * Creates a pretty printed list of keys, useful in conjunction with + * {@link InputTriggerConfig#getInputs}. + * + * @param triggers + * Set of triggers to be printed. * - * @param triggers Set of triggers to be printed. * @return String with formatted content. */ - public static String prettyPrintInputs(final Set triggers) { + public static String prettyPrintInputs( final Set< InputTrigger > triggers ) + { final StringBuilder sb = new StringBuilder(); - final Iterator it = triggers.iterator(); - while (it.hasNext()) { + final Iterator< InputTrigger > it = triggers.iterator(); + while ( it.hasNext() ) + { sb.append( it.next() ); - if (it.hasNext()) sb.append(" or "); + if ( it.hasNext() ) + sb.append( " or " ); } return sb.toString(); } @@ -131,10 +137,10 @@ public void clear() actionToInputsMap.clear(); } - public void set( InputTriggerConfig config ) + public void set( final InputTriggerConfig config ) { actionToInputsMap.clear(); - for ( Entry< String, Set< Input > > entry : config.actionToInputsMap.entrySet() ) + for ( final Entry< String, Set< Input > > entry : config.actionToInputsMap.entrySet() ) { final String behaviourName = entry.getKey(); final Set< Input > inputs = new LinkedHashSet<>(); @@ -397,7 +403,7 @@ static class Input this.contexts = new HashSet<>( contexts ); } - Input( Input input ) + Input( final Input input ) { this.trigger = input.trigger; this.behaviour = input.behaviour; From 621810cdd28389cd5e4dfb9e733f23fa8535dad5 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 16 Jul 2020 10:40:07 +0200 Subject: [PATCH 145/184] Simplify InputTriggerConfig.remove() and clarify comments --- .../ui/behaviour/io/InputTriggerConfig.java | 43 ++++++++++--------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index ee188d9..a021988 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -149,7 +149,11 @@ public synchronized void add( final InputTrigger trigger, final String behaviour */ input.contexts.addAll( contexts ); return; - //NB: this assumes that there exists up to one Input record for this (trigger,behaviour) pair + /* + * NB: this assumes that there exists not more than one Input + * record for each (trigger, behaviour) pair. This property is + * maintained by the add/remove implementations. + */ } } @@ -173,32 +177,31 @@ public void remove( final InputTrigger trigger, final String behaviourName, fina public synchronized void remove( final InputTrigger trigger, final String behaviourName, final Collection< String > contexts ) { final Set< Input > inputs = actionToInputsMap.get( behaviourName ); - if (inputs == null) return; + if ( inputs == null ) + return; - //find Input that covers this trigger -> behaviour binding - Input foundRelevantInput = null; for ( final Input input : inputs ) { if ( input.trigger.equals( trigger ) ) { - foundRelevantInput = input; - break; - //NB: this assumes that there exists up to one Input record for this (trigger,behaviour) pair - } - } + // found Input that covers this trigger -> behaviour binding, + // make sure it does not exist for the given context(s) + input.contexts.removeAll( contexts ); + if ( input.contexts.isEmpty() ) + { + // empty context set -> invalid record -> remove it + inputs.remove( input ); - if (foundRelevantInput != null) - { - //found Input that covers this trigger -> behaviour binding, - //make sure it does not exist for the given context(s) - foundRelevantInput.contexts.removeAll( contexts ); - if (foundRelevantInput.contexts.isEmpty()) - { - //empty context set -> invalid record -> remove it - inputs.remove( foundRelevantInput ); + if ( inputs.isEmpty() ) + actionToInputsMap.remove( behaviourName ); + } - if (inputs.isEmpty()) - actionToInputsMap.remove( behaviourName ); + return; + /* + * NB: this assumes that there exists not more than one Input + * record for each (trigger, behaviour) pair. This property is + * maintained by the add/remove implementations. + */ } } } From c4af3b1a9a693907d5ed3eb96cb4fc9a47128eb0 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 16 Jul 2020 10:40:56 +0200 Subject: [PATCH 146/184] Clean up --- .../org/scijava/ui/behaviour/io/InputTriggerConfig.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index a021988..6d7acb0 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -114,10 +114,10 @@ public void clear() actionToInputsMap.clear(); } - public void set( InputTriggerConfig config ) + public void set( final InputTriggerConfig config ) { actionToInputsMap.clear(); - for ( Entry< String, Set< Input > > entry : config.actionToInputsMap.entrySet() ) + for ( final Entry< String, Set< Input > > entry : config.actionToInputsMap.entrySet() ) { final String behaviourName = entry.getKey(); final Set< Input > inputs = new LinkedHashSet<>(); @@ -427,7 +427,7 @@ static class Input this.contexts = new HashSet<>( contexts ); } - Input( Input input ) + Input( final Input input ) { this.trigger = input.trigger; this.behaviour = input.behaviour; From 5998c02abaf987bdf2a701295e3bc3570cdac4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Ulman?= Date: Thu, 16 Jul 2020 17:42:03 +0200 Subject: [PATCH 147/184] VisualEditorPanel: finer grain listeners (#20) * CHG: VisualEditorPanel.listeners renamed to itemChangedListeners, added docs * ADD: VisualEditorPanel.configChangedListeners and their management * Rename variable to match method names: Rename "configChangedListeners" to "configComittedListeners" to match method name "addConfigCommittedListener()". Rename "itemChangeListeners" to "configChangeListeners" to match method name "addConfigChangeListener()". * VisualEditorPanel: Use `Listeners` instead of maintaining listener HashSets * Clean up/simplify ...thank you, IntelliJ Co-authored-by: tpietzsch --- pom.xml | 7 ++ .../behaviour/io/gui/VisualEditorPanel.java | 105 +++++++++++------- .../io/gui/VisualEditorPanelDemo.java | 5 +- 3 files changed, 72 insertions(+), 45 deletions(-) diff --git a/pom.xml b/pom.xml index dae8788..7bddc7b 100644 --- a/pom.xml +++ b/pom.xml @@ -100,6 +100,8 @@ Max Planck Institute of Molecular Cell Biology and Genetics. + 1.0.0-beta-3 + deploy-to-scijava @@ -112,6 +114,11 @@ and Genetics. + + org.scijava + scijava-listeners + ${scijava-listeners.version} + net.sf.trove4j trove4j diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 283a5ca..404e03f 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -18,7 +18,6 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -26,7 +25,6 @@ import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; - import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; @@ -49,7 +47,7 @@ import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableRowSorter; - +import org.scijava.listeners.Listeners; import org.scijava.ui.behaviour.InputTrigger; import org.scijava.ui.behaviour.io.InputTriggerConfig; import org.scijava.ui.behaviour.io.InputTriggerDescription; @@ -86,12 +84,12 @@ public boolean accept( final File f ) * editor. */ @FunctionalInterface - public static interface ConfigChangeListener + public interface ConfigChangeListener { /** * Called when settings are changed in the visual editor. */ - public void configChanged(); + void configChanged(); } private JTextField textFieldFilter; @@ -126,7 +124,19 @@ public static interface ConfigChangeListener private final JPanel panelButtons; - private final HashSet< ConfigChangeListener > listeners; + /** + * Set of listeners that are triggered whenever any single item change in the GUI. + * This, however, does not mean that the underlying {@link InputTriggerConfig} was + * changed at all as the GUI is buffering changes until the "Apply" button is pressed. + */ + private final Listeners.List< ConfigChangeListener > configChangeListeners; + + /** + * Set of listeners that are triggered only when the "Apply" button is pressed, + * which is precisely the moment when the current state/content of GUI is committed + * to the underlying {@link InputTriggerConfig} via the ModelToConfig(). + */ + private final Listeners.List< ConfigChangeListener > configCommittedListeners; private final JButton btnApply; @@ -165,7 +175,8 @@ public VisualEditorPanel( final InputTriggerConfig config, final Map< Command, S commandNameToAcceptableContexts = new HashMap<>(); for ( final Command command : commands ) commandNameToAcceptableContexts.computeIfAbsent( command.getName(), k -> new HashSet<>() ).add( command.getContext() ); - this.listeners = new HashSet<>(); + this.configChangeListeners = new Listeners.SynchronizedList<>(); + this.configCommittedListeners = new Listeners.SynchronizedList<>(); /* * GUI @@ -427,14 +438,9 @@ public void valueChanged( final ListSelectionEvent e ) btnApply.addActionListener( ( e ) -> modelToConfig() ); // Buttons re-enabling when model and config are out of sync. - addConfigChangeListener( new ConfigChangeListener() - { - @Override - public void configChanged() - { - btnApply.setEnabled( true ); - btnRestore.setEnabled( true ); - } + configChangeListeners().add( () -> { + btnApply.setEnabled( true ); + btnRestore.setEnabled( true ); } ); configToModel(); @@ -475,9 +481,9 @@ private void lookForConflicts() { final StringBuilder str = new StringBuilder(); str.append( tableModel.rows.get( i ).getName() ); - str.append( " in " + overlappingContexts.get( 0 ) ); + str.append( " in " ).append( overlappingContexts.get( 0 ) ); for ( int j = 1; j < overlappingContexts.size(); j++ ) - str.append( ", " + overlappingContexts.get( j ) ); + str.append( ", " ).append( overlappingContexts.get( j ) ); conflicts.add( str.toString() ); } @@ -488,7 +494,7 @@ private void lookForConflicts() { final StringBuilder str = new StringBuilder( conflicts.get( 0 ) ); for ( int i = 1; i < conflicts.size(); i++ ) - str.append( "; " + conflicts.get( i ) ); + str.append( "; " ).append( conflicts.get( i ) ); lblConflict.setText( str.toString() ); } } @@ -529,6 +535,8 @@ public void modelToConfig() btnApply.setEnabled( false ); btnRestore.setEnabled( false ); + + configCommittedListeners.list.forEach( ConfigChangeListener::configChanged ); } public void configToModel() @@ -615,16 +623,14 @@ private void exportToCsv() { sb.append( contexts.get( 0 ) ); for ( int j = 1; j < contexts.size(); j++ ) - sb.append( " - " + contexts.get( j ) ); + sb.append( " - " ).append( contexts.get( j ) ); } sb.append( '\n' ); } - try (final PrintWriter pw = new PrintWriter( file )) + try ( final PrintWriter pw = new PrintWriter( file ) ) { - pw.write( sb.toString() ); - pw.close(); } catch ( final FileNotFoundException e ) { @@ -664,9 +670,9 @@ private void updateEditors() { final String d = actionDescriptions.get( new Command( action, context ) ); if ( d != null ) - str.append( "\n\nIn " + context + ":\n" + d ); + str.append( "\n\nIn " ).append( context ).append( ":\n" ).append( d ); else - str.append( "\n\nIn " + context + " - no description." ); + str.append( "\n\nIn " ).append( context ).append( " - no description." ); } str.delete( 0, 2 ); description = str.toString(); @@ -703,13 +709,7 @@ private void unbindAllCommand() return; final int modelRow = tableBindings.convertRowIndexToModel( viewRow ); final String removeName = tableModel.rows.get( modelRow ).getName(); - final Iterator< MyTableRow > iter = tableModel.rows.iterator(); - while( iter.hasNext() ) - { - final MyTableRow row = iter.next(); - if ( row.getName().equals( removeName ) ) - iter.remove(); - } + tableModel.rows.removeIf( row -> row.getName().equals( removeName ) ); if ( !tableModel.addMissingRows() ) tableModel.fireTableDataChanged(); @@ -797,8 +797,7 @@ private void contextsChanged( final List< String > selectedContexts ) private void notifyListeners() { - for ( final ConfigChangeListener listener : listeners ) - listener.configChanged(); + configChangeListeners.list.forEach( ConfigChangeListener::configChanged ); } private static Map< Command, String > extractEmptyCommandDescriptions( final InputTriggerConfig keyconf ) @@ -813,14 +812,42 @@ private static Map< Command, String > extractEmptyCommandDescriptions( final Inp return commandDescriptions; } + /** + * Please, see the documentation of {@link VisualEditorPanel#configChangeListeners} + * and {@link VisualEditorPanel#configCommittedListeners} to understand when these + * listeners are triggered. In short, these are triggered anytime a GUI item is changed. + */ + public Listeners< ConfigChangeListener > configChangeListeners() + { + return configChangeListeners; + } + + /** + * @deprecated Use {@code configChangeListeners().add(listener)} instead. + */ + @Deprecated public void addConfigChangeListener( final ConfigChangeListener listener ) { - listeners.add( listener ); + configChangeListeners().add( listener ); } + /** + * @deprecated Use {@code configChangeListeners().remove(listener)} instead. + */ + @Deprecated public void removeConfigChangeListener( final ConfigChangeListener listener ) { - listeners.remove( listener ); + configChangeListeners().remove( listener ); + } + + /** + * Please, see the documentation of {@link VisualEditorPanel#configChangeListeners} + * and {@link VisualEditorPanel#configCommittedListeners} to understand when these + * listeners are triggered. In short, these are triggered only when "Apply" button is pressed. + */ + public Listeners< ConfigChangeListener > configCommittedListeners() + { + return configCommittedListeners; } /* @@ -991,13 +1018,7 @@ public MyTableModel( final Set< Command > commands, final InputTriggerConfig con */ public void removeAllNotMapped( final List< MyTableRow > rows ) { - final Iterator< MyTableRow > iter = rows.iterator(); - while ( iter.hasNext() ) - { - final MyTableRow row = iter.next(); - if ( row.getTrigger().equals( InputTrigger.NOT_MAPPED ) ) - iter.remove(); - } + rows.removeIf( row -> row.getTrigger().equals( InputTrigger.NOT_MAPPED ) ); } /** diff --git a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java index 75b8338..42168e5 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java @@ -45,8 +45,7 @@ private static InputTriggerConfig getDemoConfig() " triggers: [control A]" + "\n" + "" ); final List< InputTriggerDescription > triggers = YamlConfigIO.read( reader ); - final InputTriggerConfig config = new InputTriggerConfig( triggers ); - return config; + return new InputTriggerConfig( triggers ); } private static Map< Command, String > getDemoCommands() @@ -91,7 +90,7 @@ public void run() { final JFrame frame = new JFrame( "Behaviour Key bindings editor" ); final VisualEditorPanel editorPanel = new VisualEditorPanel( getDemoConfig(), getDemoCommands() ); - editorPanel.addConfigChangeListener( () -> System.out.println( "Config changed @ " + new java.util.Date().toString() ) ); + editorPanel.configChangeListeners().add( () -> System.out.println( "Config changed @ " + new java.util.Date().toString() ) ); SwingUtilities.updateComponentTreeUI( VisualEditorPanel.fileChooser ); frame.getContentPane().add( editorPanel ); frame.pack(); From f073696a7b059f5e12b90871a32ee46e42e87445 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 16 Jul 2020 17:43:31 +0200 Subject: [PATCH 148/184] POM: Bump parent to pom-scijava 29.0.0-beta-3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7bddc7b..e7373b1 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.scijava pom-scijava - 27.0.1 + 29.0.0-beta-3 ui-behaviour From 23006c5a7a733be47860cbe53e2dd425650f8c5a Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 16 Jul 2020 18:03:46 +0200 Subject: [PATCH 149/184] Update license headers --- LICENSE.txt | 2 +- .../behaviour/AbstractMouseAndKeyHandler.java | 29 +++++++++++++++++ .../org/scijava/ui/behaviour/Behaviour.java | 2 +- .../scijava/ui/behaviour/BehaviourMap.java | 2 +- .../scijava/ui/behaviour/ClickBehaviour.java | 2 +- .../scijava/ui/behaviour/DragBehaviour.java | 2 +- .../behaviour/GlobalKeyEventDispatcher.java | 2 +- .../scijava/ui/behaviour/InputTrigger.java | 2 +- .../ui/behaviour/InputTriggerAdder.java | 2 +- .../scijava/ui/behaviour/InputTriggerMap.java | 2 +- .../ui/behaviour/KeyPressedManager.java | 6 ++-- .../scijava/ui/behaviour/KeyStrokeAdder.java | 2 +- .../ui/behaviour/MouseAndKeyHandler.java | 6 ++-- .../scijava/ui/behaviour/ScrollBehaviour.java | 2 +- .../ui/behaviour/io/InputTriggerConfig.java | 6 ++-- .../behaviour/io/InputTriggerDescription.java | 2 +- .../io/InputTriggerDescriptionsBuilder.java | 6 ++-- .../scijava/ui/behaviour/io/gui/Command.java | 29 +++++++++++++++++ .../io/gui/CommandDescriptionBuilder.java | 29 +++++++++++++++++ .../io/gui/InputTriggerPanelEditor.java | 29 +++++++++++++++++ .../ui/behaviour/io/gui/RoundBorder.java | 31 ++++++++++++++++++- .../ui/behaviour/io/gui/TagPanelEditor.java | 29 +++++++++++++++++ .../behaviour/io/gui/VisualEditorPanel.java | 29 +++++++++++++++++ .../ui/behaviour/io/json/JsonConfigIO.java | 2 +- .../ui/behaviour/io/yaml/YamlConfigIO.java | 2 +- .../scijava/ui/behaviour/package-info.java | 29 +++++++++++++++++ .../behaviour/util/AbstractNamedAction.java | 2 +- .../util/AbstractNamedBehaviour.java | 2 +- .../scijava/ui/behaviour/util/Actions.java | 2 +- .../scijava/ui/behaviour/util/Behaviours.java | 2 +- .../behaviour/util/InputActionBindings.java | 2 +- .../ui/behaviour/util/RunnableAction.java | 2 +- .../util/TriggerBehaviourBindings.java | 6 ++-- .../ui/behaviour/util/WrappedActionMap.java | 29 +++++++++++++++++ .../behaviour/util/WrappedBehaviourMap.java | 29 +++++++++++++++++ .../ui/behaviour/util/WrappedInputMap.java | 29 +++++++++++++++++ .../util/WrappedInputTriggerMap.java | 29 +++++++++++++++++ .../ui/behaviour/EventsInteractiveTest.java | 2 +- .../ui/behaviour/MultiWindowExample.java | 2 +- .../scijava/ui/behaviour/UsageExample.java | 2 +- .../io/gui/VisualEditorPanelDemo.java | 29 +++++++++++++++++ .../io/json/JsonInteractiveTest.java | 2 +- .../io/yaml/YamlInteractiveTest.java | 2 +- 43 files changed, 418 insertions(+), 41 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 91e2bac..4fdf2bb 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2015 - 2017, Max Planck Institute of Molecular Cell Biology +Copyright (c) 2015 - 2020, Max Planck Institute of Molecular Cell Biology and Genetics. All rights reserved. diff --git a/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java index e866c73..b455358 100644 --- a/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour; import java.awt.Toolkit; diff --git a/src/main/java/org/scijava/ui/behaviour/Behaviour.java b/src/main/java/org/scijava/ui/behaviour/Behaviour.java index ee7556f..d80148f 100644 --- a/src/main/java/org/scijava/ui/behaviour/Behaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/Behaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java index 9a3c2c8..99d52f9 100644 --- a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java +++ b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java b/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java index e6fea17..84add22 100644 --- a/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java b/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java index bb5ac30..56a1caa 100644 --- a/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java b/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java index 9c1d3b4..8318401 100644 --- a/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java +++ b/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java index 3781bff..2047a7d 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java index 3e5ab18..e00cd71 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java index 0babb2e..0d77f1a 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java index 1470c6d..bc53419 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java @@ -2,18 +2,18 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * 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 diff --git a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java index cc33d0d..ab0b8b3 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java index 6d4020b..e300fa0 100644 --- a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java @@ -2,18 +2,18 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * 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 diff --git a/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java b/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java index 7487c83..d188338 100644 --- a/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 2914668..355eff3 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -2,18 +2,18 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * 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 diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java index 933f804..04a78af 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java index 4d38c19..c7d6e51 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java @@ -2,18 +2,18 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * 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 diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java b/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java index bf50f44..55a441e 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.gui; /** diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java index 02422eb..5222562 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.gui; import java.util.Collections; diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index beab283..5d9cc21 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.gui; import java.awt.Color; diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java index a38336b..399e98b 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.gui; import java.awt.Color; @@ -51,4 +80,4 @@ public void paintBorder( final Component c, final Graphics g, final int x, final } } -} \ No newline at end of file +} diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java index e230d92..948f6e4 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.gui; import java.awt.Color; diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 404e03f..2dde1f2 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.gui; import java.awt.BorderLayout; diff --git a/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java index aebfa68..9148449 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java index 7c5edfa..7493713 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/package-info.java b/src/main/java/org/scijava/ui/behaviour/package-info.java index 41d1e80..ddfe757 100644 --- a/src/main/java/org/scijava/ui/behaviour/package-info.java +++ b/src/main/java/org/scijava/ui/behaviour/package-info.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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% + */ /** *

Configurable-keys

Simplify making AWT mouse-handlers configurable. * diff --git a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java index 25bad9f..1cb234f 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java index 7d728da..6efe2a2 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index dffb4d2..82751a3 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java index c97febf..f9d9c6d 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java index 9a459b6..b697f6c 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java index 716ffb2..24359e1 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java index e22e53e..4b1aff1 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java @@ -2,18 +2,18 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * 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 diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java index 0af31d4..bc7e2ad 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import javax.swing.Action; diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java index 87dfa50..aa12a46 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import java.util.HashMap; diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java index 417c62b..7b71047 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import javax.swing.InputMap; diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java index ae4caac..09dccb8 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.util; import java.util.HashMap; diff --git a/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java index 578cf70..8f13677 100644 --- a/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java b/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java index 26eb424..63a6c6f 100644 --- a/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java +++ b/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/UsageExample.java b/src/test/java/org/scijava/ui/behaviour/UsageExample.java index b3222dc..5118709 100644 --- a/src/test/java/org/scijava/ui/behaviour/UsageExample.java +++ b/src/test/java/org/scijava/ui/behaviour/UsageExample.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java index 42168e5..eae16ce 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java @@ -1,3 +1,32 @@ +/*- + * #%L + * Configurable key and mouse event handling + * %% + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * and Genetics. + * %% + * 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.behaviour.io.gui; import java.awt.EventQueue; diff --git a/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java index f5c39aa..e04b01b 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java index 7e8ff81..98a7dc5 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2017 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without From b14b7786587cbd1cbbca734a07483a29ce004e47 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 16 Jul 2020 18:05:02 +0200 Subject: [PATCH 150/184] Bump to next development cycle Signed-off-by: tpietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e7373b1..b5b777f 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 2.0.2-SNAPSHOT + 2.0.3-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 35258456d8af9f9592eb7222775edac06c6f8739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Ulman?= Date: Wed, 21 Oct 2020 13:51:33 +0200 Subject: [PATCH 151/184] CHG: VisualEditorPanel.configChangeListeners -> modelChangedListeners, (#24) deprecated all *ConfigChange* methods (for listeners mngmt), updated example code --- .../behaviour/io/gui/VisualEditorPanel.java | 37 ++++++++++++------- .../io/gui/VisualEditorPanelDemo.java | 3 +- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 2dde1f2..2d8421e 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -158,7 +158,7 @@ public interface ConfigChangeListener * This, however, does not mean that the underlying {@link InputTriggerConfig} was * changed at all as the GUI is buffering changes until the "Apply" button is pressed. */ - private final Listeners.List< ConfigChangeListener > configChangeListeners; + private final Listeners.List< ConfigChangeListener > modelChangedListeners; /** * Set of listeners that are triggered only when the "Apply" button is pressed, @@ -204,7 +204,7 @@ public VisualEditorPanel( final InputTriggerConfig config, final Map< Command, S commandNameToAcceptableContexts = new HashMap<>(); for ( final Command command : commands ) commandNameToAcceptableContexts.computeIfAbsent( command.getName(), k -> new HashSet<>() ).add( command.getContext() ); - this.configChangeListeners = new Listeners.SynchronizedList<>(); + this.modelChangedListeners = new Listeners.SynchronizedList<>(); this.configCommittedListeners = new Listeners.SynchronizedList<>(); /* @@ -467,7 +467,7 @@ public void valueChanged( final ListSelectionEvent e ) btnApply.addActionListener( ( e ) -> modelToConfig() ); // Buttons re-enabling when model and config are out of sync. - configChangeListeners().add( () -> { + modelChangedListeners.add( () -> { btnApply.setEnabled( true ); btnRestore.setEnabled( true ); } ); @@ -826,7 +826,7 @@ private void contextsChanged( final List< String > selectedContexts ) private void notifyListeners() { - configChangeListeners.list.forEach( ConfigChangeListener::configChanged ); + modelChangedListeners.list.forEach( ConfigChangeListener::configChanged ); } private static Map< Command, String > extractEmptyCommandDescriptions( final InputTriggerConfig keyconf ) @@ -842,37 +842,46 @@ private static Map< Command, String > extractEmptyCommandDescriptions( final Inp } /** - * Please, see the documentation of {@link VisualEditorPanel#configChangeListeners} - * and {@link VisualEditorPanel#configCommittedListeners} to understand when these - * listeners are triggered. In short, these are triggered anytime a GUI item is changed. + * @deprecated Use {@code modelChangedListeners()} instead. */ + @Deprecated public Listeners< ConfigChangeListener > configChangeListeners() { - return configChangeListeners; + return modelChangedListeners(); } /** - * @deprecated Use {@code configChangeListeners().add(listener)} instead. + * @deprecated Use {@code modelChangedListeners().add(listener)} instead. */ @Deprecated public void addConfigChangeListener( final ConfigChangeListener listener ) { - configChangeListeners().add( listener ); + modelChangedListeners().add( listener ); } /** - * @deprecated Use {@code configChangeListeners().remove(listener)} instead. + * @deprecated Use {@code modelChangedListeners().remove(listener)} instead. */ @Deprecated public void removeConfigChangeListener( final ConfigChangeListener listener ) { - configChangeListeners().remove( listener ); + modelChangedListeners().remove( listener ); + } + + /** + * Please, see the documentation of {@link VisualEditorPanel#modelChangedListeners} + * and {@link VisualEditorPanel#configCommittedListeners} to understand when these + * listeners are triggered. In short, listeners here are triggered anytime a GUI item is changed. + */ + public Listeners< ConfigChangeListener > modelChangedListeners() + { + return modelChangedListeners; } /** - * Please, see the documentation of {@link VisualEditorPanel#configChangeListeners} + * Please, see the documentation of {@link VisualEditorPanel#modelChangedListeners} * and {@link VisualEditorPanel#configCommittedListeners} to understand when these - * listeners are triggered. In short, these are triggered only when "Apply" button is pressed. + * listeners are triggered. In short, listeners here are triggered only when "Apply" button is pressed. */ public Listeners< ConfigChangeListener > configCommittedListeners() { diff --git a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java index eae16ce..3ac3861 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java @@ -119,7 +119,8 @@ public void run() { final JFrame frame = new JFrame( "Behaviour Key bindings editor" ); final VisualEditorPanel editorPanel = new VisualEditorPanel( getDemoConfig(), getDemoCommands() ); - editorPanel.configChangeListeners().add( () -> System.out.println( "Config changed @ " + new java.util.Date().toString() ) ); + editorPanel.modelChangedListeners().add( () -> System.out.println( "Model (GUI only) changed @ " + new java.util.Date().toString() ) ); + editorPanel.configCommittedListeners().add( () -> System.out.println( "Config changed, Apply button pressed @ " + new java.util.Date().toString() ) ); SwingUtilities.updateComponentTreeUI( VisualEditorPanel.fileChooser ); frame.getContentPane().add( editorPanel ); frame.pack(); From f53396618529d10579087229ff1d0cd1a7e7a88e Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 21 Oct 2020 13:57:25 +0200 Subject: [PATCH 152/184] POM: bump parent to pom-scijava-29.2.1 and remove obsolete version overrides --- pom.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index b5b777f..0acc1c3 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.scijava pom-scijava - 29.0.0-beta-3 + 29.2.1 ui-behaviour @@ -100,8 +100,6 @@ Max Planck Institute of Molecular Cell Biology and Genetics. - 1.0.0-beta-3 - deploy-to-scijava From 6683d07dc97db9016202d3518219f09a8fc01510 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 21 Oct 2020 14:01:53 +0200 Subject: [PATCH 153/184] Bump to next development cycle Signed-off-by: tpietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0acc1c3..da201dd 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 2.0.3-SNAPSHOT + 2.0.4-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 6f928fd4e17b60b72dbffcbcf42e9a96f48b5dfd Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sat, 6 Mar 2021 23:07:35 +0100 Subject: [PATCH 154/184] Add @Deprecated (inherited) --- .../java/org/scijava/ui/behaviour/io/InputTriggerConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 355eff3..d263c48 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -336,6 +336,7 @@ public KeyStrokeAdderImp( this.contexts.addAll( Arrays.asList( contexts ) ); } + @Deprecated @Override public void put( final String actionName, final KeyStroke... defaultKeyStrokes ) { From aa905cd354ae1305c5f6b21953512b95cd32174b Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sat, 6 Mar 2021 23:08:29 +0100 Subject: [PATCH 155/184] Move CommandDescriptionBuilder to VisualEditorPanelDemo (only place it is used) --- .../io/gui/CommandDescriptionBuilder.java | 73 ------------------- .../io/gui/VisualEditorPanelDemo.java | 45 +++++++++++- 2 files changed, 43 insertions(+), 75 deletions(-) delete mode 100644 src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java deleted file mode 100644 index 5222562..0000000 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionBuilder.java +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * #%L - * Configurable key and mouse event handling - * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology - * and Genetics. - * %% - * 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.behaviour.io.gui; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * Utility class that is used to build a map of {@link Command}s to their - * description. - * - * @author Jean-Yves Tinevez - */ -public class CommandDescriptionBuilder -{ - - /** - * The map of {@link Command} to description of what the command does. - */ - private final HashMap< Command, String > map; - - public CommandDescriptionBuilder() - { - this.map = new HashMap<>(); - } - - public CommandDescriptionBuilder addCommand( final String name, final String context, final String description ) - { - final Command command = new Command( name, context ); - map.put( command, description ); - return this; - } - - /** - * Returns the map of {@link Command} to description of what the command - * does. - * - * @return a new immutable map - */ - public Map< Command, String > get() - { - return Collections.unmodifiableMap( map ); - } - -} diff --git a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java index 3ac3861..b121295 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java @@ -7,13 +7,13 @@ * %% * 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 @@ -31,6 +31,8 @@ import java.awt.EventQueue; import java.io.StringReader; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -97,6 +99,45 @@ private static Map< Command, String > getDemoCommands() .get(); } + /** + * Utility class that is used to build a map of {@link Command}s to their + * description. + * + * @author Jean-Yves Tinevez + */ + static class CommandDescriptionBuilder + { + + /** + * The map of {@link Command} to description of what the command does. + */ + private final HashMap< Command, String > map; + + public CommandDescriptionBuilder() + { + this.map = new HashMap<>(); + } + + public CommandDescriptionBuilder addCommand( final String name, final String context, final String description ) + { + final Command command = new Command( name, context ); + map.put( command, description ); + return this; + } + + /** + * Returns the map of {@link Command} to description of what the command + * does. + * + * @return a new immutable map + */ + public Map< Command, String > get() + { + return Collections.unmodifiableMap( map ); + } + + } + /** * Launch the application. * From 355a9a41549fe02a5713c43f8dc1e3d4f95d24e3 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sat, 6 Mar 2021 23:09:22 +0100 Subject: [PATCH 156/184] Bump to pom-scijava-30.0.0 and add scijava-common depencency --- pom.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index da201dd..0952662 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.scijava pom-scijava - 29.2.1 + 30.0.0 ui-behaviour @@ -115,7 +115,10 @@ and Genetics. org.scijava scijava-listeners - ${scijava-listeners.version} + + + org.scijava + scijava-common net.sf.trove4j From c8cb8cf6dcb9a41bd9b870fdc871b9f4809927da Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sat, 6 Mar 2021 23:09:54 +0100 Subject: [PATCH 157/184] Move CommandDescriptions etc from Mastodon --- .../io/gui/CommandDescriptionProvider.java | 123 ++++++++++++ .../behaviour/io/gui/CommandDescriptions.java | 160 ++++++++++++++++ .../io/gui/CommandDescriptionsBuilder.java | 179 ++++++++++++++++++ .../behaviour/io/gui/VisualEditorPanel.java | 2 +- 4 files changed, 463 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java create mode 100644 src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java create mode 100644 src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java new file mode 100644 index 0000000..9cc39bb --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java @@ -0,0 +1,123 @@ +/*- + * #%L + * Mastodon + * %% + * Copyright (C) 2014 - 2021 Tobias Pietzsch, Jean-Yves Tinevez + * %% + * 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.behaviour.io.gui; + +import org.scijava.plugin.SciJavaPlugin; + +/** + * Implementations of this interface, annotated with {@code @Plugin}, are + * discovered for automatically adding actions/behaviours to a + * {@link CommandDescriptions} map. + *

+ * (This allows to discover Plugin shortcuts which cannot be hardwired into the + * default keymap.) + */ +public abstract class CommandDescriptionProvider implements SciJavaPlugin +{ + private final String[] expectedContexts; + + private final Scope scope; + + protected CommandDescriptionProvider( final Scope scope, final String... expectedContexts ) + { + this.scope = scope; + this.expectedContexts = expectedContexts; + } + + /** + * The contexts in which the described actions/bahaviours are expected to be + * used. + *

+ * The scope describes the application / Fiji plugin that the actions are + * defined in. This is to make it possible to only harvest descriptions + * for the desired scopes. + *

+ * Note that {@code CommandDescriptionProvider} is only used for harvesting + * actions/behaviours for the config dialog. So basically it has nothing to + * do with reality, necessarily. Whether these actions are ever actualized + * depends on other code! The {@code scope} is for which scope + * the config dialog will make the actions configurable. For example, if you + * put {"mastodon"} there, then the {@code InputTriggerConfig} will be picked + * up by a config dialog requesting these scopes. + */ + public Scope getScope() + { + return scope; + } + + /** + * The contexts in which the described actions/bahaviours are expected to be + * used. + *

+ * Note that {@code CommandDescriptionProvider} is only used for harvesting + * actions/behaviours for the config dialog. So basically it has nothing to + * do with reality, necessarily. Whether these actions are ever actualized + * depends on other code! The {@code expectedContexts} is for which context + * the config dialog will make the actions configurable. For example, if you + * put {"bdv", "ts"} there, then the {@code InputTriggerConfig} made by the + * config dialog will put InputTriggers with these contexts. + */ + public String[] getExpectedContexts() + { + return expectedContexts; + } + + public abstract void getCommandDescriptions( final CommandDescriptions descriptions ); + + public static class Scope + { + private final String name; + + public Scope( final String name ) + { + this.name = name; + } + + public String getName() + { + return name; + } + + @Override + public boolean equals( final Object o ) + { + if ( this == o ) + return true; + if ( !( o instanceof Scope ) ) + return false; + return name.equals( ( ( Scope ) o ).name ); + } + + @Override + public int hashCode() + { + return name.hashCode(); + } + } +} diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java new file mode 100644 index 0000000..25563ee --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java @@ -0,0 +1,160 @@ +/*- + * #%L + * Mastodon + * %% + * Copyright (C) 2014 - 2021 Tobias Pietzsch, Jean-Yves Tinevez + * %% + * 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.behaviour.io.gui; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.scijava.ui.behaviour.InputTrigger; +import org.scijava.ui.behaviour.io.InputTriggerConfig; + +/** + * A map linking {@link Command} (action name and context name) to its + * {@link DescriptionAndTriggers} (textual description and default triggers of + * the command). + *

+ * New entries are added using {@link #add(String, String[], String)}. This + * specifies only the action name of the {@code Command}. The context of the + * {@code Command} is the current context of this + * {@code CommandDescriptions}. The current context is changed by + * {@link #setKeyconfigContext(String)}, and then used for subsequently added + * entries. + */ +public final class CommandDescriptions +{ + public static final class DescriptionAndTriggers + { + private final String description; + + private final String[] defaultTriggers; + + public DescriptionAndTriggers( final String description, final String[] defaultTriggers ) + { + this.description = description; + this.defaultTriggers = defaultTriggers; + } + } + + private final Map< Command, DescriptionAndTriggers > descriptions = new LinkedHashMap<>(); + + private String context; + + /** + * Adds a new entry, linking a {@code Command} to textual description and + * default triggers. + * + * @param name + * name of the {@code Action} or {@code Behaviour}. Together with + * the current context name (see + * {@link #setKeyconfigContext(String)}) this specifies a + * {@link Command}. + * @param defaultTriggers + * default {@link InputTrigger}s for the command. + * @param description + * textual description of the command (for displaying in UI). + */ + public void add( final String name, final String[] defaultTriggers, final String description ) + { + final Command c = new Command( name, context ); + final DescriptionAndTriggers cd = new DescriptionAndTriggers( description, defaultTriggers ); + descriptions.put( c, cd ); + } + + /** + * Sets the current context. This context name is then used for subsequently + * {@link #add(String, String[], String) added} commands. + * + * @param context + * the context name. + */ + public void setKeyconfigContext( final String context ) + { + this.context = context; + } + + /** + * Builds a map from {@link Command} to textual description. This is for + * making a keyconfig {@link VisualEditorPanel}. + * + * @return a new map. + */ + public Map< Command, String > createCommandDescriptionsMap() + { + final Map< Command, String > map = new LinkedHashMap<>(); + descriptions.forEach( ( c, d ) -> map.put( c, d.description ) ); + return map; + } + + /** + * Builds a {@link InputTriggerConfig} with all commands and their default + * triggers. Commands that have no specified default triggers will have + * trigger {@code "not mapped"}. + * + * @return a new {@link InputTriggerConfig}. + */ + public InputTriggerConfig createDefaultKeyconfig() + { + final InputTriggerConfig config = new InputTriggerConfig(); + descriptions.forEach( ( c, d ) -> { + final String name = c.getName(); + final String context = c.getContext(); + final String[] triggers = d.defaultTriggers; + if ( triggers == null || triggers.length == 0 ) + config.add( "not mapped", name, context ); + else + Arrays.stream( triggers ).forEachOrdered( t -> config.add( t, name, context ) ); + } ); + return config; + } + + /** + * For commands that are not yet defined in {@code config}, add them with + * their default triggers. Commands that have no specified default triggers + * will have trigger {@code "not mapped"}. + * + * @param config + * the input trigger config to add commands to. + */ + public void augmentInputTriggerConfig( final InputTriggerConfig config ) + { + descriptions.forEach( ( c, d ) -> { + final String name = c.getName(); + final String context = c.getContext(); + if ( config.getInputs( name, context ).isEmpty() ) + { + final String[] triggers = d.defaultTriggers; + if ( triggers == null || triggers.length == 0 ) + config.add( "not mapped", name, context ); + else + Arrays.stream( triggers ).forEachOrdered( t -> config.add( t, name, context ) ); + } + } ); + } +} diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java new file mode 100644 index 0000000..9da912e --- /dev/null +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java @@ -0,0 +1,179 @@ +/*- + * #%L + * Mastodon + * %% + * Copyright (C) 2014 - 2021 Tobias Pietzsch, Jean-Yves Tinevez + * %% + * 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.behaviour.io.gui; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import java.util.function.Predicate; +import org.scijava.AbstractContextual; +import org.scijava.plugin.Parameter; +import org.scijava.plugin.PluginService; + +/** + * Helper class to populate {@link CommandDescriptions} from + * {@link CommandDescriptionProvider}s. + */ +public class CommandDescriptionsBuilder extends AbstractContextual +{ + @Parameter + private PluginService pluginService; + + private static class ProviderAndContext + { + final CommandDescriptionProvider provider; + + final String context; + + public ProviderAndContext( final CommandDescriptionProvider provider, final String context ) + { + this.provider = provider; + this.context = context; + } + } + + private final List< ProviderAndContext > registered = new ArrayList<>(); + + /** + * Manually adds a {@code provider} in a specified {@code context}. For + * example, this is useful for adding stuff in a specific order, for + * building nice {@code keyconfig.yaml} files. + * + * @param provider + * the provider to add. + * @param context + * the context to add to. + */ + public void addManually( final CommandDescriptionProvider provider, final String context ) + { + for ( final ProviderAndContext pac : registered ) + { + if ( pac.context.equals( context ) && pac.provider.getClass().equals( provider.getClass() ) ) + System.err.println( "Potential problem: a provider of class " + provider.getClass() + " is already registered for context \"" + context + "\"." ); + } + registered.add( new ProviderAndContext( provider, context ) ); + } + + /** + * Manually add a {@code provider} in the specified {@code contexts}. For + * example, this is useful for adding stuff in a specific order, for + * building nice {@code keyconfig.yaml} files. + * + * @param provider + * the provider to add. + * @param contexts + * the list of contexts to add to. + */ + public void addManually( final CommandDescriptionProvider provider, final String ... contexts ) + { + Arrays.stream( contexts ).forEachOrdered( context -> addManually( provider, context ) ); + } + + /** + * Adds all {@link CommandDescriptionProvider}s on the plugin index, with + * their respective {@link CommandDescriptionProvider#getExpectedContexts() + * expected contexts}. + */ + public void discoverProviders() + { + discoverProviders( p -> true ); + } + + /** + * Adds all {@link CommandDescriptionProvider}s on the plugin index having + * any of the given {@code scopes}, with their respective {@link + * CommandDescriptionProvider#getExpectedContexts() expected contexts}. + */ + public void discoverProviders( final CommandDescriptionProvider.Scope ... scopes ) + { + discoverProviders( Arrays.asList(scopes)::contains ); + } + + /** + * Adds all {@link CommandDescriptionProvider}s on the plugin index that + * match the given {@code predicate}, with their respective {@link + * CommandDescriptionProvider#getExpectedContexts() expected contexts}. + */ + public void discoverProviders( final Predicate< CommandDescriptionProvider > predicate ) + { + final List< CommandDescriptionProvider > providers = pluginService.createInstancesOfType( CommandDescriptionProvider.class ); + for ( final CommandDescriptionProvider provider : providers ) + if ( predicate.test( provider ) ) + for ( final String context : provider.getExpectedContexts() ) + registered.add( new ProviderAndContext( provider, context ) ); + } + + /** + * Debugging helper. Checks whether all manually added providers are + * automatically discovered, and vice versa. Prints warnings to stderr + * otherwise. + */ + public void verifyManuallyAdded() + { + final List< ProviderAndContext > discovered = new ArrayList<>(); + final List< CommandDescriptionProvider > providers = pluginService.createInstancesOfType( CommandDescriptionProvider.class ); + for ( final CommandDescriptionProvider provider : providers ) + for ( final String context : provider.getExpectedContexts() ) + discovered.add( new ProviderAndContext( provider, context ) ); + + // Can all registered providers be discovered? + boolean anyFailed = false; + A: for ( final ProviderAndContext r : registered ) + { + for ( final ProviderAndContext d : discovered ) + if ( r.context.equals( d.context ) && r.provider.getClass().equals( d.provider.getClass() ) ) + continue A; + System.err.println( r.provider.getClass() + " (\"" + r.context + "\") is manually registered, but could not be discovered." ); + anyFailed = true; + } + if ( anyFailed ) + System.err.println(); + + // Were all discovered providers manually added? + A: for ( final ProviderAndContext d : discovered ) + { + for ( final ProviderAndContext r : registered ) + if ( r.context.equals( d.context ) && r.provider.getClass().equals( d.provider.getClass() ) ) + continue A; + System.err.println( d.provider.getClass() + " (\"" + d.context + "\") was discovered, but was not manually registered." ); + } + } + + public CommandDescriptions build() + { + final CommandDescriptions descriptions = new CommandDescriptions(); + for ( final ProviderAndContext pac : registered ) + { + descriptions.setKeyconfigContext( pac.context ); + pac.provider.getCommandDescriptions( descriptions ); + } + return descriptions; + } +} diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 2d8421e..c9efd71 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -193,7 +193,7 @@ public VisualEditorPanel( final InputTriggerConfig config ) * The commands available. They are specified as a map from * command to description. Use null as value to not * specify a description. - * @see CommandDescriptionBuilder + * @see CommandDescriptionsBuilder */ public VisualEditorPanel( final InputTriggerConfig config, final Map< Command, String > commandDescriptions ) { From 5cdff4149861ff7e6d205ffd415ea5ce157fac23 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Mon, 8 Mar 2021 23:36:47 +0100 Subject: [PATCH 158/184] Behave a bit better when Look-and-Feel is changed --- .../io/gui/InputTriggerPanelEditor.java | 60 +++++++++++---- .../ui/behaviour/io/gui/TagPanelEditor.java | 73 ++++++++++++++++--- .../behaviour/io/gui/VisualEditorPanel.java | 17 ++++- 3 files changed, 122 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index 5d9cc21..965fe4e 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -54,12 +54,16 @@ import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.EmptyBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.BadLocationException; import org.scijava.ui.behaviour.InputTrigger; +import static org.scijava.ui.behaviour.io.gui.TagPanelEditor.mix; + public class InputTriggerPanelEditor extends JPanel { @@ -93,12 +97,10 @@ public InputTriggerPanelEditor( final boolean editable ) setPreferredSize( new Dimension( 400, 26 ) ); setMinimumSize( new Dimension( 26, 26 ) ); setLayout( new BoxLayout( this, BoxLayout.LINE_AXIS ) ); - setBackground( Color.white ); - setBorder( new JTextField().getBorder() ); this.textField = new JTextField(); textField.setColumns( 10 ); - textField.setBorder( null ); + textField.setBorder( new EmptyBorder( 0, 0, 0, 0 ) ); textField.setOpaque( false ); textField.setEditable( editable ); @@ -133,6 +135,14 @@ public void keyPressed( final KeyEvent e ) add( Box.createHorizontalGlue() ); } + @Override + public void updateUI() + { + super.updateUI(); + setBorder( UIManager.getBorder( "TextField.border" ) ); + setBackground( UIManager.getColor( "TextField.background" ) ); + } + public void setInputTrigger( final InputTrigger trigger ) { this.trigger = trigger; @@ -427,20 +437,19 @@ public void run() private final class KeyItem extends JPanel { - private static final long serialVersionUID = 1L; + private final boolean valid; + + private final JLabel txt; + public KeyItem( final String tag, final boolean valid ) { - final Font parentFont = InputTriggerPanelEditor.this.getFont(); - final Font font = parentFont.deriveFont( parentFont.getSize2D() - 2f ); + this.valid = valid; final String str = TRIGGER_SYMBOLS.containsKey( tag ) ? ( " " + TRIGGER_SYMBOLS.get( tag ) + " " ) : ( " " + tag + " " ); - final JLabel txt = new JLabel( str ); - txt.setFont( font ); + txt = new JLabel( str ); txt.setOpaque( true ); - if ( !valid ) - txt.setBackground( Color.PINK ); - txt.setBorder( new RoundBorder( getBackground().darker(), InputTriggerPanelEditor.this, 1 ) ); + updateTxtLook(); setLayout( new BoxLayout( this, BoxLayout.LINE_AXIS ) ); add( Box.createHorizontalStrut( 1 ) ); @@ -448,6 +457,30 @@ public KeyItem( final String tag, final boolean valid ) add( Box.createHorizontalStrut( 1 ) ); setOpaque( false ); } + + @Override + public void updateUI() + { + super.updateUI(); + updateTxtLook(); + } + + private void updateTxtLook() + { + if ( txt != null ) + { + final Color tfg = UIManager.getColor( "TextField.foreground" ); + final Color tbg = UIManager.getColor( "TextField.background" ); + final Color bg = valid ? mix( tbg, tfg, 0.95 ) : mix( tbg, Color.red, 0.5 ); + final Color borderColor = mix( bg, tfg, 0.8 ); + txt.setBackground( bg ); + txt.setBorder( new RoundBorder( borderColor, InputTriggerPanelEditor.this, 1 ) ); + + Font font = UIManager.getFont( "Label.font" ); + font = font.deriveFont( font.getSize2D() - 2f ); + txt.setFont( font ); + } + } } private void notifyListeners() @@ -479,7 +512,7 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l static { INPUT_TRIGGER_SYNTAX_TAGS.addAll( - Arrays.asList( new String[] { + Arrays.asList( "all", "ctrl", "alt", @@ -540,8 +573,7 @@ public void removeInputTriggerChangeListener( final InputTriggerChangeListener l "button2", "button3", "scroll", - "|" - } ) ); + "|" ) ); for ( int i = 0; i < 26; i++ ) INPUT_TRIGGER_SYNTAX_TAGS.add( String.valueOf( ( char ) ( 'A' + i ) ) ); for ( int i = 0; i < 10; i++ ) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java index 948f6e4..f83e8ff 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java @@ -51,6 +51,8 @@ import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.EmptyBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.text.BadLocationException; @@ -105,12 +107,10 @@ public TagPanelEditor( final Collection< String > tags, final boolean editable, setPreferredSize( new Dimension( 400, 26 ) ); setMinimumSize( new Dimension( 26, 26 ) ); setLayout( new BoxLayout( this, BoxLayout.LINE_AXIS ) ); - setBackground( Color.white ); - setBorder( new JTextField().getBorder() ); this.textField = new JTextField(); textField.setColumns( 10 ); - textField.setBorder( null ); + textField.setBorder( new EmptyBorder( 0, 0, 0, 0 ) ); textField.setOpaque( false ); textField.setEditable( editable ); @@ -144,6 +144,14 @@ public void keyPressed( final KeyEvent e ) add( Box.createHorizontalGlue() ); } + @Override + public void updateUI() + { + super.updateUI(); + setBorder( UIManager.getBorder( "TextField.border" ) ); + setBackground( UIManager.getColor( "TextField.background" ) ); + } + public List< String > getSelectedTags() { return Collections.unmodifiableList( selectedTags ); @@ -317,21 +325,25 @@ final class TagPanel extends JPanel { private static final long serialVersionUID = 1L; + private final JPanel content; + + private final boolean valid; + + private final JLabel txt; + + private JLabel close; + public TagPanel( final String tag, final boolean valid ) { - final Color bg = valid ? getBackground() : Color.PINK; - final Font font = TagPanelEditor.this.getFont().deriveFont( TagPanelEditor.this.getFont().getSize2D() - 2f ); + this.valid = valid; - final JPanel content = new JPanel(); + content = new JPanel(); content.setLayout( new BoxLayout( content, BoxLayout.LINE_AXIS ) ); content.setOpaque( true ); - content.setBackground( bg ); - content.setBorder( new RoundBorder( bg.darker(), TagPanelEditor.this, 1 ) ); if ( editable ) { - final JLabel close = new JLabel( "\u00D7" ); - close.setFont( font ); + close = new JLabel( "\u00D7" ); close.setOpaque( false ); close.addMouseListener( new java.awt.event.MouseAdapter() { @@ -346,10 +358,10 @@ public void mousePressed( final java.awt.event.MouseEvent evt ) } final String str = printables.containsKey( tag ) ? printables.get( tag ) : tag; - final JLabel txt = new JLabel( str ); - txt.setFont( font ); + txt = new JLabel( str ); txt.setOpaque( false ); content.add( txt ); + updateTxtLook(); setLayout( new BoxLayout( this, BoxLayout.LINE_AXIS ) ); add( Box.createHorizontalStrut( 1 ) ); @@ -357,6 +369,32 @@ public void mousePressed( final java.awt.event.MouseEvent evt ) add( Box.createHorizontalStrut( 4 ) ); setOpaque( false ); } + + @Override + public void updateUI() + { + super.updateUI(); + updateTxtLook(); + } + + private void updateTxtLook() + { + if ( content != null ) + { + final Color tfg = UIManager.getColor( "TextField.foreground" ); + final Color tbg = UIManager.getColor( "TextField.background" ); + final Color bg = valid ? mix( tbg, tfg, 0.95 ) : mix( tbg, Color.red, 0.5 ); + final Color borderColor = mix( bg, tfg, 0.8 ); + content.setBackground( bg ); + content.setBorder( new RoundBorder( borderColor, TagPanelEditor.this, 1 ) ); + + Font font = UIManager.getFont( "Label.font" ); + font = font.deriveFont( font.getSize2D() - 2f ); + txt.setFont( font ); + if ( close != null ) + close.setFont( font ); + } + } } private static Box.Filler createHorizontalStrutWithMaxHeight1( final int width ) @@ -382,4 +420,15 @@ public void removeTagSelectionChangeListener( final TagSelectionChangeListener l listeners.remove( listener ); } + /** + * Mix colors {@code c1} and {@code c2} by ratios {@code c1Weight} and {@code (1-c1Weight)}, respectively. + */ + static Color mix( final Color c1, final Color c2, final double c1Weight ) + { + final double c2Weight = 1.0 - c1Weight; + return new Color( + ( int ) ( c1.getRed() * c1Weight + c2.getRed() * c2Weight ), + ( int ) ( c1.getGreen() * c1Weight + c2.getGreen() * c2Weight ), + ( int ) ( c1.getBlue() * c1Weight + c2.getBlue() * c2Weight ) ); + } } diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index c9efd71..ba9cbc0 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -68,6 +68,7 @@ import javax.swing.ListSelectionModel; import javax.swing.RowFilter; import javax.swing.ScrollPaneConstants; +import javax.swing.border.EmptyBorder; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; @@ -900,7 +901,13 @@ private final class MyContextsRenderer extends TagPanelEditor implements TableCe public MyContextsRenderer( final Collection< String > tags ) { super( tags, false ); - setBorder( null ); + } + + @Override + public void updateUI() + { + super.updateUI(); + setBorder( new EmptyBorder( 0, 0, 0, 0 ) ); } @Override @@ -930,7 +937,13 @@ private static final class MyBindingsRenderer extends InputTriggerPanelEditor im public MyBindingsRenderer() { super( false ); - setBorder( null ); + } + + @Override + public void updateUI() + { + super.updateUI(); + setBorder( new EmptyBorder( 0, 0, 0, 0 ) ); } @Override From 168bbc2dced0c0909dc1ad1042fc8d1d27c41b8f Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Tue, 9 Mar 2021 16:02:02 +0100 Subject: [PATCH 159/184] Fix NPE --- .../org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index ba9cbc0..29710a4 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -920,7 +920,9 @@ public Component getTableCellRendererComponent( final JTable table, final Object setAcceptableTags( commandNameToAcceptableContexts.get( name ) ); @SuppressWarnings( "unchecked" ) - final List< String > contexts = ( List< String > ) value; + final List< String > contexts = value != null + ? ( List< String > ) value + : Collections.emptyList(); if ( contexts.isEmpty() ) setBackground( Color.PINK ); setTags( contexts ); From 486e59d4861fde8842e15912b8739387e234b2ad Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Tue, 23 Mar 2021 11:13:35 +0100 Subject: [PATCH 160/184] Update license headers --- LICENSE.txt | 2 +- .../scijava/ui/behaviour/AbstractMouseAndKeyHandler.java | 2 +- src/main/java/org/scijava/ui/behaviour/Behaviour.java | 2 +- src/main/java/org/scijava/ui/behaviour/BehaviourMap.java | 2 +- .../java/org/scijava/ui/behaviour/ClickBehaviour.java | 2 +- .../java/org/scijava/ui/behaviour/DragBehaviour.java | 2 +- .../scijava/ui/behaviour/GlobalKeyEventDispatcher.java | 2 +- src/main/java/org/scijava/ui/behaviour/InputTrigger.java | 2 +- .../java/org/scijava/ui/behaviour/InputTriggerAdder.java | 2 +- .../java/org/scijava/ui/behaviour/InputTriggerMap.java | 2 +- .../java/org/scijava/ui/behaviour/KeyPressedManager.java | 2 +- .../java/org/scijava/ui/behaviour/KeyStrokeAdder.java | 2 +- .../org/scijava/ui/behaviour/MouseAndKeyHandler.java | 2 +- .../java/org/scijava/ui/behaviour/ScrollBehaviour.java | 2 +- .../org/scijava/ui/behaviour/io/InputTriggerConfig.java | 2 +- .../scijava/ui/behaviour/io/InputTriggerDescription.java | 2 +- .../ui/behaviour/io/InputTriggerDescriptionsBuilder.java | 2 +- .../java/org/scijava/ui/behaviour/io/gui/Command.java | 2 +- .../ui/behaviour/io/gui/CommandDescriptionProvider.java | 9 +++++---- .../scijava/ui/behaviour/io/gui/CommandDescriptions.java | 9 +++++---- .../ui/behaviour/io/gui/CommandDescriptionsBuilder.java | 9 +++++---- .../ui/behaviour/io/gui/InputTriggerPanelEditor.java | 2 +- .../org/scijava/ui/behaviour/io/gui/RoundBorder.java | 2 +- .../org/scijava/ui/behaviour/io/gui/TagPanelEditor.java | 2 +- .../scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 2 +- .../org/scijava/ui/behaviour/io/json/JsonConfigIO.java | 2 +- .../org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java | 2 +- src/main/java/org/scijava/ui/behaviour/package-info.java | 2 +- .../scijava/ui/behaviour/util/AbstractNamedAction.java | 2 +- .../ui/behaviour/util/AbstractNamedBehaviour.java | 2 +- src/main/java/org/scijava/ui/behaviour/util/Actions.java | 2 +- .../java/org/scijava/ui/behaviour/util/Behaviours.java | 2 +- .../scijava/ui/behaviour/util/InputActionBindings.java | 2 +- .../org/scijava/ui/behaviour/util/RunnableAction.java | 2 +- .../ui/behaviour/util/TriggerBehaviourBindings.java | 2 +- .../org/scijava/ui/behaviour/util/WrappedActionMap.java | 2 +- .../scijava/ui/behaviour/util/WrappedBehaviourMap.java | 2 +- .../org/scijava/ui/behaviour/util/WrappedInputMap.java | 2 +- .../ui/behaviour/util/WrappedInputTriggerMap.java | 2 +- .../org/scijava/ui/behaviour/EventsInteractiveTest.java | 2 +- .../org/scijava/ui/behaviour/MultiWindowExample.java | 2 +- src/test/java/org/scijava/ui/behaviour/UsageExample.java | 2 +- .../ui/behaviour/io/gui/VisualEditorPanelDemo.java | 6 +++--- .../ui/behaviour/io/json/JsonInteractiveTest.java | 2 +- .../ui/behaviour/io/yaml/YamlInteractiveTest.java | 2 +- 45 files changed, 59 insertions(+), 56 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 4fdf2bb..53d3c5e 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2015 - 2020, Max Planck Institute of Molecular Cell Biology +Copyright (c) 2015 - 2021, Max Planck Institute of Molecular Cell Biology and Genetics. All rights reserved. diff --git a/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java index b455358..1496829 100644 --- a/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/Behaviour.java b/src/main/java/org/scijava/ui/behaviour/Behaviour.java index d80148f..0c4eb2e 100644 --- a/src/main/java/org/scijava/ui/behaviour/Behaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/Behaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java index 99d52f9..6abfa84 100644 --- a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java +++ b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java b/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java index 84add22..e915d49 100644 --- a/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java b/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java index 56a1caa..efa059a 100644 --- a/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java b/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java index 8318401..904ac28 100644 --- a/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java +++ b/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java index 2047a7d..c043e1f 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java index e00cd71..8b20842 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java index 0d77f1a..93a6b02 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java index bc53419..d2b1f2c 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java index ab0b8b3..c608ea0 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java index e300fa0..948e1f8 100644 --- a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java b/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java index d188338..b290c59 100644 --- a/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index d263c48..8dd20c7 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java index 04a78af..c82e086 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java index c7d6e51..90aea81 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java b/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java index 55a441e..d1427d1 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java index 9cc39bb..6b1974b 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java @@ -1,18 +1,19 @@ /*- * #%L - * Mastodon + * Configurable key and mouse event handling * %% - * Copyright (C) 2014 - 2021 Tobias Pietzsch, Jean-Yves Tinevez + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * and Genetics. * %% * 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 diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java index 25563ee..dd2d5eb 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java @@ -1,18 +1,19 @@ /*- * #%L - * Mastodon + * Configurable key and mouse event handling * %% - * Copyright (C) 2014 - 2021 Tobias Pietzsch, Jean-Yves Tinevez + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * and Genetics. * %% * 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 diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java index 9da912e..af725c1 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java @@ -1,18 +1,19 @@ /*- * #%L - * Mastodon + * Configurable key and mouse event handling * %% - * Copyright (C) 2014 - 2021 Tobias Pietzsch, Jean-Yves Tinevez + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * and Genetics. * %% * 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 diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index 965fe4e..16a53c3 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java index 399e98b..dbfa0db 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java index f83e8ff..d0a9cc9 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 29710a4..2bcf4d1 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java index 9148449..a93cd8f 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java index 7493713..d4297b4 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/package-info.java b/src/main/java/org/scijava/ui/behaviour/package-info.java index ddfe757..0f3faf3 100644 --- a/src/main/java/org/scijava/ui/behaviour/package-info.java +++ b/src/main/java/org/scijava/ui/behaviour/package-info.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java index 1cb234f..f6f9983 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java index 6efe2a2..0492b16 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index 82751a3..cb1ff4f 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java index f9d9c6d..165fca1 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java index b697f6c..3cfb33d 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java index 24359e1..19355b6 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java index 4b1aff1..b0e51b2 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java index bc7e2ad..5c2a44d 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java index aa12a46..3a3c366 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java index 7b71047..43bae3a 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java index 09dccb8..a2e8326 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java index 8f13677..4713e6f 100644 --- a/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java b/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java index 63a6c6f..edfd345 100644 --- a/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java +++ b/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/UsageExample.java b/src/test/java/org/scijava/ui/behaviour/UsageExample.java index 5118709..cb2c239 100644 --- a/src/test/java/org/scijava/ui/behaviour/UsageExample.java +++ b/src/test/java/org/scijava/ui/behaviour/UsageExample.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java index b121295..532bdfa 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java @@ -2,18 +2,18 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * 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 diff --git a/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java index e04b01b..d4b7e28 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java index 98a7dc5..c9198ab 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2020 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without From d23da8b3f27e1a008e1484a856668ef8cfed95b9 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Tue, 23 Mar 2021 11:15:06 +0100 Subject: [PATCH 161/184] Bump to next development cycle Signed-off-by: tpietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0952662..bacb4e1 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 2.0.4-SNAPSHOT + 2.0.5-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 33de3c0472bced86122b1ed3015a7593d8f88e2d Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 24 Mar 2021 11:28:29 +0100 Subject: [PATCH 162/184] bugfix --- .../scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java index af725c1..d079ecc 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java @@ -114,7 +114,7 @@ public void discoverProviders() */ public void discoverProviders( final CommandDescriptionProvider.Scope ... scopes ) { - discoverProviders( Arrays.asList(scopes)::contains ); + discoverProviders( provider -> Arrays.asList( scopes ).contains( provider.getScope() ) ); } /** From eaba41ec9ac7348a3cf64f31e31669614d0fd5dc Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 24 Mar 2021 11:29:56 +0100 Subject: [PATCH 163/184] Bump to next development cycle Signed-off-by: tpietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bacb4e1..e0f956a 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 2.0.5-SNAPSHOT + 2.0.6-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 80ec4a61e223cf109af56dc6144e5dd4ef85950e Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Thu, 1 Jul 2021 15:51:37 -0500 Subject: [PATCH 164/184] Switch from Travis CI to GitHub Actions --- {.travis => .github}/build.sh | 4 +-- .github/setup.sh | 3 +++ .github/workflows/build-main.yml | 42 ++++++++++++++++++++++++++++++++ .github/workflows/build-pr.yml | 35 ++++++++++++++++++++++++++ .travis.yml | 12 --------- README.md | 2 +- pom.xml | 6 ++--- 7 files changed, 86 insertions(+), 18 deletions(-) rename {.travis => .github}/build.sh (61%) create mode 100755 .github/setup.sh create mode 100644 .github/workflows/build-main.yml create mode 100644 .github/workflows/build-pr.yml delete mode 100644 .travis.yml diff --git a/.travis/build.sh b/.github/build.sh similarity index 61% rename from .travis/build.sh rename to .github/build.sh index e939b6c..7da4262 100755 --- a/.travis/build.sh +++ b/.github/build.sh @@ -1,3 +1,3 @@ #!/bin/sh -curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/master/travis-build.sh -sh travis-build.sh +curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/master/ci-build.sh +sh ci-build.sh diff --git a/.github/setup.sh b/.github/setup.sh new file mode 100755 index 0000000..f359bbe --- /dev/null +++ b/.github/setup.sh @@ -0,0 +1,3 @@ +#!/bin/sh +curl -fsLO https://raw.githubusercontent.com/scijava/scijava-scripts/master/ci-setup-github-actions.sh +sh ci-setup-github-actions.sh diff --git a/.github/workflows/build-main.yml b/.github/workflows/build-main.yml new file mode 100644 index 0000000..45b6b5e --- /dev/null +++ b/.github/workflows/build-main.yml @@ -0,0 +1,42 @@ +name: build + +on: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Cache m2 folder + uses: actions/cache@v2 + env: + cache-name: cache-m2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-build-${{ env.cache-name }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: Set up JDK 8 + uses: actions/setup-java@v2 + with: + java-version: '8' + distribution: 'zulu' + - name: Set up CI environment + run: .github/setup.sh + - name: Execute the build + run: .github/build.sh + env: + GPG_KEY_NAME: ${{ secrets.GPG_KEY_NAME }} + GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + MAVEN_USER: ${{ secrets.MAVEN_USER }} + MAVEN_PASS: ${{ secrets.MAVEN_PASS }} + OSSRH_PASS: ${{ secrets.OSSRH_PASS }} + SIGNING_ASC: ${{ secrets.SIGNING_ASC }} diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml new file mode 100644 index 0000000..92a0192 --- /dev/null +++ b/.github/workflows/build-pr.yml @@ -0,0 +1,35 @@ +name: build PR + +on: + pull_request: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Cache m2 folder + uses: actions/cache@v2 + env: + cache-name: cache-m2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-build-${{ env.cache-name }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: Set up JDK 8 + uses: actions/setup-java@v2 + with: + java-version: '8' + distribution: 'zulu' + - name: Set up CI environment + run: .github/setup.sh + - name: Execute the build + run: .github/build.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 961356c..0000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: java -jdk: openjdk8 -branches: - only: - - master - - "/.*-[0-9]+\\..*/" -install: true -script: ".travis/build.sh" -env: - global: - - secure: YRNfBvbeO4779HH3rkuat08sFAhGIFJUNil9iSLO3KuiiS+o940jPQoJUXw2N+U9EtZtl78EeKOLRP9/98Lyt7H8Lh1ml5ELw5eA0cr+PUENoKi2Wygm7OG96bLGydhRGj/thX1gKA8DyveOpNNuSnINTq/zTvqo5dYNTRhmQ9uRAWJ7Iag6UWjXVNQabIf0qrGQ+DHnVtdMq3t8XPdeckaum22Xl1sPem+iPIj0E2jftwDGfEJ4y+7m881+0lUDDsqzZ6ag+YGKrEYg2VeoHJU62/XKbGBgSHfGZb0b88ps0PN8wCv3VYcrNx3hCi2G8awYjg6s+LOs/IOaKX0UsTFf5oexAmxlgT8TMtxtMEG03o/4W/AuppNz5H9kiusvWdBKv2ZfLUTgh2lW4fxpJweBCYVw7bM2na9SOO9bXvjxBHFjmv3f6CxhBzQ9qsjZInbSo3F3KUI0dNmf9VYqG0YP9zcL75E7L1GgrGvbboACpiZfq6e6RIhST0JBkOaPs0nBc4jrdd1Xf6I2F5ppxl0ODBmbmtUsccb7UMFQlXLIKtK0hLnT46JXcSzDwYob7+WnGvnuyyCc4RvMnO8Va8wp3ykdp+xKwD0RXV4LDqiFuRPFccO9KH4Q1memzOHE2hn5nCWK3JUcv2H0PdUmax87s7ehCMAC8d1VJBBxXkU= - - secure: C/hGRQ4Fkhy1TB8bYlNXuHu1f8YDp8r+5lQCj8IHiErPih/ac1t8qatgg6K9rBN8G+gyOAoc3yUtxI8I2FV3lgpaRYZRTCTss7II0W39zYLr+nYZsitzgpB0dXg1O8kRVTk7h6eHufmGfui9XLXsZY9Ovg+gYwX0eVyrgYSQlU7WPy+HuvwtwEryKxFTIW7WXe/oKtV6kWLtwISd/kADrhEeUbwi02xS6udBFDLPQwBzFBu7AKc8WiEhpGXEooywewi/0S85f1KnBh43i6/erKw3ltKfgRspwpYyJTnpJphicUvD7CIGMlCcjfm6oOH8TOfSLnEGNu9mrXRchB8izXzHcgQv2DTlpkv5S9RCQnHp4vut39beLjXQu1fMufvz1aSe4hdpSzNwwTn0mNnROm7kicF2CkdoGnXX438k+54C9XQo/VqkD3rno5V/rplZcClss5F2AmA23K4Tl0p6UECO//jdXWcEUiZrXvMrIf7qljvHXmbzrmZEe98oYg0vDPfVoRHn96VE9X3iyzTYDqkkvATvifFqyvbUvBcSUlDa/M6w3cP9IAYEgzbD8+Tq0FPEGIajGhE+Fht7+QVzRaoif++/5l0LxFXDiJIPdGp5GgrnkF+ueSL4ALNxv8EfIxOY6p0u0woYFsN2TObLRaRxNO2Y7XtyetEv3shAUiM= diff --git a/README.md b/README.md index 02b487a..d7de467 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![](https://travis-ci.org/scijava/ui-behaviour.svg?branch=master)](https://travis-ci.org/scijava/ui-behaviour) +[![](https://github.com/scijava/ui-behaviour/actions/workflows/build-main.yml/badge.svg)](https://github.com/scijava/ui-behaviour/actions/workflows/build-main.yml) # configurable-keys diff --git a/pom.xml b/pom.xml index e0f956a..3dc872b 100644 --- a/pom.xml +++ b/pom.xml @@ -90,8 +90,8 @@ https://github.com/scijava/ui-behaviour/issues - Travis CI - https://travis-ci.org/scijava/ui-behaviour + GitHub Actions + https://github.com/scijava/ui-behaviour/actions @@ -101,7 +101,7 @@ and Genetics. - deploy-to-scijava + sign,deploy-to-scijava From 4866148ec982dee24354174229f9ca07df875297 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Fri, 2 Jul 2021 09:50:12 -0500 Subject: [PATCH 165/184] CI: build release tags --- .github/workflows/build-main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-main.yml b/.github/workflows/build-main.yml index 45b6b5e..3fb5622 100644 --- a/.github/workflows/build-main.yml +++ b/.github/workflows/build-main.yml @@ -4,6 +4,8 @@ on: push: branches: - master + tags: + - "*-[0-9]+.*" jobs: build: From ecf201a84d196526a563f384b91d8c9ebd4fbb83 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Sat, 23 Oct 2021 19:12:23 -0500 Subject: [PATCH 166/184] POM: update parent POM version and imagej.net URLs --- pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 3dc872b..500e32b 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.scijava pom-scijava - 30.0.0 + 31.1.0 ui-behaviour @@ -31,7 +31,7 @@ tpietzsch Tobias Pietzsch - https://imagej.net/User:Pietzsch + https://imagej.net/people/tpietzsch founder lead @@ -45,7 +45,7 @@ tinevez Jean-Yves Tinevez - https://imagej.net/User:JeanYvesTinevez + https://imagej.net/people/tinevez developer debugger @@ -55,7 +55,7 @@ ctrueden Curtis Rueden - https://imagej.net/User:Rueden + https://imagej.net/people/ctrueden maintainer @@ -64,7 +64,7 @@ Ulrik Günther - https://imagej.net/User:Skalarproduktraum + https://imagej.net/people/skalarproduktraum skalarproduktraum From 3cf462dcbd6d45be436d9aff2f8563159c8916a2 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Mon, 8 Nov 2021 15:42:45 -0600 Subject: [PATCH 167/184] POM: Stop using git:// protocol with github.com The GitHub platform is discontinuing support for it. See: https://github.blog/2021-09-01-improving-git-protocol-security-github/#whats-changing --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 500e32b..aa42aba 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,7 @@ - scm:git:git://github.com/scijava/ui-behaviour + scm:git:https://github.com/scijava/ui-behaviour scm:git:git@github.com:scijava/ui-behaviour HEAD https://github.com/scijava/ui-behaviour From bfdce0b4ffaf6d34506ba2c69fdcf7474752df93 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Fri, 10 Jun 2022 10:06:31 -0400 Subject: [PATCH 168/184] Don't use fixed table row height. Make it dependent on font size --- .../scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 2bcf4d1..10f16ca 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -403,11 +403,17 @@ public void changedUpdate( final DocumentEvent e ) scrollPane.setHorizontalScrollBarPolicy( ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER ); add( scrollPane, BorderLayout.CENTER ); - tableBindings = new JTable(); + tableBindings = new JTable() { + @Override + public void updateUI() + { + super.updateUI(); + setRowHeight( ( int ) ( getFontMetrics( getFont() ).getHeight() * 1.5 ) ); + } + }; tableBindings.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); tableBindings.setFillsViewportHeight( true ); tableBindings.setAutoResizeMode( JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS ); - tableBindings.setRowHeight( 30 ); tableBindings.getSelectionModel().addListSelectionListener( new ListSelectionListener() { @Override From 52a122f870c070d75ed4e78f471f40cbcaab80b1 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 14 Jun 2022 15:54:36 -0500 Subject: [PATCH 169/184] CI: cache ~/.m2/repository correctly --- .github/workflows/build-main.yml | 18 +++--------------- .github/workflows/build-pr.yml | 18 +++--------------- 2 files changed, 6 insertions(+), 30 deletions(-) diff --git a/.github/workflows/build-main.yml b/.github/workflows/build-main.yml index 3fb5622..5ef5692 100644 --- a/.github/workflows/build-main.yml +++ b/.github/workflows/build-main.yml @@ -13,24 +13,12 @@ jobs: steps: - uses: actions/checkout@v2 - - - name: Cache m2 folder - uses: actions/cache@v2 - env: - cache-name: cache-m2 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-build-${{ env.cache-name }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - - name: Set up JDK 8 - uses: actions/setup-java@v2 + - name: Set up Java + uses: actions/setup-java@v3 with: java-version: '8' distribution: 'zulu' + cache: 'maven' - name: Set up CI environment run: .github/setup.sh - name: Execute the build diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 92a0192..925b576 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -11,24 +11,12 @@ jobs: steps: - uses: actions/checkout@v2 - - - name: Cache m2 folder - uses: actions/cache@v2 - env: - cache-name: cache-m2 - with: - path: ~/.m2/repository - key: ${{ runner.os }}-build-${{ env.cache-name }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - - name: Set up JDK 8 - uses: actions/setup-java@v2 + - name: Set up Java + uses: actions/setup-java@v3 with: java-version: '8' distribution: 'zulu' + cache: 'maven' - name: Set up CI environment run: .github/setup.sh - name: Execute the build From 9e4d01c57f6d28acfdebaefb41957a199553bfdc Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 15 Jun 2022 17:11:42 -0400 Subject: [PATCH 170/184] POM: Bump parent to pom-scijava 32.0.0-beta-4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index aa42aba..b2dfa35 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.scijava pom-scijava - 31.1.0 + 32.0.0-beta-4 ui-behaviour From 2246c535919cb2d00df6816ddce8bad7bd384a20 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 15 Jun 2022 17:13:29 -0400 Subject: [PATCH 171/184] Update license headers --- LICENSE.txt | 2 +- .../org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java | 2 +- src/main/java/org/scijava/ui/behaviour/Behaviour.java | 2 +- src/main/java/org/scijava/ui/behaviour/BehaviourMap.java | 2 +- src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java | 2 +- src/main/java/org/scijava/ui/behaviour/DragBehaviour.java | 2 +- .../java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java | 2 +- src/main/java/org/scijava/ui/behaviour/InputTrigger.java | 2 +- src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java | 2 +- src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java | 2 +- src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java | 2 +- src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java | 2 +- src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java | 2 +- src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java | 2 +- .../java/org/scijava/ui/behaviour/io/InputTriggerConfig.java | 2 +- .../org/scijava/ui/behaviour/io/InputTriggerDescription.java | 2 +- .../ui/behaviour/io/InputTriggerDescriptionsBuilder.java | 2 +- src/main/java/org/scijava/ui/behaviour/io/gui/Command.java | 2 +- .../scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java | 2 +- .../org/scijava/ui/behaviour/io/gui/CommandDescriptions.java | 2 +- .../scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java | 2 +- .../scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java | 2 +- src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java | 2 +- .../java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java | 2 +- .../java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 2 +- .../java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java | 2 +- .../java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java | 2 +- src/main/java/org/scijava/ui/behaviour/package-info.java | 2 +- .../java/org/scijava/ui/behaviour/util/AbstractNamedAction.java | 2 +- .../org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java | 2 +- src/main/java/org/scijava/ui/behaviour/util/Actions.java | 2 +- src/main/java/org/scijava/ui/behaviour/util/Behaviours.java | 2 +- .../java/org/scijava/ui/behaviour/util/InputActionBindings.java | 2 +- src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java | 2 +- .../org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java | 2 +- .../java/org/scijava/ui/behaviour/util/WrappedActionMap.java | 2 +- .../java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java | 2 +- .../java/org/scijava/ui/behaviour/util/WrappedInputMap.java | 2 +- .../org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java | 2 +- .../java/org/scijava/ui/behaviour/EventsInteractiveTest.java | 2 +- src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java | 2 +- src/test/java/org/scijava/ui/behaviour/UsageExample.java | 2 +- .../org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java | 2 +- .../org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java | 2 +- .../org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java | 2 +- 45 files changed, 45 insertions(+), 45 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 53d3c5e..1687e07 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2015 - 2021, Max Planck Institute of Molecular Cell Biology +Copyright (c) 2015 - 2022, Max Planck Institute of Molecular Cell Biology and Genetics. All rights reserved. diff --git a/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java index 1496829..cdf811a 100644 --- a/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/Behaviour.java b/src/main/java/org/scijava/ui/behaviour/Behaviour.java index 0c4eb2e..543c8b9 100644 --- a/src/main/java/org/scijava/ui/behaviour/Behaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/Behaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java index 6abfa84..021bb6a 100644 --- a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java +++ b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java b/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java index e915d49..25616af 100644 --- a/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java b/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java index efa059a..052b43c 100644 --- a/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java b/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java index 904ac28..73289fe 100644 --- a/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java +++ b/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java index c043e1f..1e0c189 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java index 8b20842..3760af6 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java index 93a6b02..3db69ce 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java index d2b1f2c..723c9b1 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java index c608ea0..05b3ad8 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java index 948e1f8..17811c9 100644 --- a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java b/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java index b290c59..b93b0bb 100644 --- a/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 8dd20c7..e443709 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java index c82e086..fa1b9b5 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java index 90aea81..5e664f5 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java b/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java index d1427d1..bd5c8b8 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java index 6b1974b..e391a1d 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java index dd2d5eb..b19dada 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java index d079ecc..27b94ef 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index 16a53c3..5b0cf05 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java index dbfa0db..bf71a88 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java index d0a9cc9..91013e5 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index 10f16ca..d77c7e3 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java index a93cd8f..2b4b2dc 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java index d4297b4..e38b09c 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/package-info.java b/src/main/java/org/scijava/ui/behaviour/package-info.java index 0f3faf3..8bb95ef 100644 --- a/src/main/java/org/scijava/ui/behaviour/package-info.java +++ b/src/main/java/org/scijava/ui/behaviour/package-info.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java index f6f9983..68d011b 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java index 0492b16..7600699 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index cb1ff4f..3da90c5 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java index 165fca1..ace1003 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java index 3cfb33d..3e22ec2 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java index 19355b6..5c9d40e 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java index b0e51b2..3f903eb 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java index 5c2a44d..55ebb48 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java index 3a3c366..9319690 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java index 43bae3a..8a97777 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java index a2e8326..82aac7a 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java index 4713e6f..8200253 100644 --- a/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java b/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java index edfd345..22c4368 100644 --- a/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java +++ b/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/UsageExample.java b/src/test/java/org/scijava/ui/behaviour/UsageExample.java index cb2c239..d871b4a 100644 --- a/src/test/java/org/scijava/ui/behaviour/UsageExample.java +++ b/src/test/java/org/scijava/ui/behaviour/UsageExample.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java index 532bdfa..03bd24c 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java index d4b7e28..92637f5 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java index c9198ab..0ec2f97 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2021 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without From 4972921a218257485b62bd2ece5c06d67f75c0b2 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 15 Jun 2022 17:48:21 -0400 Subject: [PATCH 172/184] Fix javadoc error --- src/main/java/org/scijava/ui/behaviour/package-info.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/package-info.java b/src/main/java/org/scijava/ui/behaviour/package-info.java index 8bb95ef..b77038c 100644 --- a/src/main/java/org/scijava/ui/behaviour/package-info.java +++ b/src/main/java/org/scijava/ui/behaviour/package-info.java @@ -28,7 +28,7 @@ * #L% */ /** - *

Configurable-keys

Simplify making AWT mouse-handlers configurable. + *

Configurable-keys

Simplify making AWT mouse-handlers configurable. * * Works along the lines of the InputMap / ActionMap mechanism. The syntax for * defining key and mouse "triggers" is described in the InputTrigger-syntax From a3341e51e9b06359148bc25a50f741ac96a4aa3c Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 15 Jun 2022 22:22:01 -0400 Subject: [PATCH 173/184] POM: use HTTPS for schema location URL Maven no longer supports plain HTTP for the schema location. And using HTTP now generates errors in Eclipse (and probably other IDEs). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b2dfa35..4d14cb4 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,5 @@ - + 4.0.0 From 5f01ece326a1ea2f064420220ec7e98d34f3c65e Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 15 Jun 2022 22:22:52 -0400 Subject: [PATCH 174/184] Bump to next development cycle Signed-off-by: tpietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4d14cb4..d625e56 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 2.0.6-SNAPSHOT + 2.0.7-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 1a3d136c70db60e62940efde3069ef06452088ab Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 20 Jul 2022 09:49:55 +0200 Subject: [PATCH 175/184] Add descriptive InputTriggerConfig.toString() --- .../org/scijava/ui/behaviour/io/InputTriggerConfig.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index e443709..b0b27ff 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -229,6 +229,12 @@ public synchronized void remove( final InputTrigger trigger, final String behavi } } + @Override + public String toString() + { + return "InputTriggerConfig{" + new InputTriggerDescriptionsBuilder( this ).getDescriptions() + '}'; + } + public static class InputTriggerAdderImp implements InputTriggerAdder { private final InputTriggerMap map; From 1879f548b541302312d5c65212d6de7372eece85 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Wed, 20 Jul 2022 13:26:05 +0200 Subject: [PATCH 176/184] Simplify TriggerDescriptionsBuilder --- .../ui/behaviour/io/InputTriggerDescription.java | 10 ++++++++++ .../io/InputTriggerDescriptionsBuilder.java | 14 +++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java index fa1b9b5..4fe9197 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java @@ -29,6 +29,7 @@ */ package org.scijava.ui.behaviour.io; +import java.util.Arrays; import javax.swing.Action; import org.scijava.ui.behaviour.Behaviour; @@ -121,4 +122,13 @@ public void setContexts( final String[] contexts ) else this.contexts = contexts; } + + public void addTrigger( final String trigger ) + { + if ( !Arrays.asList( triggers ).contains( trigger ) ) + { + triggers = Arrays.copyOf( triggers, triggers.length + 1 ); + triggers[ triggers.length - 1 ] = trigger; + } + } } diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java index 5e664f5..a1dbdd0 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java @@ -65,11 +65,9 @@ public InputTriggerDescriptionsBuilder( final InputTriggerConfig config ) public List< InputTriggerDescription > getDescriptions() { final ArrayList< InputTriggerDescription > descs = new ArrayList<>(); - final String[] emptyStringArray = new String[ 0 ]; - for ( final Entry< String, Set< Input > > entry : config.actionToInputsMap.entrySet() ) + for ( final Set< Input > inputs : config.actionToInputsMap.values() ) { - final Set< Input > inputs = entry.getValue(); for ( final Input input : inputs ) { boolean found = false; @@ -78,20 +76,14 @@ public List< InputTriggerDescription > getDescriptions() if ( input.behaviour.equals( desc.getAction() ) && input.contexts.equals( new HashSet<>( Arrays.asList( desc.getContexts() ) ) ) ) { - final HashSet< String > triggers = new HashSet<>( Arrays.asList( desc.getTriggers() ) ); - triggers.add( input.trigger.toString() ); - desc.setTriggers( triggers.toArray( emptyStringArray ) ); + desc.addTrigger( input.trigger.toString() ); found = true; break; } } if ( !found ) { - final InputTriggerDescription desc = new InputTriggerDescription( - new String[] { input.trigger.toString() }, - input.behaviour, - input.contexts.toArray( emptyStringArray ) ); - descs.add( desc ); + descs.add( input.getDescription() ); } } } From 437fdc746dc709e534206637248d57c37db1e13e Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sun, 24 Jul 2022 10:43:39 +0200 Subject: [PATCH 177/184] Fix warning in Actions.updateKeyConfig When rebuilding the InputMap, don't try to put unassigned actions back with triggers from the new config (they are not assigned there, of course). This avoids printing warnings like "Could not assign KeyStroke for ... Nothing defined in InputTriggerConfig, and no default given." --- src/main/java/org/scijava/ui/behaviour/util/Actions.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index 3da90c5..5257a94 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -237,7 +237,8 @@ public void updateKeyConfig( final InputTriggerConfig keyConfig, final boolean c final Object[] keys = actionMap.keys(); if ( keys != null ) for ( final Object o : keys ) - keyStrokeAdder.put( ( String ) o ); + if ( !unassigned.containsKey( o ) ) + keyStrokeAdder.put( ( String ) o ); unassigned.forEach( ( actionMapKey, keyStrokes ) -> keyStrokes.forEach( keyStroke -> inputMap.put( keyStroke, actionMapKey ) ) ); } From 2f28d85d938d2add7233ab120e18c97920ed00a7 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sun, 24 Jul 2022 10:48:13 +0200 Subject: [PATCH 178/184] fix javadoc --- .../ui/behaviour/io/gui/CommandDescriptionProvider.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java index e391a1d..bfe1c89 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java @@ -52,9 +52,6 @@ protected CommandDescriptionProvider( final Scope scope, final String... expecte } /** - * The contexts in which the described actions/bahaviours are expected to be - * used. - *

* The scope describes the application / Fiji plugin that the actions are * defined in. This is to make it possible to only harvest descriptions * for the desired scopes. @@ -73,7 +70,7 @@ public Scope getScope() } /** - * The contexts in which the described actions/bahaviours are expected to be + * The contexts in which the described actions/behaviours are expected to be * used. *

* Note that {@code CommandDescriptionProvider} is only used for harvesting From bc1698150ede02caf7df4769fd0fccae0a4d30af Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Sun, 24 Jul 2022 10:48:37 +0200 Subject: [PATCH 179/184] minor simplification --- .../org/scijava/ui/behaviour/io/InputTriggerConfig.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index b0b27ff..8d432af 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -260,8 +260,7 @@ public InputTriggerAdderImp( { this.map = map; this.config = config; - this.contexts = new HashSet<>(); - this.contexts.addAll( Arrays.asList( contexts ) ); + this.contexts = new HashSet<>( Arrays.asList( contexts ) ); } @Override @@ -338,8 +337,7 @@ public KeyStrokeAdderImp( { this.map = map; this.config = config; - this.contexts = new HashSet<>(); - this.contexts.addAll( Arrays.asList( contexts ) ); + this.contexts = new HashSet<>( Arrays.asList( contexts ) ); } @Deprecated From 019f2256ba2bc3f763388153e936be4ef9509c58 Mon Sep 17 00:00:00 2001 From: tpietzsch Date: Thu, 4 Aug 2022 14:47:41 +0200 Subject: [PATCH 180/184] Bump to next development cycle Signed-off-by: tpietzsch --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d625e56..d1fda2c 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ ui-behaviour - 2.0.7-SNAPSHOT + 2.0.8-SNAPSHOT UI Behaviour Configurable key and mouse event handling From 9cbc0df842c240e36af48b48fc294ea8c982a63d Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Mon, 20 Mar 2023 15:35:16 -0500 Subject: [PATCH 181/184] POM: update parent to pom-scijava 34.1.0 This avoids a CVE in snakeyaml impacting versions [0, 1.31). --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d1fda2c..65c4e89 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.scijava pom-scijava - 32.0.0-beta-4 + 34.1.0 ui-behaviour From af2572e9f1b9938f126f6ecfbe30ac2cae771516 Mon Sep 17 00:00:00 2001 From: Ulrik Guenther Date: Wed, 16 Aug 2023 21:40:47 +0200 Subject: [PATCH 182/184] Update code for snakeyaml 2.0 Adjust YamlConfigIO constructors for Representer() and Constructor() to reflect API changes in snakeyaml 2.0. Signed-off-by: Curtis Rueden --- pom.xml | 5 ++++- .../scijava/ui/behaviour/io/yaml/YamlConfigIO.java | 12 ++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 65c4e89..ec12e6f 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,8 @@ org.scijava pom-scijava - 34.1.0 + 36.0.0 + ui-behaviour @@ -102,6 +103,8 @@ and Genetics. sign,deploy-to-scijava + + 2.0 diff --git a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java index e38b09c..c3ee2ec 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java @@ -39,6 +39,7 @@ import org.scijava.ui.behaviour.io.InputTriggerDescription; import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.TypeDescription; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; @@ -86,14 +87,17 @@ public class YamlConfigIO */ private static final Yaml getYaml() { - final Representer representer = new Representer(); + final DumperOptions options = new DumperOptions(); + options.setExplicitStart( true ); + + final Representer representer = new Representer( options ); representer.addClassTag( InputTriggerDescription.class, tag ); - final Constructor constructor = new Constructor(); + final LoaderOptions loaderOptions = new LoaderOptions(); + + final Constructor constructor = new Constructor( loaderOptions ); constructor.addTypeDescription( new TypeDescription( InputTriggerDescription.class, tag ) ); - final DumperOptions options = new DumperOptions(); - options.setExplicitStart( true ); final Yaml yaml = new Yaml( constructor, representer, options ); return yaml; From 7cbd84778223aa5773c856e78c33b557cf5c4a99 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Wed, 16 Aug 2023 15:32:50 -0500 Subject: [PATCH 183/184] Happy New Year 2023 --- LICENSE.txt | 2 +- .../org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java | 2 +- src/main/java/org/scijava/ui/behaviour/Behaviour.java | 2 +- src/main/java/org/scijava/ui/behaviour/BehaviourMap.java | 2 +- src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java | 2 +- src/main/java/org/scijava/ui/behaviour/DragBehaviour.java | 2 +- .../java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java | 2 +- src/main/java/org/scijava/ui/behaviour/InputTrigger.java | 2 +- src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java | 2 +- src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java | 2 +- src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java | 2 +- src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java | 2 +- src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java | 2 +- src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java | 2 +- .../java/org/scijava/ui/behaviour/io/InputTriggerConfig.java | 2 +- .../org/scijava/ui/behaviour/io/InputTriggerDescription.java | 2 +- .../ui/behaviour/io/InputTriggerDescriptionsBuilder.java | 2 +- src/main/java/org/scijava/ui/behaviour/io/gui/Command.java | 2 +- .../scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java | 2 +- .../org/scijava/ui/behaviour/io/gui/CommandDescriptions.java | 2 +- .../scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java | 2 +- .../scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java | 2 +- src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java | 2 +- .../java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java | 2 +- .../java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java | 2 +- .../java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java | 2 +- .../java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java | 2 +- src/main/java/org/scijava/ui/behaviour/package-info.java | 2 +- .../java/org/scijava/ui/behaviour/util/AbstractNamedAction.java | 2 +- .../org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java | 2 +- src/main/java/org/scijava/ui/behaviour/util/Actions.java | 2 +- src/main/java/org/scijava/ui/behaviour/util/Behaviours.java | 2 +- .../java/org/scijava/ui/behaviour/util/InputActionBindings.java | 2 +- src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java | 2 +- .../org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java | 2 +- .../java/org/scijava/ui/behaviour/util/WrappedActionMap.java | 2 +- .../java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java | 2 +- .../java/org/scijava/ui/behaviour/util/WrappedInputMap.java | 2 +- .../org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java | 2 +- .../java/org/scijava/ui/behaviour/EventsInteractiveTest.java | 2 +- src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java | 2 +- src/test/java/org/scijava/ui/behaviour/UsageExample.java | 2 +- .../org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java | 2 +- .../org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java | 2 +- .../org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java | 2 +- 45 files changed, 45 insertions(+), 45 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 1687e07..84f23ce 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2015 - 2022, Max Planck Institute of Molecular Cell Biology +Copyright (c) 2015 - 2023, Max Planck Institute of Molecular Cell Biology and Genetics. All rights reserved. diff --git a/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java index cdf811a..527196f 100644 --- a/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/AbstractMouseAndKeyHandler.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/Behaviour.java b/src/main/java/org/scijava/ui/behaviour/Behaviour.java index 543c8b9..64fceb2 100644 --- a/src/main/java/org/scijava/ui/behaviour/Behaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/Behaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java index 021bb6a..73eb005 100644 --- a/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java +++ b/src/main/java/org/scijava/ui/behaviour/BehaviourMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java b/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java index 25616af..f9daab8 100644 --- a/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/ClickBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java b/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java index 052b43c..bffcab4 100644 --- a/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/DragBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java b/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java index 73289fe..2592779 100644 --- a/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java +++ b/src/main/java/org/scijava/ui/behaviour/GlobalKeyEventDispatcher.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java index 1e0c189..3413973 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTrigger.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTrigger.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java index 3760af6..433799a 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerAdder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java index 3db69ce..f124357 100644 --- a/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java +++ b/src/main/java/org/scijava/ui/behaviour/InputTriggerMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java index 723c9b1..0694064 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyPressedManager.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java index 05b3ad8..d56f187 100644 --- a/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java +++ b/src/main/java/org/scijava/ui/behaviour/KeyStrokeAdder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java index 17811c9..09c083a 100644 --- a/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java +++ b/src/main/java/org/scijava/ui/behaviour/MouseAndKeyHandler.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java b/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java index b93b0bb..a499e12 100644 --- a/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/ScrollBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java index 8d432af..ac2af75 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerConfig.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java index 4fe9197..7003775 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescription.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java index a1dbdd0..5f46d96 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/InputTriggerDescriptionsBuilder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java b/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java index bd5c8b8..f4a4a13 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/Command.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java index bfe1c89..7fd072c 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionProvider.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java index b19dada..b994597 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptions.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java index 27b94ef..e40dfe7 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/CommandDescriptionsBuilder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java index 5b0cf05..801842f 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/InputTriggerPanelEditor.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java b/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java index bf71a88..f613871 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/RoundBorder.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java index 91013e5..616698e 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/TagPanelEditor.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java index d77c7e3..7f56adb 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java +++ b/src/main/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanel.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java index 2b4b2dc..a8c3b7d 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/json/JsonConfigIO.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java index c3ee2ec..76fb0fb 100644 --- a/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java +++ b/src/main/java/org/scijava/ui/behaviour/io/yaml/YamlConfigIO.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/package-info.java b/src/main/java/org/scijava/ui/behaviour/package-info.java index b77038c..139284a 100644 --- a/src/main/java/org/scijava/ui/behaviour/package-info.java +++ b/src/main/java/org/scijava/ui/behaviour/package-info.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java index 68d011b..79e10a3 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedAction.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java index 7600699..2034217 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java +++ b/src/main/java/org/scijava/ui/behaviour/util/AbstractNamedBehaviour.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/Actions.java b/src/main/java/org/scijava/ui/behaviour/util/Actions.java index 5257a94..4cb4a68 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Actions.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Actions.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java index ace1003..0774627 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java +++ b/src/main/java/org/scijava/ui/behaviour/util/Behaviours.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java index 3e22ec2..3a133ec 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/InputActionBindings.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java index 5c9d40e..1c74d23 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java +++ b/src/main/java/org/scijava/ui/behaviour/util/RunnableAction.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java index 3f903eb..a9cce8e 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java +++ b/src/main/java/org/scijava/ui/behaviour/util/TriggerBehaviourBindings.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java index 55ebb48..9929f3a 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedActionMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java index 9319690..6e34af0 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedBehaviourMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java index 8a97777..ad530ec 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java index 82aac7a..e97fadb 100644 --- a/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java +++ b/src/main/java/org/scijava/ui/behaviour/util/WrappedInputTriggerMap.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java index 8200253..3f79aad 100644 --- a/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/EventsInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java b/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java index 22c4368..5134999 100644 --- a/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java +++ b/src/test/java/org/scijava/ui/behaviour/MultiWindowExample.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/UsageExample.java b/src/test/java/org/scijava/ui/behaviour/UsageExample.java index d871b4a..95e4830 100644 --- a/src/test/java/org/scijava/ui/behaviour/UsageExample.java +++ b/src/test/java/org/scijava/ui/behaviour/UsageExample.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java index 03bd24c..3c0e5ea 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java +++ b/src/test/java/org/scijava/ui/behaviour/io/gui/VisualEditorPanelDemo.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java index 92637f5..7953859 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/io/json/JsonInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without diff --git a/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java b/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java index 0ec2f97..4dcb4ac 100644 --- a/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java +++ b/src/test/java/org/scijava/ui/behaviour/io/yaml/YamlInteractiveTest.java @@ -2,7 +2,7 @@ * #%L * Configurable key and mouse event handling * %% - * Copyright (C) 2015 - 2022 Max Planck Institute of Molecular Cell Biology + * Copyright (C) 2015 - 2023 Max Planck Institute of Molecular Cell Biology * and Genetics. * %% * Redistribution and use in source and binary forms, with or without From be1d881829cc2a639a74a342f33b849240425647 Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Wed, 16 Aug 2023 15:33:20 -0500 Subject: [PATCH 184/184] Bump to next development cycle Signed-off-by: Curtis Rueden --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ec12e6f..5d9c325 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ ui-behaviour - 2.0.8-SNAPSHOT + 2.0.9-SNAPSHOT UI Behaviour Configurable key and mouse event handling