├── .gitignore ├── .travis.yml ├── .travis └── builder.sh ├── LICENSE ├── README.md ├── build-resources ├── eclipse.prefs.formatter.xml └── version.txt ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── package ├── bintray.deploy.json ├── license │ ├── COPYING.AFFERO │ ├── COPYING.GPLv3 │ ├── COPYING.LGPLv3 │ └── README └── template.deploy.json ├── src └── main │ ├── java │ └── net │ │ └── rptools │ │ └── lib │ │ ├── AppEvent.java │ │ ├── AppEventListener.java │ │ ├── AppUtil.java │ │ ├── ArrayUtil.java │ │ ├── BackupManager.java │ │ ├── CodeTimer.java │ │ ├── DebugStream.java │ │ ├── DebugUtil.java │ │ ├── EventDispatcher.java │ │ ├── FileUtil.java │ │ ├── GUID.java │ │ ├── GeometryUtil.java │ │ ├── InvalidGUIDException.java │ │ ├── LineSegmentId.java │ │ ├── MD5Key.java │ │ ├── ModelVersionManager.java │ │ ├── ModelVersionTransformation.java │ │ ├── TaskBarFlasher.java │ │ ├── i18n │ │ ├── ButtonLocaleChangeListener.java │ │ ├── I18NManager.java │ │ ├── LabelLocaleChangeListener.java │ │ ├── LocaleChangeListener.java │ │ └── WindowLocaleChangeListener.java │ │ ├── image │ │ ├── ImageUtil.java │ │ ├── LargeImage.java │ │ └── ThumbnailManager.java │ │ ├── io │ │ └── PackedFile.java │ │ ├── net │ │ ├── FTPLocation.java │ │ ├── LocalLocation.java │ │ ├── Location.java │ │ └── RPTURLStreamHandlerFactory.java │ │ ├── service │ │ └── EchoServer.java │ │ ├── sound │ │ ├── SoundManager.java │ │ └── SoundPlayer.java │ │ ├── swing │ │ ├── AboutDialog.java │ │ ├── AbstractPaintChooserPanel.java │ │ ├── ColorPicker.java │ │ ├── FramesPerSecond.java │ │ ├── GradientPanel.java │ │ ├── ImageBorder.java │ │ ├── ImageLabel.java │ │ ├── ImagePanel.java │ │ ├── ImagePanelModel.java │ │ ├── ImageToggleButton.java │ │ ├── JSplitPaneEx.java │ │ ├── OutlookPanel.java │ │ ├── PaintChooser.java │ │ ├── PaintedPanel.java │ │ ├── PenWidthChooser.java │ │ ├── PopupListener.java │ │ ├── PositionalLayout.java │ │ ├── PositionalPanel.java │ │ ├── RoundedTitledPanel.java │ │ ├── SelectionListener.java │ │ ├── SwingUtil.java │ │ ├── TaskPanel.java │ │ ├── TaskPanelGroup.java │ │ └── preference │ │ │ ├── SplitPanePreferences.java │ │ │ ├── TaskPanelGroupPreferences.java │ │ │ ├── TreePreferences.java │ │ │ └── WindowPreferences.java │ │ ├── tool │ │ └── DropTargetInfo.java │ │ └── transferable │ │ ├── FileListTransferable.java │ │ ├── FileTransferableHandler.java │ │ ├── GroupTokenTransferData.java │ │ ├── ImageTransferable.java │ │ ├── ImageTransferableHandler.java │ │ ├── MapToolTokenTransferData.java │ │ ├── TokenTransferData.java │ │ └── TransferableHandler.java │ └── resources │ └── net │ └── rptools │ └── lib │ ├── image │ ├── icons │ │ ├── contrast_high.png │ │ ├── cross.png │ │ ├── eraser.png │ │ ├── freehand.png │ │ ├── freehand2.png │ │ ├── paintbrush.png │ │ ├── paintcan.png │ │ ├── palette.png │ │ ├── pencil.png │ │ ├── pencil_add.png │ │ ├── pencil_delete.png │ │ ├── round_cap.png │ │ ├── round_cap2.png │ │ ├── shape_handles.png │ │ ├── shape_handles2.png │ │ ├── shape_no_handles.png │ │ ├── square_cap.png │ │ ├── square_cap2.png │ │ ├── transparent.png │ │ └── transparent2.png │ ├── jide_logo_small.png │ └── rptools-logo.png │ └── swing │ ├── forms │ └── colorPanel.xml │ └── image │ ├── border │ ├── blue │ │ ├── bl.png │ │ ├── bottom.png │ │ ├── br.png │ │ ├── left.png │ │ ├── right.png │ │ ├── tl.png │ │ ├── top.png │ │ └── tr.png │ ├── gray │ │ ├── bl.png │ │ ├── bottom.png │ │ ├── br.png │ │ ├── left.png │ │ ├── right.png │ │ ├── tl.png │ │ ├── top.png │ │ └── tr.png │ └── red │ │ ├── bl.png │ │ ├── bottom.png │ │ ├── br.png │ │ ├── left.png │ │ ├── right.png │ │ ├── tl.png │ │ ├── top.png │ │ └── tr.png │ ├── collapse.png │ ├── downArrow.png │ ├── empty.png │ └── expand.png └── version.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | 4 | # OS generated files 5 | ################################################################################ 6 | .DS_Store 7 | .DS_Store? 8 | ._* 9 | .Spotlight-V100 10 | .Trashes 11 | Icon? 12 | ehthumbs.db 13 | Thumbs.db 14 | 15 | 16 | # Others 17 | ################################################################################ 18 | *.log 19 | *~ 20 | target/ 21 | out/ 22 | 23 | 24 | # IDEs 25 | ################################################################################ 26 | *.iml 27 | .idea/ 28 | .*.sw[p0-9] 29 | .sw[p0-9] 30 | .project 31 | .settings/ 32 | .classpath 33 | .history 34 | 35 | # Local gradle files and properties 36 | ################################################################################ 37 | gradle.properties 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # The .travis/builder.sh script now takes into account whether this is a 2 | # tagged commit and whether it's part of the RPTools repository. If the 3 | # answer is yes to both, then "./gradlew bintrayUpload" is executed. 4 | # Otherwise, it's just a regular "./gradlew build". 5 | # 6 | # Eventually, we'll have Travis do this as a deploy target: 7 | # https://docs.travis-ci.com/user/deployment/bintray/ 8 | language: java 9 | script: ./gradlew build 10 | jdk: oraclejdk8 11 | 12 | # Shamelessly copied from Jamz's TokenTool configuration file. :) 13 | before_cache: 14 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 15 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ 16 | cache: 17 | directories: 18 | - "$HOME/.gradle/caches/" 19 | - "$HOME/.gradle/wrapper/" 20 | 21 | # This will cause a deploy back to GitHub for any tagged commit. Note 22 | # that tagging from the command line seems to require the "-a" option 23 | # when tagging in order to trigger Travis to deploy. Use the Travis 24 | # "Settings" for your repo to add the DEPLOYMENT_KEY variable; the value 25 | # should be GitHub's _personal OAuth token_. 26 | deploy: 27 | - provider: releases 28 | api_key: $DEPLOYMENT_KEY 29 | 30 | # Must prevent 'git stash --all' that Travis does -- we want the JARs 31 | # to still be in place! 32 | skip_cleanup: true 33 | 34 | file_glob: true 35 | file: build/libs/*.jar 36 | 37 | # The 'draft' tag prevents the release from being public unless/until 38 | # the release is edited at github.com and the state changed. 39 | draft: true 40 | on: 41 | tags: true 42 | 43 | # And this will deploy to bintray. This is only for libraries, of course. 44 | # The deployment descriptor, bintray.deploy.json, is created by Gradle 45 | # when it builds the JAR. Create Travis variables via the "Settings" 46 | # for the repo. The bintray key can be found by logging into bintray, 47 | # editing your profile, clicking "API KEY" in the bottom left, then 48 | # copy/pasting the key. 49 | - provider: bintray 50 | skip_cleanup: true 51 | file: package/bintray.deploy.json 52 | user: $BINTRAY_USER 53 | key: $BINTRAY_KEY 54 | # Add 'passphrase: ...' if a GPG-signed key is used (primarily 55 | # for when bintray artifacts are published to JCenter or Maven). 56 | on: 57 | repo: RPTools/rplib 58 | tags: true 59 | # (When dpl is fixed, the 'edge' key can be removed. See travis-ci#9314) 60 | edge: 61 | branch: v1.8.47 62 | -------------------------------------------------------------------------------- /.travis/builder.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Either runs a normal './gradlew build' or, if this CI run is because 4 | # of a tagged commit on the RPTools repository, runs 5 | # './gradlew bintrayUpload' instead. 6 | 7 | # For JDK9, should add: 8 | # _JAVA_OPTIONS="${JAVA_OPTIONS} --illegal-access=permit" 9 | # .. in order to get rid of the warning messages sent to the console. 10 | # 11 | # Not needed at the current time, though, since the RPTools 12 | # libraries can be built using JDK8. 13 | 14 | set -vex 15 | 16 | if [ "X$TRAVIS_TAG" = "X" ] || [ "X$TRAVIS_REPO_SLUG" != "RPTools/rplib" ]; then 17 | ./gradlew --no-daemon build 18 | else 19 | ./gradlew --no-daemon bintrayUpload \ 20 | "-Dtag=$TRAVIS_TAG" \ 21 | "-Dpublish=true" \ 22 | "-Duser=$BINTRAY_USER" "-Dkey=$BINTRAY_KEY" 23 | fi 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rplib 2 | Library of common functionality for the RPTools applications. 3 | -------------------------------------------------------------------------------- /build-resources/version.txt: -------------------------------------------------------------------------------- 1 | 1.4.1.9 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.5.1-bin.zip 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStorePath=wrapper/dists 5 | zipStoreBase=GRADLE_USER_HOME 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /package/bintray.deploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "package": { 3 | "name": "rplib", 4 | "repo": "RPTools", 5 | "subject": "rptools", 6 | "desc": "General library of role-playing functionality", 7 | "website_url": "http://www.rptools.net/", 8 | "issue_tracker_url": "https://github.com/RPTools/rplib/issues", 9 | "vcs_url": "https://github.com/RPTools/rplib.git", 10 | "github_use_tag_release_notes": true, 11 | "github_release_notes_file": "README.md", 12 | "licenses": ["LGPL-3.0"], 13 | "public_download_numbers": true, 14 | "public_stats": true 15 | }, 16 | 17 | "version": { 18 | "name": "1.4.1.9", 19 | "desc": "development version", 20 | "vcs_tag": "1.4.1.9", 21 | "gpgSign": false 22 | }, 23 | 24 | "files": 25 | [ { 26 | "includePattern": "build/libs/(.*\\.jar)", 27 | "uploadPattern": "$1", 28 | "matrixParams": { "override": true } 29 | } ], 30 | 31 | "publish": true 32 | } 33 | -------------------------------------------------------------------------------- /package/license/COPYING.LGPLv3: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /package/license/README: -------------------------------------------------------------------------------- 1 | This directory contains all licenses used by various RPTools packages. 2 | 3 | The libraries use LGPLv3, the applications use the Affero license, 4 | and there may be some older pieces of code that use GPLv3 but those 5 | will be transitioned to one of the first two over time. 6 | 7 | The plan was to include this directory in the Git repository of all 8 | RPTools packages so that the Gradle build file could refer to them 9 | as needed and, perhaps, in an automated manner. In other words, a 10 | single 'build.gradle' for all RPTools packages that automatically 11 | distinguishes between the repo being for a library or an application 12 | and "doing the Right Thing". 13 | 14 | Another alternative is to copy the appropriate license file to 15 | another filename, and use the package name as the filename. So the 16 | COPYING.AFFERO could be copied to LICENSE.maptool, for example. 17 | Then the build.gradle could refer to "LICENSE"+project.name without 18 | any need for conditional logic. 19 | 20 | Which of those techniques -- or any other future possibility -- 21 | will be decided over time, likely after trying one or more to see 22 | how they work out. :) 23 | -------------------------------------------------------------------------------- /package/template.deploy.json: -------------------------------------------------------------------------------- 1 | { 2 | "package": { 3 | "name": "@NAME@", 4 | "repo": "RPTools", 5 | "subject": "rptools", 6 | "desc": "@DESCRIPTION@", 7 | "website_url": "http://www.rptools.net/", 8 | "issue_tracker_url": "https://github.com/RPTools/@NAME@/issues", 9 | "vcs_url": "https://github.com/RPTools/@NAME@.git", 10 | "github_use_tag_release_notes": true, 11 | "github_release_notes_file": "README.md", 12 | "licenses": ["@LICENSE@"], 13 | "public_download_numbers": true, 14 | "public_stats": true 15 | }, 16 | 17 | "version": { 18 | "name": "@VERSION@", 19 | "desc": "development version", 20 | "vcs_tag": "@VERSION@", 21 | "gpgSign": false 22 | }, 23 | 24 | "files": 25 | [ { 26 | "includePattern": "build/libs/(.*\\.jar)", 27 | "uploadPattern": "$1", 28 | "matrixParams": { "override": true } 29 | } ], 30 | 31 | "publish": true 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/AppEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | public class AppEvent { 17 | 18 | private Enum id; 19 | private Object source; 20 | private Object oldValue; 21 | private Object newValue; 22 | 23 | public AppEvent(Enum id, Object source, Object oldValue, Object newValue) { 24 | this.id = id; 25 | this.source = source; 26 | this.oldValue = oldValue; 27 | this.newValue = newValue; 28 | } 29 | 30 | public Enum getId() { 31 | return id; 32 | } 33 | 34 | public Object getSource() { 35 | return source; 36 | } 37 | 38 | public Object getOldValue() { 39 | return oldValue; 40 | } 41 | 42 | public Object getNewValue() { 43 | return newValue; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/AppEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | public interface AppEventListener { 17 | 18 | public void handleAppEvent(AppEvent event); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/AppUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | import java.io.File; 17 | 18 | public class AppUtil { 19 | 20 | private static final String USER_HOME; 21 | 22 | private static String appName; 23 | 24 | static { 25 | 26 | USER_HOME = System.getProperty("user.home"); 27 | 28 | } 29 | 30 | public static void init(String appName) { 31 | AppUtil.appName = appName; 32 | } 33 | 34 | public static File getUserHome() { 35 | checkInit(); 36 | return USER_HOME != null ? new File(USER_HOME) : null; 37 | } 38 | 39 | public static File getAppHome() { 40 | checkInit(); 41 | if (USER_HOME == null) { 42 | return null; 43 | } 44 | 45 | File home = new File(USER_HOME + "/." + appName); 46 | home.mkdirs(); 47 | 48 | return home; 49 | } 50 | 51 | public static File getAppHome(String subdir) { 52 | checkInit(); 53 | if (USER_HOME == null) { 54 | return null; 55 | } 56 | 57 | File home = new File(getAppHome().getPath() + "/" + subdir); 58 | home.mkdirs(); 59 | 60 | return home; 61 | } 62 | 63 | private static void checkInit() { 64 | if (appName == null) { 65 | throw new IllegalStateException("Must call init() on AppUtil"); 66 | } 67 | } 68 | 69 | public static String getAppName() { 70 | return appName; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/ArrayUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | public class ArrayUtil { 17 | 18 | public static boolean arrayContains(Object[] array, Object object) { 19 | 20 | for (int i = 0; i < array.length; i++) { 21 | 22 | try { 23 | if (array[i] == object || array[i].equals(object)) { 24 | return true; 25 | } 26 | } catch (Exception e) { 27 | // Means not the same, keep looking 28 | } 29 | } 30 | 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/BackupManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | import java.io.File; 17 | import java.io.IOException; 18 | import java.util.Arrays; 19 | import java.util.Collections; 20 | import java.util.Comparator; 21 | import java.util.LinkedList; 22 | import java.util.List; 23 | 24 | public class BackupManager { 25 | 26 | private static final long DEFAULT_MAX_BACKUP_SIZE = 128 * 1024 * 1024; // megs 27 | 28 | private File backupDir; 29 | private long maxBackupSize; 30 | 31 | public BackupManager(File backupDir) throws IOException { 32 | this(backupDir, DEFAULT_MAX_BACKUP_SIZE); 33 | } 34 | 35 | public BackupManager(File backupDir, long maxBackupSize) throws IOException { 36 | this.backupDir = backupDir; 37 | this.maxBackupSize = maxBackupSize; 38 | 39 | backupDir.mkdirs(); 40 | } 41 | 42 | /** 43 | * The maximum number of bytes that the backup directory should use for backups 44 | */ 45 | public void setMaxBackupSize(long size) { 46 | maxBackupSize = size; 47 | } 48 | 49 | public void backup(File file) throws IOException { 50 | 51 | // Active ? 52 | if (maxBackupSize < 1) { 53 | return; 54 | } 55 | 56 | // Enough room ? 57 | List fileList = getFiles(); 58 | long availableSpace = maxBackupSize - getUsedSpace(); 59 | while (fileList.size() > 0 && file.length() > availableSpace) { 60 | File oldFile = fileList.remove(0); 61 | availableSpace += oldFile.length(); 62 | oldFile.delete(); 63 | } 64 | 65 | // Filename 66 | File newFile = new File(backupDir.getAbsolutePath() + "/" + file.getName()); 67 | for (int count = 1; newFile.exists(); count++) { 68 | newFile = new File(backupDir.getAbsolutePath() + "/" + count + "_" + file.getName()); 69 | } 70 | 71 | // Save 72 | FileUtil.copyFile(file, newFile); 73 | } 74 | 75 | /** 76 | * List of existing backup files, with the oldest at the front 77 | */ 78 | private List getFiles() { 79 | 80 | List fileList = new LinkedList(Arrays.asList(backupDir.listFiles())); 81 | Collections.sort(fileList, new Comparator() { 82 | public int compare(File o1, File o2) { 83 | 84 | return o1.lastModified() < o2.lastModified() ? -1 : 1; 85 | } 86 | }); 87 | 88 | return fileList; 89 | } 90 | 91 | private long getUsedSpace() { 92 | long count = 0; 93 | for (File file : backupDir.listFiles()) { 94 | count += file.length(); 95 | } 96 | return count; 97 | } 98 | 99 | // public static void main(String[] args) throws IOException { 100 | // 101 | // BackupManager mgr = new BackupManager(new File("/home/trevor/tmp/backup")); 102 | // mgr.setMaxBackupSize(35000); 103 | // 104 | // mgr.backup(new File("/home/trevor/tmp/applet.html")); 105 | // 106 | // System.out.println("Done"); 107 | // } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/CodeTimer.java: -------------------------------------------------------------------------------- 1 | package net.rptools.lib; 2 | 3 | import java.text.DecimalFormat; 4 | import java.util.ArrayList; 5 | import java.util.Collections; 6 | import java.util.Comparator; 7 | import java.util.HashMap; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | public class CodeTimer { 12 | private final Map timeMap = new HashMap(); 13 | private final Map orderMap = new HashMap(); 14 | private final String name; 15 | private final long created = System.currentTimeMillis(); 16 | private boolean enabled; 17 | private int threshold = 1; 18 | 19 | private final DecimalFormat df = new DecimalFormat(); 20 | 21 | public CodeTimer() { 22 | this(""); 23 | } 24 | 25 | public CodeTimer(String n) { 26 | name = n; 27 | enabled = true; 28 | df.setMinimumIntegerDigits(5); 29 | } 30 | 31 | public boolean isEnabled() { 32 | return enabled; 33 | } 34 | 35 | public void setThreshold(int threshold) { 36 | this.threshold = threshold; 37 | } 38 | 39 | public void setEnabled(boolean enabled) { 40 | this.enabled = enabled; 41 | } 42 | 43 | public void start(String id) { 44 | if (!enabled) { 45 | return; 46 | } 47 | int count = orderMap.size(); 48 | orderMap.put(id, count); 49 | Timer timer = timeMap.get(id); 50 | if (timer == null) { 51 | timer = new Timer(); 52 | timeMap.put(id, timer); 53 | } 54 | timer.start(); 55 | } 56 | 57 | public void stop(String id) { 58 | if (!enabled) { 59 | return; 60 | } 61 | if (!orderMap.containsKey(id)) { 62 | throw new IllegalArgumentException("Could not find orderMap id: " + id); 63 | } 64 | if (!timeMap.containsKey(id)) { 65 | throw new IllegalArgumentException("Could not find timer id: " + id); 66 | } 67 | timeMap.get(id).stop(); 68 | } 69 | 70 | public long getElapsed(String id) { 71 | if (!enabled) { 72 | return 0; 73 | } 74 | if (!orderMap.containsKey(id)) { 75 | throw new IllegalArgumentException("Could not find orderMap id: " + id); 76 | } 77 | if (!timeMap.containsKey(id)) { 78 | throw new IllegalArgumentException("Could not find timer id: " + id); 79 | } 80 | return timeMap.get(id).getElapsed(); 81 | } 82 | 83 | public void reset(String id) { 84 | if (!orderMap.containsKey(id)) { 85 | throw new IllegalArgumentException("Could not find orderMap id: " + id); 86 | } 87 | timeMap.remove(id); 88 | } 89 | 90 | public void clear() { 91 | orderMap.clear(); 92 | timeMap.clear(); 93 | } 94 | 95 | @Override 96 | public String toString() { 97 | StringBuffer builder = new StringBuffer(100); 98 | 99 | builder.append("Timer ").append(name).append(" (").append(orderMap.size()).append(" elements)\n"); 100 | 101 | List idSet = new ArrayList(timeMap.keySet()); 102 | Collections.sort(idSet, new Comparator() { 103 | public int compare(String arg0, String arg1) { 104 | return orderMap.get(arg0) - orderMap.get(arg1); 105 | } 106 | }); 107 | for (String id : idSet) { 108 | long elapsed = timeMap.get(id).getElapsed(); 109 | if (elapsed < threshold) { 110 | continue; 111 | } 112 | builder.append(String.format(" %3d. %6d ms %s\n", orderMap.get(id), elapsed, id)); 113 | // builder.append("\t").append(orderMap.get(id)).append(". ").append(id).append(": ").append(timer.getElapsed()).append(" ms\n"); 114 | } 115 | return builder.toString(); 116 | } 117 | 118 | private static class Timer { 119 | long elapsed; 120 | long start = -1; 121 | 122 | public void start() { 123 | start = System.currentTimeMillis(); 124 | } 125 | 126 | public void stop() { 127 | elapsed += (System.currentTimeMillis() - start); 128 | start = -1; 129 | } 130 | 131 | public long getElapsed() { 132 | long time = elapsed; 133 | if (start > 0) { 134 | time += (System.currentTimeMillis() - start); 135 | } 136 | return time; 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/DebugStream.java: -------------------------------------------------------------------------------- 1 | package net.rptools.lib; 2 | 3 | import java.io.PrintStream; 4 | import java.text.MessageFormat; 5 | 6 | public class DebugStream extends PrintStream { 7 | private static final DebugStream INSTANCE = new DebugStream(); 8 | private static boolean debugOn = true; 9 | 10 | public static void activate() { 11 | System.setOut(INSTANCE); 12 | debugOn = true; 13 | } 14 | 15 | public static void deactivate() { 16 | System.setOut(INSTANCE); 17 | debugOn = false; 18 | } 19 | 20 | private DebugStream() { 21 | super(System.out); 22 | } 23 | 24 | @Override 25 | public void println(Object x) { 26 | if (debugOn) { 27 | showLocation(); 28 | } 29 | 30 | super.println(x); 31 | } 32 | 33 | @Override 34 | public void println(String x) { 35 | if (debugOn) { 36 | showLocation(); 37 | } 38 | 39 | super.println(x); 40 | } 41 | 42 | private void showLocation() { 43 | StackTraceElement element = Thread.currentThread().getStackTrace()[3]; 44 | super.print(MessageFormat.format("({0}:{1, number,#}) : ", element.getFileName(), element.getLineNumber())); 45 | } 46 | } -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/DebugUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | public class DebugUtil { 17 | 18 | /** 19 | * Get the bits in the number represented as a string 20 | * 21 | * @param num 22 | * @return the bits in the number represented as a string 23 | */ 24 | public static String getBits(long num) { 25 | String str = ""; 26 | for (int i = 0; i < 64; i++) { 27 | str = (num & 1) + str; 28 | num >>= 1; 29 | 30 | if (i % 4 == 3) { 31 | str = " " + str; 32 | } 33 | } 34 | return str; 35 | } 36 | 37 | /** 38 | * Get the bits in the number represented as a string 39 | * 40 | * @param num 41 | * @return the bits in the number represented as a string 42 | */ 43 | public static String getBits(int num) { 44 | String str = ""; 45 | for (int i = 0; i < 32; i++) { 46 | str = (num & 1) + str; 47 | num >>= 1; 48 | 49 | if (i % 4 == 3) { 50 | str = " " + str; 51 | } 52 | } 53 | return str; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/EventDispatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | import java.util.ArrayList; 17 | import java.util.HashMap; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | /** 22 | * Application level event dispatch. 23 | * @author trevor 24 | */ 25 | public class EventDispatcher { 26 | 27 | private Map, List> listenerMap = new HashMap, List>(); 28 | 29 | public synchronized void registerEvents(Enum[] ids) { 30 | for (Enum e : ids) { 31 | registerEvent(e); 32 | } 33 | } 34 | 35 | public synchronized void registerEvent(Enum id) { 36 | if (listenerMap.containsKey(id)) { 37 | throw new IllegalArgumentException("Event '" + id + "' is already registered."); 38 | } 39 | 40 | listenerMap.put(id, new ArrayList()); 41 | } 42 | 43 | public synchronized void addListener(Enum id, AppEventListener listener) { 44 | addListener(listener, id); 45 | } 46 | 47 | public synchronized void addListener(AppEventListener listener, Enum... ids) { 48 | for (Enum id : ids) { 49 | if (!listenerMap.containsKey(id)) { 50 | throw new IllegalArgumentException("Event '" + id + "' is not registered."); 51 | } 52 | 53 | List list = listenerMap.get(id); 54 | if (!list.contains(listener)) { 55 | list.add(listener); 56 | } 57 | } 58 | } 59 | 60 | public synchronized void fireEvent(Enum id) { 61 | fireEvent(id, null, null, null); 62 | } 63 | 64 | public synchronized void fireEvent(Enum id, Object source) { 65 | fireEvent(id, source, null, null); 66 | } 67 | 68 | public synchronized void fireEvent(Enum id, Object source, Object newValue) { 69 | fireEvent(id, source, null, newValue); 70 | } 71 | 72 | public synchronized void fireEvent(Enum id, Object source, Object oldValue, Object newValue) { 73 | if (!listenerMap.containsKey(id)) { 74 | throw new IllegalArgumentException("Event '" + id + "' is not registered."); 75 | } 76 | 77 | List list = listenerMap.get(id); 78 | for (AppEventListener listener : list) { 79 | listener.handleAppEvent(new AppEvent(id, source, oldValue, newValue)); 80 | } 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/GUID.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | import java.io.Serializable; 17 | import java.net.InetAddress; 18 | import java.net.UnknownHostException; 19 | 20 | import com.withay.util.HexCode; 21 | 22 | /** 23 | * Global unique identificator object. 24 | */ 25 | public class GUID extends Object implements Serializable { 26 | 27 | /** Serial version unique identifier. */ 28 | private static final long serialVersionUID = 6361057925697403643L; 29 | 30 | /** GUIDs always have 16 bytes. */ 31 | public static final int GUID_LENGTH = 16; 32 | 33 | // NOTE: THIS CAN NEVER BE CHANGED, OR IT WILL AFFECT ALL THINGS THAT PREVIOUSLY USED IT 34 | public static final int GUID_BUCKETS = 100; 35 | // NOTE: THIS CAN NEVER BE CHANGED, OR IT WILL AFFECT ALL THINGS THAT PREVIOUSLY USED IT 36 | 37 | private byte[] baGUID; 38 | 39 | // Cache of the hashCode for a GUID 40 | private transient int hash; 41 | 42 | public GUID() { 43 | this.baGUID = generateGUID(); 44 | validateGUID(); 45 | } 46 | 47 | /** Creates a new GUID based on the specified GUID value. */ 48 | public GUID(byte[] baGUID) throws InvalidGUIDException { 49 | this.baGUID = baGUID; 50 | validateGUID(); 51 | } 52 | 53 | /** Creates a new GUID based on the specified hexadecimal-code string. */ 54 | public GUID(String strGUID) { 55 | if (strGUID == null) 56 | throw new InvalidGUIDException("GUID is null"); 57 | 58 | this.baGUID = HexCode.decode(strGUID); 59 | validateGUID(); 60 | } 61 | 62 | /** Ensures the GUID is legal. */ 63 | private void validateGUID() throws InvalidGUIDException { 64 | if (baGUID == null) 65 | throw new InvalidGUIDException("GUID is null"); 66 | if (baGUID.length != GUID_LENGTH) 67 | throw new InvalidGUIDException("GUID length is invalid"); 68 | } 69 | 70 | /** Returns the GUID representation of the {@link byte} array argument. */ 71 | public static GUID valueOf(byte[] bits) { 72 | if (bits == null) 73 | return null; 74 | return new GUID(bits); 75 | } 76 | 77 | /** Returns the GUID representation of the {@link String} argument. */ 78 | public static GUID valueOf(String s) { 79 | if (s == null) 80 | return null; 81 | return new GUID(s); 82 | } 83 | 84 | /** Determines whether two GUIDs are equal. */ 85 | public boolean equals(Object object) { 86 | if (object == null) { 87 | return this == null; 88 | } 89 | 90 | Class objClass = object.getClass(); 91 | 92 | GUID guid; 93 | try { 94 | if (objClass == String.class) { // string 95 | guid = new GUID((String) object); 96 | } else { // try to cast to a GUID 97 | guid = (GUID) object; 98 | } 99 | } catch (ClassCastException e) { // not a GUID 100 | return false; 101 | } 102 | 103 | // Compare bytes. 104 | for (int i = 0; i < GUID_LENGTH; i++) { 105 | if (this.baGUID[i] != guid.baGUID[i]) 106 | return false; 107 | } 108 | 109 | // All tests pass. 110 | return true; 111 | } 112 | 113 | public byte[] getBytes() { 114 | return baGUID; 115 | } 116 | 117 | /** Returns a string for the GUID. */ 118 | public String toString() { 119 | return HexCode.encode(baGUID, false); // false means uppercase 120 | } 121 | 122 | /** 123 | * Returns a hashcode for this GUID. This function is based on the algorithm that JDK 1.3 uses for a String. 124 | * @return a hash code value for this object. 125 | */ 126 | public int hashCode() { 127 | int h = hash; 128 | if (h == 0) { 129 | byte val[] = baGUID; 130 | int len = GUID_LENGTH; 131 | 132 | for (int i = 0; i < len; i++) 133 | h = 31 * h + val[i]; 134 | hash = h; 135 | } 136 | return h; 137 | } 138 | 139 | private static long guidGenerationCounter = 0; 140 | 141 | public static byte[] generateGUID() throws InvalidGUIDException { 142 | byte[] guid = new byte[16]; 143 | byte[] ip; 144 | 145 | try { 146 | InetAddress id = InetAddress.getLocalHost(); 147 | ip = id.getAddress(); // 192.168.0.14 148 | } catch (UnknownHostException e) { 149 | // Default to something known 150 | ip = new byte[] { 127, 0, 0, 1 }; 151 | } 152 | 153 | System.currentTimeMillis(); 154 | 155 | long time = System.currentTimeMillis(); 156 | 157 | guidGenerationCounter++; 158 | 159 | int n = 0; 160 | guid[n++] = ip[0]; 161 | guid[n++] = ip[1]; 162 | guid[n++] = ip[2]; 163 | guid[n++] = ip[3]; 164 | guid[n++] = (byte) (time & 0xFF); 165 | guid[n++] = (byte) (time >> 8 & 0xFF); 166 | guid[n++] = (byte) (time >> 16 & 0xFF); 167 | guid[n++] = (byte) (time >> 24 & 0xFF); 168 | guid[n++] = (byte) (guidGenerationCounter & 0xFF); 169 | guid[n++] = (byte) (guidGenerationCounter >> 8 & 0xFF); 170 | guid[n++] = (byte) (guidGenerationCounter >> 16 & 0xFF); 171 | guid[n++] = (byte) (guidGenerationCounter >> 24 & 0xFF); 172 | guid[n++] = (byte) ((time >> 24 & 0xFF) & ip[0]); 173 | guid[n++] = (byte) ((time >> 16 & 0xFF) & ip[1]); 174 | guid[n++] = (byte) ((time >> 8 & 0xFF) & ip[2]); 175 | guid[n++] = (byte) ((time >> 0 & 0xFF) & ip[3]); 176 | 177 | return guid; 178 | } 179 | 180 | public static void main(String[] args) throws Exception { 181 | for (int i = 0; i < 10; i++) { 182 | GUID guid = new GUID(); 183 | //System.out.println("insert into sys_guids values ('" + guid.toString() + "');"); 184 | System.out.println(guid.toString()); 185 | } 186 | } 187 | } -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/GeometryUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | import java.awt.geom.Area; 17 | import java.awt.geom.GeneralPath; 18 | import java.awt.geom.Line2D; 19 | import java.awt.geom.PathIterator; 20 | import java.awt.geom.Point2D; 21 | import java.util.HashSet; 22 | import java.util.List; 23 | import java.util.Set; 24 | 25 | public class GeometryUtil { 26 | public static Line2D findClosestLine(Point2D origin, PointNode pointList) { 27 | Line2D line = null; 28 | double distance = 0; 29 | 30 | PointNode node = pointList; 31 | do { 32 | Line2D newLine = new Line2D.Double(node.previous.point, node.point); 33 | double newDistance = getDistanceToCenter(origin, newLine); 34 | if (line == null || newDistance < distance) { 35 | line = newLine; 36 | distance = newDistance; 37 | } 38 | node = node.next; 39 | } while (node != pointList); 40 | 41 | return line; 42 | } 43 | 44 | public static double getDistanceToCenter(Point2D p, Line2D line) { 45 | Point2D midPoint = new Point2D.Double((line.getP1().getX() + line.getP2().getX()) / 2, (line.getP1().getY() + line.getP2().getY()) / 2); 46 | 47 | return Math.hypot(midPoint.getX() - p.getX(), midPoint.getY() - p.getY()); 48 | } 49 | 50 | public static Point2D getCloserPoint(Point2D origin, Line2D line) { 51 | double dist1 = Math.hypot(origin.getX() - line.getP1().getX(), origin.getY() - line.getP1().getY()); 52 | double dist2 = Math.hypot(origin.getX() - line.getP2().getX(), origin.getY() - line.getP2().getY()); 53 | 54 | return dist1 < dist2 ? line.getP1() : line.getP2(); 55 | } 56 | 57 | public static double getAngle(Point2D origin, Point2D target) { 58 | double angle = Math.toDegrees(Math.atan2((origin.getY() - target.getY()), (target.getX() - origin.getX()))); 59 | if (angle < 0) { 60 | angle += 360; 61 | } 62 | return angle; 63 | } 64 | 65 | public static double getAngleDelta(double sourceAngle, double targetAngle) { 66 | // Normalize 67 | targetAngle -= sourceAngle; 68 | 69 | if (targetAngle > 180) { 70 | targetAngle -= 360; 71 | } 72 | if (targetAngle < -180) { 73 | targetAngle += 360; 74 | } 75 | return targetAngle; 76 | } 77 | 78 | public static class PointNode { 79 | public PointNode previous; 80 | public PointNode next; 81 | public Point2D point; 82 | 83 | public PointNode(Point2D point) { 84 | this.point = point; 85 | } 86 | } 87 | 88 | public static double getDistanceXXX(Point2D p1, Point2D p2) { 89 | double a = p2.getX() - p1.getX(); 90 | double b = p2.getY() - p1.getY(); 91 | return Math.sqrt(a * a + b * b); // Was just "a+b" -- was that on purpose? A shortcut speed-up perhaps? 92 | } 93 | 94 | public static Set getFrontFaces(PointNode nodeList, Point2D origin) { 95 | Set frontFaces = new HashSet(); 96 | 97 | Line2D closestLine = GeometryUtil.findClosestLine(origin, nodeList); 98 | Point2D closestPoint = GeometryUtil.getCloserPoint(origin, closestLine); 99 | PointNode closestNode = nodeList; 100 | do { 101 | if (closestNode.point.equals(closestPoint)) { 102 | break; 103 | } 104 | closestNode = closestNode.next; 105 | } while (closestNode != nodeList); 106 | 107 | Point2D secondPoint = closestLine.getP1().equals(closestPoint) ? closestLine.getP2() : closestLine.getP1(); 108 | Point2D thirdPoint = secondPoint.equals(closestNode.next.point) ? closestNode.previous.point : closestNode.next.point; 109 | 110 | // Determine whether the first line segment is visible 111 | Line2D l1 = new Line2D.Double(origin, secondPoint); 112 | Line2D l2 = new Line2D.Double(closestNode.point, thirdPoint); 113 | boolean frontFace = !(l1.intersectsLine(l2)); 114 | if (frontFace) { 115 | frontFaces.add(new Line2D.Double(closestPoint, secondPoint)); 116 | } 117 | Point2D startPoint = closestNode.previous.point.equals(secondPoint) ? secondPoint : closestNode.point; 118 | Point2D endPoint = closestNode.point.equals(startPoint) ? secondPoint : closestNode.point; 119 | double originAngle = GeometryUtil.getAngle(origin, startPoint); 120 | double pointAngle = GeometryUtil.getAngle(startPoint, endPoint); 121 | int lastDirection = GeometryUtil.getAngleDelta(originAngle, pointAngle) > 0 ? 1 : -1; 122 | 123 | // System.out.format("%s: %.2f %s, %.2f %s => %.2f : %d : %s\n", frontFace, originAngle, startPoint.toString(), pointAngle, endPoint.toString(), getAngleDelta(originAngle, pointAngle), lastDirection, (closestNode.previous.point.equals(secondPoint) ? "second" : "closest").toString()); 124 | PointNode node = secondPoint.equals(closestNode.next.point) ? closestNode.next : closestNode; 125 | do { 126 | Point2D point = node.point; 127 | Point2D nextPoint = node.next.point; 128 | 129 | originAngle = GeometryUtil.getAngle(origin, point); 130 | pointAngle = GeometryUtil.getAngle(origin, nextPoint); 131 | 132 | // System.out.println(point + ":" + originAngle + ", " + nextPoint + ":"+ pointAngle + ", " + getAngleDelta(originAngle, pointAngle)); 133 | if (GeometryUtil.getAngleDelta(originAngle, pointAngle) > 0) { 134 | if (lastDirection < 0) { 135 | frontFace = !frontFace; 136 | lastDirection = 1; 137 | } 138 | } else { 139 | if (lastDirection > 0) { 140 | frontFace = !frontFace; 141 | lastDirection = -1; 142 | } 143 | } 144 | if (frontFace) { 145 | frontFaces.add(new Line2D.Double(nextPoint, point)); 146 | } 147 | node = node.next; 148 | } while (!node.point.equals(closestPoint)); 149 | 150 | return frontFaces; 151 | } 152 | 153 | public static int countAreaPoints(Area area) { 154 | int count = 0; 155 | for (PathIterator iter = area.getPathIterator(null); !iter.isDone(); iter.next()) { 156 | count++; 157 | } 158 | return count; 159 | } 160 | 161 | public static Area createLine(List points, int width) { 162 | Point2D lastPoint = null; 163 | Line2D lastLine = null; 164 | for (Point2D point : points) { 165 | if (lastPoint == null) { 166 | lastPoint = point; 167 | continue; 168 | } 169 | if (lastLine == null) { 170 | // First line segment 171 | lastLine = new Line2D.Double(lastPoint, point); 172 | 173 | // Keep track 174 | continue; 175 | } 176 | } 177 | GeneralPath path = new GeneralPath(); 178 | return new Area(path); 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/InvalidGUIDException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | public class InvalidGUIDException extends RuntimeException { 17 | private static final long serialVersionUID = 3257568421032768820L; 18 | 19 | public InvalidGUIDException() { 20 | super(); 21 | } 22 | 23 | public InvalidGUIDException(String s) { 24 | super(s); 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/LineSegmentId.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | import java.awt.geom.Point2D; 17 | 18 | public class LineSegmentId { 19 | 20 | private int x1; 21 | private int y1; 22 | private int x2; 23 | private int y2; 24 | 25 | public LineSegmentId(Point2D p1, Point2D p2) { 26 | 27 | x1 = (int) Math.min(p1.getX(), p2.getX()); 28 | x2 = (int) Math.max(p1.getX(), p2.getX()); 29 | 30 | y1 = (int) Math.min(p1.getY(), p2.getY()); 31 | y2 = (int) Math.max(p1.getY(), p2.getY()); 32 | } 33 | 34 | @Override 35 | public boolean equals(Object obj) { 36 | if (!(obj instanceof LineSegmentId)) { 37 | return false; 38 | } 39 | 40 | LineSegmentId line = (LineSegmentId) obj; 41 | 42 | return x1 == line.x1 && y1 == line.y1 && x2 == line.x2 && y2 == line.y2; 43 | } 44 | 45 | @Override 46 | public int hashCode() { 47 | // Doesn't have to be unique, only a decent spread 48 | return x1 + y1 + (x2 + y2) * 31; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/MD5Key.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | import java.io.IOException; 17 | import java.io.InputStream; 18 | import java.io.Serializable; 19 | import java.security.MessageDigest; 20 | import java.security.NoSuchAlgorithmException; 21 | 22 | /** 23 | * Represents the MD5 key for a certain set of data. 24 | * Can be used in maps as keys. 25 | */ 26 | @SuppressWarnings("serial") 27 | public class MD5Key implements Serializable { 28 | 29 | private static MessageDigest md5Digest; 30 | 31 | String id; 32 | 33 | static { 34 | try { 35 | md5Digest = MessageDigest.getInstance("md5"); 36 | } catch (NoSuchAlgorithmException e) { 37 | // TODO: handle this more gracefully 38 | e.printStackTrace(); 39 | } 40 | } 41 | 42 | public MD5Key() { 43 | } 44 | 45 | public MD5Key(String id) { 46 | this.id = id; 47 | } 48 | 49 | public MD5Key(byte[] data) { 50 | id = encodeToHex(digestData(data)); 51 | } 52 | 53 | public MD5Key(InputStream data) { 54 | 55 | id = encodeToHex(digestData(data)); 56 | } 57 | 58 | public String toString() { 59 | return id; 60 | } 61 | 62 | public boolean equals(Object obj) { 63 | if (!(obj instanceof MD5Key)) { 64 | return false; 65 | } 66 | 67 | return id.equals(((MD5Key) obj).id); 68 | } 69 | 70 | public int hashCode() { 71 | return id.hashCode(); 72 | } 73 | 74 | private static synchronized byte[] digestData(byte[] data) { 75 | 76 | md5Digest.reset(); 77 | 78 | md5Digest.update(data); 79 | 80 | return md5Digest.digest(); 81 | } 82 | 83 | private static synchronized byte[] digestData(InputStream data) { 84 | 85 | md5Digest.reset(); 86 | 87 | int b; 88 | try { 89 | while (((b = data.read()) >= 0)) { 90 | md5Digest.update((byte) b); 91 | } 92 | } catch (IOException ioe) { 93 | ioe.printStackTrace(); 94 | } 95 | 96 | return md5Digest.digest(); 97 | } 98 | 99 | private static String encodeToHex(byte[] data) { 100 | 101 | StringBuilder strbuild = new StringBuilder(); 102 | for (int i = 0; i < data.length; i++) { 103 | 104 | String hex = Integer.toHexString(data[i]); 105 | if (hex.length() < 2) { 106 | strbuild.append("0"); 107 | } 108 | if (hex.length() > 2) { 109 | hex = hex.substring(hex.length() - 2); 110 | } 111 | strbuild.append(hex); 112 | } 113 | 114 | return strbuild.toString(); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/ModelVersionTransformation.java: -------------------------------------------------------------------------------- 1 | package net.rptools.lib; 2 | 3 | public interface ModelVersionTransformation { 4 | 5 | public String transform(String xml); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/TaskBarFlasher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib; 15 | 16 | import java.awt.Color; 17 | import java.awt.Frame; 18 | import java.awt.Graphics; 19 | import java.awt.Image; 20 | import java.awt.image.BufferedImage; 21 | 22 | public class TaskBarFlasher { 23 | 24 | private static final int FLASH_DELAY = 500; 25 | 26 | private final BufferedImage flashImage; 27 | private final Image originalImage; 28 | private final Frame frame; 29 | 30 | private FlashThread flashThread; 31 | 32 | public TaskBarFlasher(Frame frame) { 33 | this.frame = frame; 34 | 35 | originalImage = frame.getIconImage(); 36 | flashImage = new BufferedImage(originalImage.getWidth(null), originalImage.getHeight(null), BufferedImage.OPAQUE); 37 | Graphics g = flashImage.getGraphics(); 38 | g.setColor(Color.blue); 39 | g.fillRect(0, 0, flashImage.getWidth(), flashImage.getHeight()); 40 | g.drawImage(originalImage, 0, 0, null); 41 | g.dispose(); 42 | } 43 | 44 | public synchronized void flash() { 45 | if (flashThread != null) { 46 | // Already flashing 47 | return; 48 | } 49 | 50 | flashThread = new FlashThread(); 51 | flashThread.start(); 52 | } 53 | 54 | private class FlashThread extends Thread { 55 | @Override 56 | public void run() { 57 | while (!frame.isFocused()) { 58 | try { 59 | Thread.sleep(FLASH_DELAY); 60 | frame.setIconImage(flashImage); 61 | Thread.sleep(FLASH_DELAY); 62 | frame.setIconImage(originalImage); 63 | } catch (InterruptedException ie) { 64 | // Just leave, whatever 65 | break; 66 | } 67 | } 68 | flashThread = null; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/i18n/ButtonLocaleChangeListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.i18n; 15 | 16 | import java.util.Locale; 17 | 18 | import javax.swing.AbstractButton; 19 | 20 | public class ButtonLocaleChangeListener implements LocaleChangeListener { 21 | 22 | private AbstractButton button; 23 | private String key; 24 | 25 | public ButtonLocaleChangeListener(AbstractButton button, String key) { 26 | this.button = button; 27 | this.key = key; 28 | } 29 | 30 | //// 31 | // LOCALE CHANGE LISTENER 32 | public void localeChanged(Locale locale) { 33 | button.setText(I18NManager.getText(key)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/i18n/I18NManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.i18n; 15 | 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | import java.util.Locale; 19 | import java.util.ResourceBundle; 20 | import java.util.concurrent.CopyOnWriteArrayList; 21 | 22 | public class I18NManager { 23 | 24 | private static List bundleNameList = new CopyOnWriteArrayList(); 25 | private static List bundleList = new ArrayList(); 26 | private static Locale locale = Locale.US; 27 | private static List localeListenerList = new CopyOnWriteArrayList(); 28 | 29 | public static void addBundle(String bundleName) { 30 | bundleNameList.add(bundleName); 31 | updateBundles(); 32 | } 33 | 34 | public static void removeBundle(String bundleName) { 35 | bundleNameList.remove(bundleName); 36 | updateBundles(); 37 | } 38 | 39 | public static void setLocale(Locale locale) { 40 | I18NManager.locale = locale; 41 | updateBundles(); 42 | fireLocaleChanged(); 43 | } 44 | 45 | public static String getText(String key) { 46 | 47 | for (ResourceBundle bundle : bundleList) { 48 | 49 | String value = bundle.getString(key); 50 | if (value != null) { 51 | return value; 52 | } 53 | } 54 | 55 | return key; 56 | } 57 | 58 | private synchronized static void fireLocaleChanged() { 59 | 60 | for (LocaleChangeListener listener : localeListenerList) { 61 | listener.localeChanged(locale); 62 | } 63 | } 64 | 65 | private synchronized static void updateBundles() { 66 | 67 | bundleList.clear(); 68 | 69 | for (String bundleName : bundleNameList) { 70 | 71 | bundleList.add(ResourceBundle.getBundle(bundleName, locale)); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/i18n/LabelLocaleChangeListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.i18n; 15 | 16 | import java.awt.Label; 17 | import java.util.Locale; 18 | 19 | public class LabelLocaleChangeListener implements LocaleChangeListener { 20 | 21 | private Label label; 22 | private String key; 23 | 24 | public LabelLocaleChangeListener(Label label, String key) { 25 | this.label = label; 26 | this.key = key; 27 | } 28 | 29 | //// 30 | // LOCALE CHANGE LISTENER 31 | public void localeChanged(Locale locale) { 32 | label.setText(I18NManager.getText(key)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/i18n/LocaleChangeListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.i18n; 15 | 16 | import java.util.Locale; 17 | 18 | public interface LocaleChangeListener { 19 | 20 | public void localeChanged(Locale locale); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/i18n/WindowLocaleChangeListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.i18n; 15 | 16 | import java.awt.Dialog; 17 | import java.awt.Frame; 18 | import java.awt.Window; 19 | import java.util.Locale; 20 | 21 | public class WindowLocaleChangeListener implements LocaleChangeListener { 22 | 23 | private Window window; 24 | private String key; 25 | 26 | public WindowLocaleChangeListener(Window window, String key) { 27 | this.window = window; 28 | this.key = key; 29 | } 30 | 31 | //// 32 | // LOCALE CHANGE LISTENER 33 | public void localeChanged(Locale locale) { 34 | 35 | if (window instanceof Dialog) { 36 | ((Dialog) window).setTitle(I18NManager.getText(key)); 37 | } 38 | if (window instanceof Frame) { 39 | ((Frame) window).setTitle(I18NManager.getText(key)); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/image/ThumbnailManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.image; 15 | 16 | import java.awt.Dimension; 17 | import java.awt.Graphics2D; 18 | import java.awt.Image; 19 | import java.awt.RenderingHints; 20 | import java.awt.image.BufferedImage; 21 | import java.io.File; 22 | import java.io.IOException; 23 | 24 | import javax.imageio.ImageIO; 25 | 26 | import net.rptools.lib.MD5Key; 27 | import net.rptools.lib.swing.SwingUtil; 28 | import org.apache.commons.io.FileUtils; 29 | 30 | public class ThumbnailManager { 31 | private final File thumbnailLocation; 32 | private final Dimension thumbnailSize; 33 | 34 | public ThumbnailManager(File thumbnailLocation, Dimension thumbnailSize) { 35 | this.thumbnailLocation = thumbnailLocation; 36 | this.thumbnailSize = thumbnailSize; 37 | } 38 | 39 | public File getThumbnailLocation() { 40 | return thumbnailLocation; 41 | } 42 | 43 | public Dimension getThumbnailSize() { 44 | return thumbnailSize; 45 | } 46 | 47 | public Image getThumbnail(File file) throws IOException { 48 | // Cache 49 | BufferedImage thumbnail = getCachedThumbnail(file); 50 | if (thumbnail != null) { 51 | return thumbnail; 52 | } 53 | // Create 54 | return createThumbnail(file); 55 | } 56 | 57 | private Image createThumbnail(File file) throws IOException { 58 | // Gather info 59 | File thumbnailFile = getThumbnailFile(file); 60 | if (thumbnailFile.exists()) { 61 | return ImageUtil.getImage(thumbnailFile); 62 | } 63 | 64 | Image image = ImageUtil.getImage(file); 65 | Dimension imgSize = new Dimension(image.getWidth(null), image.getHeight(null)); 66 | 67 | // Test if we Should we bother making a thumbnail ? 68 | // Jamz: New size 100k (was 30k) and put in check so we're not creating thumbnails LARGER than the original... 69 | if (file.length() < 102400 || (imgSize.width <= thumbnailSize.width && imgSize.height <= thumbnailSize.height)) { 70 | return image; 71 | } 72 | // Transform the image 73 | SwingUtil.constrainTo(imgSize, Math.min(image.getWidth(null), thumbnailSize.width), Math.min(image.getHeight(null), thumbnailSize.height)); 74 | BufferedImage thumbnailImage = new BufferedImage(imgSize.width, imgSize.height, ImageUtil.pickBestTransparency(image)); 75 | 76 | Graphics2D g = thumbnailImage.createGraphics(); 77 | g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 78 | g.drawImage(image, 0, 0, imgSize.width, imgSize.height, null); 79 | g.dispose(); 80 | 81 | // Use png to preserve transparency 82 | FileUtils.writeByteArrayToFile(thumbnailFile, ImageUtil.imageToBytes(thumbnailImage, "png")); 83 | 84 | return thumbnailImage; 85 | } 86 | 87 | public void clearImageThumbCache() { 88 | try { 89 | if (thumbnailLocation != null) { 90 | FileUtils.cleanDirectory(thumbnailLocation); 91 | } 92 | } catch (IOException e) { 93 | // TODO Auto-generated catch block 94 | e.printStackTrace(); 95 | } 96 | } 97 | 98 | private BufferedImage getCachedThumbnail(File file) { 99 | File thumbnailFile = getThumbnailFile(file); 100 | 101 | if (!thumbnailFile.exists()) { 102 | return null; 103 | } 104 | try { 105 | // Check that it hasn't changed on disk 106 | if (file.lastModified() > thumbnailFile.lastModified()) { 107 | return null; 108 | } 109 | // Get the thumbnail 110 | BufferedImage thumbnail = ImageIO.read(thumbnailFile); 111 | 112 | // Check that we have the size we want 113 | if (thumbnail.getWidth() != thumbnailSize.width && thumbnail.getHeight() != thumbnailSize.height) { 114 | return null; 115 | } 116 | return thumbnail; 117 | } catch (IOException ioe) { 118 | return null; 119 | } 120 | } 121 | 122 | private File getThumbnailFile(File file) { 123 | MD5Key key = new MD5Key(file.getAbsolutePath().getBytes()); 124 | return new File(thumbnailLocation.getPath(), key.toString()); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/net/FTPLocation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.net; 15 | 16 | import java.awt.image.BufferedImage; 17 | import java.io.IOException; 18 | import java.io.InputStream; 19 | import java.io.OutputStream; 20 | import java.net.URL; 21 | 22 | import javax.imageio.ImageWriter; 23 | 24 | import net.rptools.lib.FileUtil; 25 | 26 | import org.apache.commons.io.IOUtils; 27 | import org.apache.commons.lang.StringUtils; 28 | 29 | public class FTPLocation implements Location { 30 | private final String username; 31 | private transient String password; 32 | private final String hostname; 33 | private final String path; 34 | private final boolean binary; 35 | 36 | public FTPLocation(String username, String password, String hostname, String path) { 37 | this.username = username; 38 | this.password = password; 39 | this.hostname = hostname; 40 | this.path = path; 41 | this.binary = true; 42 | } 43 | 44 | public FTPLocation(String username, String password, String hostname, String path, boolean binary) { 45 | this.username = username; 46 | this.password = password; 47 | this.hostname = hostname; 48 | this.path = path; 49 | this.binary = binary; 50 | } 51 | 52 | public boolean isBinary() { 53 | return binary; 54 | } 55 | 56 | public String getHostname() { 57 | return hostname; 58 | } 59 | 60 | public String getPassword() { 61 | return password; 62 | } 63 | 64 | public String getPath() { 65 | return path; 66 | } 67 | 68 | public String getUsername() { 69 | return username; 70 | } 71 | 72 | public void putContent(InputStream content) throws IOException { 73 | OutputStream os = null; 74 | try { 75 | // os = composeURL().openConnection().getOutputStream(); 76 | os = new URL(composeFileLocation()).openConnection().getOutputStream(); 77 | FileUtil.copyWithClose(content, os); 78 | } finally { 79 | IOUtils.closeQuietly(os); 80 | } 81 | } 82 | 83 | public void putContent(ImageWriter writer, BufferedImage content) throws IOException { 84 | OutputStream os = null; 85 | try { 86 | // os = composeURL().openConnection().getOutputStream(); 87 | os = new URL(composeFileLocation()).openConnection().getOutputStream(); 88 | writer.setOutput(os); 89 | writer.write(content); 90 | } finally { 91 | IOUtils.closeQuietly(os); 92 | } 93 | } 94 | 95 | public InputStream getContent() throws IOException { 96 | // return composeURL().openConnection().getInputStream(); 97 | return new URL(composeFileLocation()).openConnection().getInputStream(); 98 | } 99 | 100 | private String composeFileLocation() { 101 | StringBuilder builder = new StringBuilder(); 102 | 103 | builder.append("ftp://"); 104 | if (username != null && !StringUtils.isEmpty(username)) { 105 | builder.append(username.replaceAll("@", "%40").replaceAll(":", "%3A")); 106 | } else { 107 | builder.append("anonymous"); 108 | } 109 | if (password != null && !StringUtils.isEmpty(password)) { 110 | builder.append(":").append(password.replaceAll("@", "%40").replaceAll(":", "%3A")); 111 | } 112 | builder.append("@"); 113 | builder.append(hostname); 114 | builder.append("/"); 115 | builder.append(path); 116 | if (binary) { 117 | builder.append(";type=i"); 118 | } 119 | return builder.toString(); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/net/LocalLocation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.net; 15 | 16 | import java.awt.image.BufferedImage; 17 | import java.io.BufferedInputStream; 18 | import java.io.BufferedOutputStream; 19 | import java.io.File; 20 | import java.io.FileInputStream; 21 | import java.io.FileOutputStream; 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.io.OutputStream; 25 | 26 | import javax.imageio.ImageWriter; 27 | import javax.imageio.stream.FileImageOutputStream; 28 | 29 | import net.rptools.lib.FileUtil; 30 | 31 | public class LocalLocation implements Location { 32 | 33 | private String localFile; 34 | 35 | public LocalLocation() { 36 | // For serialization 37 | } 38 | 39 | public LocalLocation(File file) { 40 | this.localFile = file.getAbsolutePath(); 41 | } 42 | 43 | public File getFile() { 44 | return new File(localFile); 45 | } 46 | 47 | public InputStream getContent() throws IOException { 48 | return new BufferedInputStream(new FileInputStream(getFile())); 49 | } 50 | 51 | public void putContent(InputStream content) throws IOException { 52 | 53 | OutputStream out = null; 54 | try { 55 | out = new BufferedOutputStream(new FileOutputStream(getFile())); 56 | 57 | FileUtil.copyWithClose(content, out); 58 | } finally { 59 | if (out != null) { 60 | out.close(); 61 | } 62 | } 63 | } 64 | 65 | public void putContent(ImageWriter writer, BufferedImage content) throws IOException { 66 | FileImageOutputStream out = null; 67 | try { 68 | out = new FileImageOutputStream(getFile()); 69 | 70 | writer.setOutput(out); 71 | writer.write(content); 72 | } finally { 73 | if (out != null) { 74 | out.close(); 75 | } 76 | } 77 | 78 | } 79 | 80 | /* 81 | public void backgroundPutContent(ImageWriter writer, BufferedImage content) throws IOException { 82 | FileImageOutputStream out = null; 83 | // TODO: put this in another thread 84 | try { 85 | out = new FileImageOutputStream(getFile()); 86 | 87 | writer.setOutput(out); 88 | writer.write(content); 89 | } finally { 90 | if (out != null) { 91 | out.close(); 92 | } 93 | } 94 | } 95 | */ 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/net/Location.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.net; 15 | 16 | import java.awt.image.BufferedImage; 17 | import java.io.IOException; 18 | import java.io.InputStream; 19 | 20 | import javax.imageio.ImageWriter; 21 | 22 | public interface Location { 23 | public void putContent(ImageWriter content, BufferedImage img) throws IOException; 24 | 25 | public void putContent(InputStream content) throws IOException; 26 | 27 | public InputStream getContent() throws IOException; 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/net/RPTURLStreamHandlerFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.net; 15 | 16 | import java.io.ByteArrayInputStream; 17 | import java.io.IOException; 18 | import java.io.InputStream; 19 | import java.net.URL; 20 | import java.net.URLConnection; 21 | import java.net.URLStreamHandler; 22 | import java.net.URLStreamHandlerFactory; 23 | import java.util.HashMap; 24 | import java.util.Map; 25 | 26 | import net.rptools.lib.FileUtil; 27 | 28 | public class RPTURLStreamHandlerFactory implements URLStreamHandlerFactory { 29 | 30 | private static Map imageMap = new HashMap(); 31 | 32 | private Map protocolMap = new HashMap(); 33 | 34 | public RPTURLStreamHandlerFactory() { 35 | registerProtocol("cp", new ClasspathStreamHandler()); 36 | } 37 | 38 | public void registerProtocol(String protocol, URLStreamHandler handler) { 39 | protocolMap.put(protocol, handler); 40 | } 41 | 42 | public URLStreamHandler createURLStreamHandler(String protocol) { 43 | 44 | return protocolMap.get(protocol); 45 | } 46 | 47 | private static class ClasspathStreamHandler extends URLStreamHandler { 48 | 49 | @Override 50 | protected URLConnection openConnection(URL u) throws IOException { 51 | 52 | // TODO: This should really figure out the exact type 53 | return new ImageURLConnection(u); 54 | } 55 | } 56 | 57 | private static class ImageURLConnection extends URLConnection { 58 | 59 | private byte[] data; 60 | 61 | public ImageURLConnection(URL url) { 62 | super(url); 63 | 64 | String path = url.getHost() + url.getFile(); 65 | data = imageMap.get(path); 66 | if (data == null) { 67 | try { 68 | data = FileUtil.loadResource(path); 69 | imageMap.put(path, data); 70 | } catch (IOException ioe) { 71 | ioe.printStackTrace(); 72 | data = new byte[] {}; 73 | } 74 | } 75 | } 76 | 77 | @Override 78 | public void connect() throws IOException { 79 | // Nothing to do 80 | } 81 | 82 | @Override 83 | public InputStream getInputStream() throws IOException { 84 | return new ByteArrayInputStream(data); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/service/EchoServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.service; 15 | 16 | import java.io.BufferedReader; 17 | import java.io.IOException; 18 | import java.io.InputStreamReader; 19 | import java.io.OutputStreamWriter; 20 | import java.io.PrintWriter; 21 | import java.net.ServerSocket; 22 | import java.net.Socket; 23 | 24 | public class EchoServer { 25 | 26 | private final int port; 27 | private boolean stop; 28 | private ServerSocket server; 29 | 30 | public EchoServer(int port) { 31 | this.port = port; 32 | } 33 | 34 | public synchronized void start() throws IOException { 35 | if (server != null) { 36 | return; 37 | } 38 | server = new ServerSocket(port); 39 | new ReceiveThread().start(); 40 | } 41 | 42 | public synchronized void stop() { 43 | if (server == null) { 44 | return; 45 | } 46 | try { 47 | stop = true; 48 | server.close(); 49 | server = null; 50 | } catch (IOException ioe) { 51 | // Since we're trying to kill it anyway 52 | ioe.printStackTrace(); 53 | } 54 | } 55 | 56 | private class ReceiveThread extends Thread { 57 | @Override 58 | public void run() { 59 | try { 60 | while (!stop) { 61 | Socket clientSocket = server.accept(); 62 | BufferedReader reader = new BufferedReader( 63 | new InputStreamReader(clientSocket.getInputStream(), "UTF-8")); 64 | PrintWriter writer = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream(), "UTF-8")); 65 | 66 | String line = reader.readLine(); 67 | while (line != null) { 68 | writer.println(line); 69 | writer.flush(); 70 | line = reader.readLine(); 71 | } 72 | } 73 | } catch (IOException e) { 74 | // Expected when the accept is killed 75 | } finally { 76 | server = null; 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/sound/SoundManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.sound; 15 | 16 | import java.io.IOException; 17 | import java.net.URL; 18 | import java.util.Enumeration; 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | import java.util.Properties; 22 | 23 | public class SoundManager { 24 | private final Map registeredSoundMap = new HashMap(); 25 | private final Map soundEventMap = new HashMap(); 26 | 27 | public void configure(String configPath) throws IOException { 28 | Properties props = new Properties(); 29 | props.load(SoundManager.class.getClassLoader().getResourceAsStream(configPath)); 30 | configure(props); 31 | } 32 | 33 | @SuppressWarnings("unchecked") 34 | public void configure(Properties properties) { 35 | for (Enumeration e = (Enumeration) properties.propertyNames(); e.hasMoreElements();) { 36 | String key = e.nextElement(); 37 | registerSound(key, properties.getProperty(key)); 38 | } 39 | } 40 | 41 | /** 42 | * These represent the built-in sounds. This is different than user contributed sounds which have an actual path to 43 | * them. 44 | */ 45 | public void registerSound(String name, URL sound) { 46 | if (sound != null) { 47 | registeredSoundMap.put(name, sound); 48 | } else { 49 | registeredSoundMap.remove(name); 50 | } 51 | } 52 | 53 | /** 54 | * These represent the built-in sounds. This is different than user contributed sounds which have an actual path to 55 | * them. The file is pulled from the class path. 56 | */ 57 | public void registerSound(String name, String path) { 58 | if (path != null && path.trim().length() == 0) { 59 | path = null; 60 | } 61 | registerSound(name, path != null ? SoundManager.class.getClassLoader().getResource(path) : null); 62 | } 63 | 64 | public URL getRegisteredSound(String name) { 65 | return registeredSoundMap.get(name); 66 | } 67 | 68 | /** 69 | * A sound event plays the sound associated with the event ID, this adds a new event type 70 | */ 71 | public void registerSoundEvent(String eventId, URL sound) { 72 | soundEventMap.put(eventId, sound); 73 | } 74 | 75 | /** 76 | * A sound event plays the sound associated with the event ID, this adds a new event type 77 | */ 78 | public void registerSoundEvent(String eventId) { 79 | registerSoundEvent(eventId, null); 80 | } 81 | 82 | /** 83 | * Play the sound associated with the eventId 84 | */ 85 | public void playSoundEvent(String eventId) { 86 | URL sound = soundEventMap.get(eventId); 87 | 88 | if (sound != null) { 89 | try { 90 | SoundPlayer.play(sound); 91 | } catch (IOException ioe) { 92 | ioe.printStackTrace(); 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/sound/SoundPlayer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.sound; 15 | 16 | import java.io.File; 17 | import java.io.FileInputStream; 18 | import java.io.IOException; 19 | import java.net.URL; 20 | import java.util.concurrent.ExecutorService; 21 | import java.util.concurrent.Executors; 22 | import java.util.concurrent.Future; 23 | import java.util.concurrent.atomic.AtomicInteger; 24 | 25 | import javazoom.jl.decoder.JavaLayerException; 26 | import javazoom.jl.player.Player; 27 | 28 | public class SoundPlayer { 29 | 30 | private static ExecutorService playerThreadPool = Executors.newCachedThreadPool(); 31 | private static AtomicInteger playerCount = new AtomicInteger(); 32 | public static final String FILE_EXTENSION = "mp3"; 33 | 34 | public static void play(File file) throws IOException { 35 | try { 36 | Player player = new Player(new FileInputStream(file)); 37 | play(player); 38 | } catch (JavaLayerException jle) { 39 | throw new IOException(jle.toString()); 40 | } 41 | } 42 | 43 | public static void play(URL url) throws IOException { 44 | try { 45 | Player player = new Player(url.openStream()); 46 | play(player); 47 | } catch (JavaLayerException jle) { 48 | throw new IOException(jle.toString()); 49 | } 50 | } 51 | 52 | public static void play(String sound) throws IOException { 53 | try { 54 | Player player = new Player(SoundPlayer.class.getClassLoader().getResourceAsStream(sound)); 55 | play(player); 56 | player.close(); 57 | } catch (JavaLayerException jle) { 58 | throw new IOException(jle.toString()); 59 | } catch (NullPointerException npe) { 60 | throw new IOException("Could not find sound: " + sound); 61 | } 62 | } 63 | 64 | public static int stopAll() { 65 | int currentThreads = playerCount.get(); 66 | playerThreadPool.shutdownNow(); 67 | System.out.println("Shutdown? " + playerThreadPool.isShutdown()); 68 | playerThreadPool.shutdown(); 69 | System.out.println("Terminated? " + playerThreadPool.isTerminated()); 70 | 71 | return currentThreads; 72 | } 73 | 74 | /** 75 | * Wait for all sounds to stop playing (Mostly for testing purposes) 76 | */ 77 | public static void waitFor() { 78 | 79 | while (playerCount.get() > 0) { 80 | try { 81 | synchronized (playerCount) { 82 | playerCount.wait(); 83 | } 84 | } catch (InterruptedException ie) { 85 | ie.printStackTrace(); 86 | } 87 | } 88 | } 89 | 90 | private static void play(final Player player) { 91 | playerCount.incrementAndGet(); 92 | 93 | //Not sure how to use Future here? 94 | Future f = playerThreadPool.submit(new Runnable() { 95 | public void run() { 96 | try { 97 | player.play(); 98 | playerCount.decrementAndGet(); 99 | synchronized (playerCount) { 100 | playerCount.notify(); 101 | } 102 | } catch (JavaLayerException jle) { 103 | jle.printStackTrace(); 104 | } 105 | } 106 | }); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/AboutDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.BorderLayout; 17 | import java.awt.FlowLayout; 18 | import java.awt.GridLayout; 19 | import java.awt.Image; 20 | 21 | import javax.swing.ImageIcon; 22 | import javax.swing.JButton; 23 | import javax.swing.JDialog; 24 | import javax.swing.JEditorPane; 25 | import javax.swing.JFrame; 26 | import javax.swing.JLabel; 27 | import javax.swing.JPanel; 28 | import javax.swing.JScrollPane; 29 | import javax.swing.text.html.HTMLDocument; 30 | import javax.swing.text.html.HTMLEditorKit; 31 | 32 | @SuppressWarnings("serial") 33 | public class AboutDialog extends JDialog { 34 | private JPanel jContentPane = null; 35 | private JPanel bottomPanel = null; 36 | private JButton okButton = null; 37 | private JPanel centerPanel = null; 38 | private JPanel creditPanel = null; 39 | private JLabel logoLabel = null; 40 | private JEditorPane creditEditorPane = null; 41 | 42 | /** 43 | * This is the default constructor 44 | */ 45 | public AboutDialog(JFrame parent, Image logo, String credits) { 46 | super(parent, true); 47 | initialize(); 48 | 49 | if (logo != null) { 50 | logoLabel.setIcon(new ImageIcon(logo)); 51 | } 52 | creditEditorPane.setText(credits); 53 | } 54 | 55 | @Override 56 | public void setVisible(boolean b) { 57 | if (b) { 58 | SwingUtil.centerOver(this, getOwner()); 59 | } 60 | super.setVisible(b); 61 | } 62 | 63 | /** 64 | * This method initializes this 65 | * 66 | * @return void 67 | */ 68 | private void initialize() { 69 | this.setSize(354, 354); 70 | this.setTitle("About"); 71 | this.setContentPane(getJContentPane()); 72 | } 73 | 74 | /** 75 | * This method initializes jContentPane 76 | * 77 | * @return javax.swing.JPanel 78 | */ 79 | private JPanel getJContentPane() { 80 | if (jContentPane == null) { 81 | jContentPane = new JPanel(); 82 | jContentPane.setLayout(new BorderLayout()); 83 | jContentPane.add(getBottomPanel(), java.awt.BorderLayout.SOUTH); 84 | jContentPane.add(getCenterPanel(), java.awt.BorderLayout.CENTER); 85 | } 86 | return jContentPane; 87 | } 88 | 89 | /** 90 | * This method initializes bottomPanel 91 | * 92 | * @return javax.swing.JPanel 93 | */ 94 | private JPanel getBottomPanel() { 95 | if (bottomPanel == null) { 96 | FlowLayout flowLayout = new FlowLayout(); 97 | flowLayout.setAlignment(java.awt.FlowLayout.RIGHT); 98 | bottomPanel = new JPanel(); 99 | bottomPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED)); 100 | bottomPanel.setLayout(flowLayout); 101 | bottomPanel.add(getOkButton(), null); 102 | } 103 | return bottomPanel; 104 | } 105 | 106 | /** 107 | * This method initializes okButton 108 | * 109 | * @return javax.swing.JButton 110 | */ 111 | private JButton getOkButton() { 112 | if (okButton == null) { 113 | okButton = new JButton(); 114 | okButton.setText("OK"); 115 | okButton.addActionListener(new java.awt.event.ActionListener() { 116 | public void actionPerformed(java.awt.event.ActionEvent e) { 117 | setVisible(false); 118 | } 119 | }); 120 | } 121 | return okButton; 122 | } 123 | 124 | /** 125 | * This method initializes centerPanel 126 | * 127 | * @return javax.swing.JPanel 128 | */ 129 | private JPanel getCenterPanel() { 130 | if (centerPanel == null) { 131 | logoLabel = new JLabel(); 132 | logoLabel.setText(""); 133 | centerPanel = new JPanel(); 134 | centerPanel.setLayout(new BorderLayout()); 135 | centerPanel.setBackground(java.awt.Color.white); 136 | JScrollPane jsp = new JScrollPane(getCreditPanel()); 137 | float fontSizePts = getCreditPanel().getFont().getSize2D(); 138 | jsp.getVerticalScrollBar().setUnitIncrement((int) (fontSizePts * 1.3)); // size + 30% 139 | jsp.getVerticalScrollBar().setBlockIncrement((int) (fontSizePts * 13.0)); // x10 140 | centerPanel.add(jsp, java.awt.BorderLayout.CENTER); 141 | centerPanel.add(logoLabel, java.awt.BorderLayout.NORTH); 142 | } 143 | return centerPanel; 144 | } 145 | 146 | /** 147 | * This method initializes creditPanel 148 | * 149 | * @return javax.swing.JPanel 150 | */ 151 | private JPanel getCreditPanel() { 152 | if (creditPanel == null) { 153 | GridLayout gridLayout = new GridLayout(); 154 | gridLayout.setRows(1); 155 | creditPanel = new JPanel(); 156 | creditPanel.setLayout(gridLayout); 157 | creditPanel.setBackground(java.awt.Color.white); 158 | creditPanel.add(getCreditEditorPane(), null); 159 | } 160 | return creditPanel; 161 | } 162 | 163 | /** 164 | * This method initializes creditEditorPane 165 | * 166 | * @return javax.swing.JEditorPane 167 | */ 168 | private JEditorPane getCreditEditorPane() { 169 | if (creditEditorPane == null) { 170 | creditEditorPane = new JEditorPane(); 171 | creditEditorPane.setEditable(false); 172 | 173 | HTMLDocument document = new HTMLDocument(); 174 | 175 | creditEditorPane.setEditorKit(new HTMLEditorKit()); 176 | creditEditorPane.setDocument(document); 177 | } 178 | return creditEditorPane; 179 | } 180 | 181 | } // @jve:decl-index=0:visual-constraint="200,16" 182 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/AbstractPaintChooserPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import javax.swing.JPanel; 17 | 18 | @SuppressWarnings("serial") 19 | public abstract class AbstractPaintChooserPanel extends JPanel { 20 | 21 | public abstract String getDisplayName(); 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/FramesPerSecond.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | public class FramesPerSecond extends Thread { 17 | 18 | private int count = 0; 19 | private int lastFPS = 0; 20 | 21 | public FramesPerSecond() { 22 | setDaemon(true); 23 | } 24 | 25 | public void bump() { 26 | count++; 27 | } 28 | 29 | public int getFramesPerSecond() { 30 | return lastFPS; 31 | } 32 | 33 | @Override 34 | public void run() { 35 | while (true) { 36 | lastFPS = count; 37 | count = 0; 38 | try { 39 | Thread.sleep(1000); 40 | } catch (InterruptedException ie) { 41 | ie.printStackTrace(); 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/GradientPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Color; 17 | import java.awt.FlowLayout; 18 | import java.awt.GradientPaint; 19 | import java.awt.Graphics; 20 | import java.awt.Graphics2D; 21 | import java.awt.LayoutManager; 22 | import java.awt.Paint; 23 | 24 | import javax.swing.JPanel; 25 | 26 | @SuppressWarnings("serial") 27 | public class GradientPanel extends JPanel { 28 | 29 | private Color c1; 30 | private Color c2; 31 | 32 | public GradientPanel(Color c1, Color c2) { 33 | this(c1, c2, new FlowLayout()); 34 | } 35 | 36 | public GradientPanel(Color c1, Color c2, LayoutManager layout) { 37 | super(layout); 38 | 39 | this.c1 = c1; 40 | this.c2 = c2; 41 | } 42 | 43 | @Override 44 | protected void paintComponent(Graphics g) { 45 | 46 | Graphics2D g2d = (Graphics2D) g; 47 | Paint p = new GradientPaint(0, 0, c1, getSize().width, 0, c2); 48 | Paint oldPaint = g2d.getPaint(); 49 | g2d.setPaint(p); 50 | g2d.fillRect(0, 0, getSize().width, getSize().height); 51 | g2d.setPaint(oldPaint); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/ImageBorder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Graphics2D; 17 | import java.awt.Rectangle; 18 | import java.awt.Shape; 19 | import java.awt.geom.Rectangle2D; 20 | import java.awt.image.BufferedImage; 21 | import java.io.IOException; 22 | 23 | import net.rptools.lib.image.ImageUtil; 24 | 25 | /** 26 | * @author trevor 27 | */ 28 | public class ImageBorder { 29 | public static final ImageBorder GRAY = new ImageBorder("net/rptools/lib/swing/image/border/gray"); 30 | public static final ImageBorder RED = new ImageBorder("net/rptools/lib/swing/image/border/red"); 31 | public static final ImageBorder BLUE = new ImageBorder("net/rptools/lib/swing/image/border/blue"); 32 | 33 | private BufferedImage topRight; 34 | private BufferedImage top; 35 | private BufferedImage topLeft; 36 | private BufferedImage left; 37 | private BufferedImage bottomLeft; 38 | private BufferedImage bottom; 39 | private BufferedImage bottomRight; 40 | private BufferedImage right; 41 | 42 | private int topMargin; 43 | private int bottomMargin; 44 | private int leftMargin; 45 | private int rightMargin; 46 | 47 | public ImageBorder(String imagePath) { 48 | try { 49 | topRight = ImageUtil.getCompatibleImage(imagePath + "/tr.png"); 50 | top = ImageUtil.getCompatibleImage(imagePath + "/top.png"); 51 | topLeft = ImageUtil.getCompatibleImage(imagePath + "/tl.png"); 52 | left = ImageUtil.getCompatibleImage(imagePath + "/left.png"); 53 | bottomLeft = ImageUtil.getCompatibleImage(imagePath + "/bl.png"); 54 | bottom = ImageUtil.getCompatibleImage(imagePath + "/bottom.png"); 55 | bottomRight = ImageUtil.getCompatibleImage(imagePath + "/br.png"); 56 | right = ImageUtil.getCompatibleImage(imagePath + "/right.png"); 57 | 58 | topMargin = max(topRight.getHeight(), top.getHeight(), topLeft.getHeight()); 59 | bottomMargin = max(bottomRight.getHeight(), bottom.getHeight(), bottomLeft.getHeight()); 60 | rightMargin = max(topRight.getWidth(), right.getWidth(), bottomRight.getWidth()); 61 | leftMargin = max(topLeft.getWidth(), left.getWidth(), bottomLeft.getWidth()); 62 | } catch (IOException ioe) { 63 | ioe.printStackTrace(); 64 | } 65 | } 66 | 67 | public int getTopMargin() { 68 | return topMargin; 69 | } 70 | 71 | public int getBottomMargin() { 72 | return bottomMargin; 73 | } 74 | 75 | public int getRightMargin() { 76 | return rightMargin; 77 | } 78 | 79 | public int getLeftMargin() { 80 | return leftMargin; 81 | } 82 | 83 | public void paintAround(Graphics2D g, Rectangle rect) { 84 | paintAround(g, rect.x, rect.y, rect.width, rect.height); 85 | } 86 | 87 | public void paintAround(Graphics2D g, int x, int y, int width, int height) { 88 | paintWithin(g, x - leftMargin, y - topMargin, width + leftMargin + rightMargin, height + topMargin + bottomMargin); 89 | } 90 | 91 | public void paintWithin(Graphics2D g, Rectangle rect) { 92 | paintWithin(g, rect.x, rect.y, rect.width, rect.height); 93 | } 94 | 95 | public void paintWithin(Graphics2D g, int x, int y, int width, int height) { 96 | Rectangle2D r = g.getClipBounds().createIntersection(new Rectangle(x, y, width, height)); 97 | if (r.isEmpty()) 98 | return; 99 | Shape oldClip = g.getClip(); 100 | 101 | // Draw Corners 102 | g.drawImage(topLeft, x + leftMargin - topLeft.getWidth(), y + topMargin - topLeft.getHeight(), null); 103 | g.drawImage(topRight, x + width - rightMargin, y + topMargin - topRight.getHeight(), null); 104 | g.drawImage(bottomLeft, x + leftMargin - bottomLeft.getWidth(), y + height - bottomMargin, null); 105 | g.drawImage(bottomRight, x + width - rightMargin, y + height - bottomMargin, null); 106 | 107 | // Draw top 108 | 109 | int i; 110 | int max = width - rightMargin; 111 | 112 | // Hopefully the compiler is doing subexpression optimization! ;-) 113 | Rectangle topEdge, botEdge, lftEdge, rgtEdge; 114 | topEdge = new Rectangle(x + leftMargin, y + topMargin - top.getHeight(), width - leftMargin - rightMargin, top.getHeight()); 115 | botEdge = new Rectangle(x + leftMargin, y + height - bottomMargin, width - leftMargin - rightMargin, top.getHeight()); 116 | lftEdge = new Rectangle(x + leftMargin - left.getWidth(), y + topMargin, left.getWidth(), height - topMargin - bottomMargin); 117 | rgtEdge = new Rectangle(x + width - rightMargin, y + topMargin, right.getWidth(), height - topMargin - bottomMargin); 118 | 119 | Rectangle.intersect(topEdge, r, topEdge); 120 | Rectangle.intersect(botEdge, r, botEdge); 121 | Rectangle.intersect(lftEdge, r, lftEdge); 122 | Rectangle.intersect(rgtEdge, r, rgtEdge); 123 | 124 | // Top 125 | if (!topEdge.isEmpty()) { 126 | g.setClip(topEdge); 127 | for (i = leftMargin; i < max; i += top.getWidth()) { 128 | g.drawImage(top, x + i, y + topMargin - top.getHeight(), null); 129 | } 130 | } 131 | 132 | // Bottom 133 | if (!botEdge.isEmpty()) { 134 | g.setClip(botEdge); 135 | for (i = leftMargin; i < max; i += bottom.getWidth()) { 136 | g.drawImage(bottom, x + i, y + height - bottomMargin, null); 137 | } 138 | } 139 | 140 | // Left 141 | if (!lftEdge.isEmpty()) { 142 | g.setClip(lftEdge); 143 | max = height - bottomMargin; 144 | for (i = topMargin; i < max; i += left.getHeight()) { 145 | g.drawImage(left, x + leftMargin - left.getWidth(), y + i, null); 146 | } 147 | } 148 | 149 | // Right 150 | if (!rgtEdge.isEmpty()) { 151 | g.setClip(rgtEdge); 152 | for (i = topMargin; i < max; i += right.getHeight()) { 153 | g.drawImage(right, x + width - rightMargin, y + i, null); 154 | } 155 | } 156 | g.setClip(oldClip); 157 | } 158 | 159 | private int max(int i1, int i2, int i3) { 160 | int bigger = i1 > i2 ? i1 : i2; 161 | return bigger > i3 ? bigger : i3; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/ImageLabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Graphics2D; 17 | import java.awt.image.BufferedImage; 18 | import java.io.IOException; 19 | 20 | import net.rptools.lib.image.ImageUtil; 21 | 22 | public class ImageLabel { 23 | 24 | private BufferedImage labelBoxLeftImage; 25 | private BufferedImage labelBoxRightImage; 26 | private BufferedImage labelBoxMiddleImage; 27 | private int leftMargin = 4; 28 | private int rightMargin = 4; 29 | 30 | public ImageLabel(String labelImage, int leftMargin, int rightMargin) { 31 | this.leftMargin = leftMargin; 32 | this.rightMargin = rightMargin; 33 | 34 | try { 35 | parseImage(ImageUtil.getCompatibleImage(labelImage)); 36 | } catch (IOException ioe) { 37 | ioe.printStackTrace(); 38 | } 39 | } 40 | 41 | public void renderLabel(Graphics2D g, int x, int y, int width, int height) { 42 | g.drawImage(labelBoxLeftImage, x, y, labelBoxLeftImage.getWidth(), height, null); 43 | g.drawImage(labelBoxRightImage, x + width - rightMargin, y, rightMargin, height, null); 44 | g.drawImage(labelBoxMiddleImage, x + leftMargin, y, width - rightMargin - leftMargin, height, null); 45 | } 46 | 47 | private void parseImage(BufferedImage image) { 48 | 49 | labelBoxLeftImage = image.getSubimage(0, 0, leftMargin, image.getHeight()); 50 | labelBoxRightImage = image.getSubimage(image.getWidth() - rightMargin, 0, rightMargin, image.getHeight()); 51 | labelBoxMiddleImage = image.getSubimage(leftMargin, 0, image.getWidth() - leftMargin - rightMargin, image.getHeight()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/ImagePanelModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Image; 17 | import java.awt.Paint; 18 | import java.awt.datatransfer.Transferable; 19 | 20 | public interface ImagePanelModel { 21 | 22 | public int getImageCount(); 23 | 24 | public Transferable getTransferable(int index); 25 | 26 | public Object getID(int index); 27 | 28 | public Image getImage(Object ID); 29 | 30 | public Image getImage(int index); 31 | 32 | public String getCaption(int index); 33 | 34 | public String getCaption(int index, boolean withDimensions); 35 | 36 | public Paint getBackground(int index); 37 | 38 | public Image[] getDecorations(int index); 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/ImageToggleButton.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Dimension; 17 | import java.awt.Graphics; 18 | import java.awt.Image; 19 | import java.io.IOException; 20 | 21 | import javax.swing.JToggleButton; 22 | 23 | import net.rptools.lib.image.ImageUtil; 24 | 25 | @SuppressWarnings("serial") 26 | public class ImageToggleButton extends JToggleButton { 27 | 28 | private Image onImage; 29 | private Image offImage; 30 | 31 | private int padding; 32 | 33 | public ImageToggleButton(String onImage, String offImage) { 34 | this(onImage, offImage, 3); 35 | } 36 | 37 | public ImageToggleButton(String onImage, String offImage, int padding) { 38 | try { 39 | init(ImageUtil.getImage(onImage), ImageUtil.getImage(offImage), padding); 40 | } catch (IOException ioe) { 41 | ioe.printStackTrace(); 42 | } 43 | } 44 | 45 | public ImageToggleButton(Image onImage, Image offImage) { 46 | this(onImage, offImage, 3); 47 | } 48 | 49 | public ImageToggleButton(Image onImage, Image offImage, int padding) { 50 | init(onImage, offImage, padding); 51 | } 52 | 53 | private void init(Image onImage, Image offImage, int padding) { 54 | 55 | this.onImage = onImage; 56 | this.offImage = offImage; 57 | this.padding = padding; 58 | 59 | int maxWidth = Math.max(onImage.getWidth(null), offImage.getWidth(null)); 60 | int maxHeight = Math.max(onImage.getHeight(null), offImage.getHeight(null)); 61 | 62 | setPreferredSize(new Dimension(maxWidth, maxHeight)); 63 | setMinimumSize(new Dimension(maxWidth, maxHeight)); 64 | setFocusPainted(false); 65 | setBorderPainted(false); 66 | 67 | setOpaque(false); 68 | } 69 | 70 | @Override 71 | protected void paintComponent(Graphics g) { 72 | 73 | Dimension size = getSize(); 74 | 75 | // g.setColor(getBackground()); 76 | // g.fillRect(0, 0, size.width-1, size.height-1); 77 | 78 | Image image = isSelected() ? onImage : offImage; 79 | 80 | g.drawImage(image, (size.width - image.getWidth(null)) / 2 + padding / 2, (size.height - image.getHeight(null)) / 2 + padding / 2, this); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/JSplitPaneEx.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Dimension; 17 | 18 | import javax.swing.JComponent; 19 | import javax.swing.JSplitPane; 20 | 21 | /** 22 | * Extension that provides the ability to show/hide one of the panels 23 | * in the split pane 24 | */ 25 | @SuppressWarnings("serial") 26 | public class JSplitPaneEx extends JSplitPane { 27 | 28 | private int lastVisibleSize; 29 | 30 | private static final int HORIZONTAL = 0; 31 | private static final int VERITICAL = 1; 32 | 33 | private static final int LEFT = 0; 34 | private static final int RIGHT = 1; 35 | 36 | private boolean isEitherHidden; 37 | 38 | private int dividerSize; 39 | 40 | public JSplitPaneEx() { 41 | setContinuousLayout(true); 42 | } 43 | 44 | public void setInitialDividerPosition(int position) { 45 | lastVisibleSize = position; 46 | setDividerLocation(position); 47 | } 48 | 49 | public int getDividerLocation() { 50 | return getDividerSize() > 0 ? super.getDividerLocation() : lastVisibleSize; 51 | } 52 | 53 | public boolean isTopHidden() { 54 | return !getTopComponent().isVisible(); 55 | } 56 | 57 | public boolean isLeftHidden() { 58 | return !getLeftComponent().isVisible(); 59 | } 60 | 61 | public boolean isBottomHidden() { 62 | return !getBottomComponent().isVisible(); 63 | } 64 | 65 | public boolean isRightHidden() { 66 | return !getRightComponent().isVisible(); 67 | } 68 | 69 | public void hideLeft() { 70 | hideInternal((JComponent) getLeftComponent(), LEFT, HORIZONTAL); 71 | } 72 | 73 | public void hideTop() { 74 | hideInternal((JComponent) getLeftComponent(), LEFT, VERITICAL); 75 | } 76 | 77 | public void showLeft() { 78 | showInternal((JComponent) getLeftComponent(), LEFT, HORIZONTAL); 79 | } 80 | 81 | public void showTop() { 82 | showInternal((JComponent) getLeftComponent(), LEFT, VERITICAL); 83 | } 84 | 85 | public void hideRight() { 86 | hideInternal((JComponent) getRightComponent(), RIGHT, HORIZONTAL); 87 | } 88 | 89 | public void hideBottom() { 90 | hideInternal((JComponent) getRightComponent(), RIGHT, VERITICAL); 91 | } 92 | 93 | public void showRight() { 94 | showInternal((JComponent) getRightComponent(), RIGHT, HORIZONTAL); 95 | } 96 | 97 | public void showBottom() { 98 | showInternal((JComponent) getRightComponent(), RIGHT, VERITICAL); 99 | } 100 | 101 | public int getLastVisibleSize() { 102 | return lastVisibleSize; 103 | } 104 | 105 | private synchronized void hideInternal(JComponent component, int which, int orientation) { 106 | if (isEitherHidden) { 107 | return; 108 | } 109 | 110 | Dimension componentSize = component.getSize(); 111 | Dimension mySize = getSize(); 112 | 113 | lastVisibleSize = orientation == HORIZONTAL ? componentSize.width : componentSize.height; 114 | if (which == RIGHT) { 115 | lastVisibleSize = (orientation == HORIZONTAL ? mySize.width : mySize.height) - lastVisibleSize - getDividerSize(); 116 | } 117 | component.setVisible(false); 118 | dividerSize = getDividerSize(); 119 | 120 | setDividerSize(0); 121 | 122 | isEitherHidden = true; 123 | } 124 | 125 | private synchronized void showInternal(JComponent component, int which, int orientation) { 126 | if (!isEitherHidden) { 127 | return; 128 | } 129 | 130 | if (lastVisibleSize == 0) { 131 | 132 | Dimension mySize = getSize(); 133 | Dimension preferredSize = component.getSize(); 134 | 135 | if (preferredSize.width == 0 && preferredSize.height == 0) { 136 | preferredSize = component.getMinimumSize(); 137 | } 138 | 139 | lastVisibleSize = orientation == HORIZONTAL ? preferredSize.width : preferredSize.height; 140 | if (which == RIGHT) { 141 | lastVisibleSize = (orientation == HORIZONTAL ? mySize.width : mySize.height) - lastVisibleSize; 142 | } 143 | } 144 | setDividerSize(dividerSize); 145 | setDividerLocation(lastVisibleSize); 146 | 147 | component.setVisible(true); 148 | isEitherHidden = false; 149 | } 150 | 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/OutlookPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Dimension; 17 | import java.awt.Graphics; 18 | import java.awt.event.ActionEvent; 19 | import java.awt.event.ActionListener; 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | 23 | import javax.swing.JButton; 24 | import javax.swing.JComponent; 25 | import javax.swing.JPanel; 26 | 27 | /** 28 | * ButtonPanel.java 29 | * 30 | * Trevor Croft 2002 CopyRight 31 | */ 32 | @SuppressWarnings("serial") 33 | public class OutlookPanel extends JPanel { 34 | // TODO: Variable size buttons ? 35 | public static final int BUTTON_HEIGHT = 20; 36 | 37 | public OutlookPanel() { 38 | m_compList = new ArrayList(); 39 | 40 | setLayout(null); 41 | } 42 | 43 | /** 44 | * @param label 45 | * @param component 46 | * @return index of the button 47 | */ 48 | public int addButton(String label, JComponent component) { 49 | // Create the button 50 | JButtonEx button = new JButtonEx(label, m_compList.size(), component); 51 | button.addActionListener(new ActionListener() { 52 | 53 | public void actionPerformed(ActionEvent ae) { 54 | int index = ((JButtonEx) ae.getSource()).getIndex(); 55 | if (m_active.getIndex() == index && index > 0) { 56 | index--; 57 | } 58 | setActive(index); 59 | } 60 | 61 | }); 62 | 63 | // Update 64 | component.setVisible(false); 65 | m_compList.add(button); 66 | add(label, button); 67 | add(label, component); 68 | 69 | if (m_compList.size() == 1) { 70 | setActive(0); 71 | } 72 | 73 | repaint(); 74 | return m_compList.size() - 1; 75 | } 76 | 77 | public int getButtonCount() { 78 | return m_compList.size(); 79 | } 80 | 81 | public void setActive(int index) { 82 | // Sanity check 83 | if (index < 0 || index >= m_compList.size()) { 84 | return; 85 | } 86 | 87 | // Update old active 88 | if (m_active != null) { 89 | m_active.getComponent().setVisible(false); 90 | } 91 | 92 | // Set it 93 | m_active = m_compList.get(index); 94 | m_active.getComponent().setVisible(true); 95 | 96 | repaint(); 97 | } 98 | 99 | public void setActive(String name) { 100 | setActive(getButtonIndex(name)); 101 | } 102 | 103 | public int getButtonIndex(String name) { 104 | 105 | for (JButtonEx button : m_compList) { 106 | 107 | if (button.getText().equals(name)) { 108 | return button.m_index; 109 | } 110 | } 111 | 112 | return -1; 113 | } 114 | 115 | public void paint(Graphics g) { 116 | int y = 0; 117 | 118 | Dimension size = getSize(); 119 | 120 | g.setColor(getBackground()); 121 | g.fillRect(0, 0, size.width, size.height); 122 | 123 | // TODO: This can be pulled out and put in a layout manager 124 | for (int count = 0; count < m_compList.size(); count++) { 125 | JButtonEx button = m_compList.get(count); 126 | 127 | // Position the button 128 | button.setBounds(0, y, size.width, BUTTON_HEIGHT); 129 | 130 | // Update 131 | y += BUTTON_HEIGHT; 132 | 133 | // Active Panel ? 134 | if (button == m_active) { 135 | // Calculate 136 | int height = getSize().height - (m_compList.size() * BUTTON_HEIGHT); 137 | 138 | // Stretch to take the available space 139 | button.m_component.setBounds(5, y, size.width - 6, height - 2); 140 | button.m_component.revalidate(); 141 | 142 | y += height; 143 | } 144 | 145 | } 146 | 147 | // Paint them 148 | paintChildren(g); 149 | } 150 | 151 | // For convenience 152 | private class JButtonEx extends JButton { 153 | public JButtonEx(String label, int index, JComponent component) { 154 | super(label); 155 | m_index = index; 156 | setHorizontalAlignment(LEFT); 157 | m_component = component; 158 | setFocusPainted(false); 159 | } 160 | 161 | public int getIndex() { 162 | return m_index; 163 | } 164 | 165 | /** 166 | * We don't ever want the focus 167 | */ 168 | public boolean isRequestFocusEnabled() { 169 | return false; 170 | } 171 | 172 | public JComponent getComponent() { 173 | return m_component; 174 | } 175 | 176 | private int m_index; 177 | private JComponent m_component; 178 | } 179 | 180 | // Internal 181 | private List m_compList; 182 | private JButtonEx m_active; 183 | } -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/PaintChooser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.BorderLayout; 17 | import java.awt.Color; 18 | import java.awt.Dimension; 19 | import java.awt.FlowLayout; 20 | import java.awt.Frame; 21 | import java.awt.Paint; 22 | import java.awt.event.ActionListener; 23 | import java.awt.event.WindowAdapter; 24 | import java.awt.event.WindowEvent; 25 | 26 | import javax.swing.BorderFactory; 27 | import javax.swing.JButton; 28 | import javax.swing.JColorChooser; 29 | import javax.swing.JDialog; 30 | import javax.swing.JLabel; 31 | import javax.swing.JPanel; 32 | import javax.swing.JTabbedPane; 33 | import javax.swing.colorchooser.AbstractColorChooserPanel; 34 | import javax.swing.event.ChangeEvent; 35 | import javax.swing.event.ChangeListener; 36 | 37 | @SuppressWarnings("serial") 38 | public class PaintChooser extends JPanel { 39 | 40 | private final JColorChooser swatchColorChooser; 41 | private final JColorChooser hueColorChooser; 42 | private final JColorChooser rgbColorChooser; 43 | 44 | private Paint paint; 45 | 46 | private final PaintedPanel previewPanel; 47 | 48 | private final JTabbedPane tabbedPane; 49 | 50 | private JDialog dialog; 51 | 52 | public PaintChooser() { 53 | setLayout(new BorderLayout()); 54 | 55 | tabbedPane = new JTabbedPane(); 56 | 57 | previewPanel = new PaintedPanel(); 58 | previewPanel.setBorder(BorderFactory.createLineBorder(Color.black)); 59 | previewPanel.setPreferredSize(new Dimension(150, 100)); 60 | 61 | swatchColorChooser = createSwatchColorChooser(); 62 | swatchColorChooser.setColor(Color.white); 63 | 64 | hueColorChooser = createHueColorChooser(); 65 | hueColorChooser.setColor(Color.white); 66 | 67 | rgbColorChooser = createRGBColorChooser(); 68 | rgbColorChooser.setColor(Color.white); 69 | 70 | AbstractColorChooserPanel[] choosers = swatchColorChooser.getChooserPanels(); 71 | 72 | if (choosers != null && choosers.length > 0) { 73 | tabbedPane.addTab(choosers[0].getDisplayName(), swatchColorChooser); 74 | } 75 | choosers = hueColorChooser.getChooserPanels(); 76 | if (choosers != null && choosers.length > 0) { 77 | tabbedPane.addTab(choosers[0].getDisplayName(), hueColorChooser); 78 | } 79 | choosers = rgbColorChooser.getChooserPanels(); 80 | if (choosers != null && choosers.length > 0) { 81 | tabbedPane.addTab(choosers[0].getDisplayName(), rgbColorChooser); 82 | } 83 | 84 | add(BorderLayout.CENTER, tabbedPane); 85 | add(BorderLayout.SOUTH, createSouthPanel()); 86 | } 87 | 88 | public void addPaintChooser(AbstractPaintChooserPanel panel) { 89 | tabbedPane.addTab(panel.getDisplayName(), panel); 90 | } 91 | 92 | public Paint getPaint() { 93 | return paint; 94 | } 95 | 96 | public void setPaint(Paint paint) { 97 | this.paint = paint; 98 | previewPanel.setPaint(paint); 99 | } 100 | 101 | private JPanel createSouthPanel() { 102 | JPanel panel = new JPanel(new BorderLayout()); 103 | panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5), BorderFactory.createLoweredBevelBorder())); 104 | panel.add(previewPanel); 105 | 106 | return panel; 107 | } 108 | 109 | private JPanel createButtonPanel(JDialog dialog) { 110 | JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); 111 | 112 | panel.add(createOKButton(dialog)); 113 | panel.add(createCancelButton(dialog)); 114 | 115 | return panel; 116 | } 117 | 118 | private JButton createOKButton(final JDialog dialog) { 119 | JButton button = new JButton("OK"); 120 | button.addActionListener(new ActionListener() { 121 | public void actionPerformed(java.awt.event.ActionEvent e) { 122 | dialog.setVisible(false); 123 | } 124 | }); 125 | return button; 126 | } 127 | 128 | private JButton createCancelButton(final JDialog dialog) { 129 | JButton button = new JButton("Cancel"); 130 | button.addActionListener(new ActionListener() { 131 | public void actionPerformed(java.awt.event.ActionEvent e) { 132 | paint = null; 133 | dialog.setVisible(false); 134 | } 135 | }); 136 | return button; 137 | } 138 | 139 | private JColorChooser createSwatchColorChooser() { 140 | final JColorChooser chooser = new JColorChooser(); 141 | 142 | AbstractColorChooserPanel swatchPanel = chooser.getChooserPanels()[0]; 143 | for (AbstractColorChooserPanel panel : chooser.getChooserPanels()) { 144 | if (panel != swatchPanel) { // Swatch panel 145 | chooser.removeChooserPanel(panel); 146 | } 147 | } 148 | 149 | chooser.setPreviewPanel(new JPanel()); 150 | chooser.getSelectionModel().addChangeListener(new ChangeListener() { 151 | public void stateChanged(ChangeEvent e) { 152 | setPaint(chooser.getColor()); 153 | hueColorChooser.setColor(chooser.getColor()); 154 | rgbColorChooser.setColor(chooser.getColor()); 155 | } 156 | }); 157 | return chooser; 158 | } 159 | 160 | private JColorChooser createHueColorChooser() { 161 | final JColorChooser chooser = new JColorChooser(); 162 | 163 | AbstractColorChooserPanel hsvPanel = chooser.getChooserPanels()[1]; 164 | 165 | for (AbstractColorChooserPanel panel : chooser.getChooserPanels()) { 166 | if (panel != hsvPanel) { // Hue panel 167 | chooser.removeChooserPanel(panel); 168 | } 169 | } 170 | 171 | chooser.setPreviewPanel(new JPanel()); 172 | chooser.getSelectionModel().addChangeListener(new ChangeListener() { 173 | public void stateChanged(ChangeEvent e) { 174 | setPaint(chooser.getColor()); 175 | swatchColorChooser.setColor(chooser.getColor()); 176 | rgbColorChooser.setColor(chooser.getColor()); 177 | } 178 | }); 179 | return chooser; 180 | } 181 | 182 | private JColorChooser createRGBColorChooser() { 183 | final JColorChooser chooser = new JColorChooser(); 184 | 185 | AbstractColorChooserPanel rgbPanel; 186 | if (chooser.getChooserPanels().length > 3) { 187 | rgbPanel = chooser.getChooserPanels()[3]; 188 | } else { 189 | rgbPanel = chooser.getChooserPanels()[2]; 190 | } 191 | 192 | for (AbstractColorChooserPanel panel : chooser.getChooserPanels()) { 193 | if (panel != rgbPanel) { // RGB panel 194 | chooser.removeChooserPanel(panel); 195 | } 196 | } 197 | 198 | chooser.setPreviewPanel(new JPanel()); 199 | chooser.getSelectionModel().addChangeListener(new ChangeListener() { 200 | public void stateChanged(ChangeEvent e) { 201 | setPaint(chooser.getColor()); 202 | swatchColorChooser.setColor(chooser.getColor()); 203 | hueColorChooser.setColor(chooser.getColor()); 204 | } 205 | }); 206 | return chooser; 207 | } 208 | 209 | public Paint choosePaint(Frame owner, Paint paint) { 210 | return choosePaint(owner, paint, "Choose Paint"); 211 | } 212 | 213 | public Paint choosePaint(Frame owner, Paint paint, String title) { 214 | if (dialog == null) { 215 | dialog = new JDialog(owner, true); 216 | dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 217 | dialog.addWindowListener(new WindowAdapter() { 218 | @Override 219 | public void windowClosing(WindowEvent e) { 220 | PaintChooser.this.paint = null; 221 | dialog.setVisible(false); 222 | } 223 | }); 224 | JPanel panel = new JPanel(new BorderLayout()); 225 | panel.add(BorderLayout.CENTER, this); 226 | panel.add(BorderLayout.SOUTH, createButtonPanel(dialog)); 227 | 228 | dialog.setContentPane(panel); 229 | dialog.pack(); 230 | SwingUtil.centerOver(dialog, owner); 231 | } 232 | 233 | dialog.setTitle(title); 234 | setPaint(paint); 235 | dialog.setVisible(true); 236 | return getPaint(); 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/PaintedPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Color; 17 | import java.awt.Dimension; 18 | import java.awt.Graphics; 19 | import java.awt.Graphics2D; 20 | import java.awt.Image; 21 | import java.awt.Paint; 22 | import java.awt.Rectangle; 23 | import java.awt.TexturePaint; 24 | import java.awt.image.BufferedImage; 25 | import java.io.File; 26 | import java.io.IOException; 27 | import java.net.URL; 28 | 29 | import javax.imageio.ImageIO; 30 | import javax.swing.ImageIcon; 31 | import javax.swing.JPanel; 32 | 33 | @SuppressWarnings("serial") 34 | public class PaintedPanel extends JPanel { 35 | 36 | private Paint paint; 37 | 38 | public PaintedPanel() { 39 | this(null); 40 | } 41 | 42 | public PaintedPanel(Paint paint) { 43 | this.paint = paint; 44 | setMinimumSize(new Dimension(10, 10)); 45 | setPreferredSize(getMinimumSize()); 46 | } 47 | 48 | public Paint getPaint() { 49 | return paint; 50 | } 51 | 52 | public void setPaint(Paint paint) { 53 | this.paint = paint; 54 | repaint(); 55 | } 56 | 57 | @Override 58 | protected void paintComponent(Graphics g) { 59 | 60 | Dimension size = getSize(); 61 | g.setColor(getBackground()); 62 | g.fillRect(0, 0, size.width, size.height); 63 | 64 | if (paint != null) { 65 | ((Graphics2D) g).setPaint(paint); 66 | g.fillRect(0, 0, size.width, size.height); 67 | } else { 68 | try { 69 | BufferedImage texture; 70 | texture = ImageIO.read(getClass().getResource("/net/rptools/lib/image/icons/transparent2.png")); 71 | TexturePaint tp = new TexturePaint(texture, new Rectangle(0, 0, 28, 28)); 72 | ((Graphics2D) g).setPaint(tp); 73 | g.fillRect(0, 0, size.width, size.height); 74 | } catch (IOException e) { 75 | System.out.println(e.getMessage()); 76 | g.setColor(Color.white); 77 | g.fillRect(0, 0, size.width, size.height); 78 | g.setColor(Color.red); 79 | g.drawLine(size.width - 1, 0, 0, size.height - 1); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/PenWidthChooser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.BasicStroke; 17 | import java.awt.Component; 18 | import java.awt.Graphics; 19 | import java.awt.Graphics2D; 20 | import java.awt.Stroke; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | import javax.swing.DefaultComboBoxModel; 25 | import javax.swing.DefaultListCellRenderer; 26 | import javax.swing.Icon; 27 | import javax.swing.JComboBox; 28 | import javax.swing.JList; 29 | 30 | /** 31 | * Combo box showing the available pen widths and a preview of each. 32 | * 33 | * @author Jay 34 | * @version $Revision: 1307 $ $Date: 2005-10-18 19:51:22 -0500 (Tue, 18 Oct 2005) $ $Author:& 35 | */ 36 | @SuppressWarnings("serial") 37 | public class PenWidthChooser extends JComboBox { 38 | 39 | /** 40 | * The renderer for this chooser. 41 | */ 42 | private PenListRenderer renderer = new PenListRenderer(); 43 | 44 | /** 45 | * Supported Pen Widths 46 | */ 47 | public static final int[] WIDTHS = { 1, 3, 5, 7, 11, 15, 21 }; 48 | 49 | /** 50 | * The width that the Icon is painted. 51 | */ 52 | public static final int ICON_WIDTH = 25; 53 | 54 | /** 55 | * The maximum number of eleemnts in the list before it scrolls 56 | */ 57 | public static final int MAX_ROW_COUNT = 10; 58 | 59 | /** 60 | * Create the renderer and model for the combo box 61 | */ 62 | public PenWidthChooser(int defaultThickness) { 63 | setRenderer(renderer); 64 | DefaultComboBoxModel model = new DefaultComboBoxModel(); 65 | int selected = -1; 66 | for (int i = 0; i < WIDTHS.length; i += 1) { 67 | model.addElement(WIDTHS[i]); 68 | renderer.icon.strokes.put(WIDTHS[i], new BasicStroke(WIDTHS[i], BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)); 69 | if (WIDTHS[i] == defaultThickness) 70 | selected = i; 71 | } // endfor 72 | 73 | // Set up the component 74 | setModel(model); 75 | setMaximumSize(getPreferredSize()); 76 | setMaximumRowCount(MAX_ROW_COUNT); 77 | setSelectedIndex(Math.max(selected, WIDTHS[0])); 78 | } 79 | 80 | /** 81 | * Renderer for the items in the combo box 82 | * 83 | * @author jgorrell 84 | * @version $Revision: 1307 $ $Date: 2005-10-18 19:51:22 -0500 (Tue, 18 Oct 2005) $ $Author: tcroft $ 85 | */ 86 | private class PenListRenderer extends DefaultListCellRenderer { 87 | 88 | /** 89 | * Icon used to draw the line sample 90 | */ 91 | PenIcon icon = new PenIcon(); 92 | 93 | /** 94 | * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean) 95 | */ 96 | @Override 97 | public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 98 | 99 | // Sets the text, clears the icon 100 | super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 101 | 102 | // Set the icon 103 | icon.width = (Integer) value; 104 | setIcon(icon); 105 | return this; 106 | } 107 | } 108 | 109 | /** 110 | * Icon for the renderer 111 | * 112 | * @author jgorrell 113 | * @version $Revision: 1307 $ $Date: 2005-10-18 19:51:22 -0500 (Tue, 18 Oct 2005) $ $Author: tcroft $ 114 | */ 115 | private class PenIcon implements Icon { 116 | 117 | /** 118 | * Pen used in drawing. 119 | */ 120 | private int width = 0; 121 | 122 | /** 123 | * Strokes for this icon 124 | */ 125 | private Map strokes = new HashMap(); 126 | 127 | /** 128 | * @see javax.swing.Icon#getIconHeight() 129 | */ 130 | public int getIconHeight() { 131 | return getHeight(); 132 | } 133 | 134 | /** 135 | * @see javax.swing.Icon#getIconWidth() 136 | */ 137 | public int getIconWidth() { 138 | return ICON_WIDTH; 139 | } 140 | 141 | /** 142 | * @see javax.swing.Icon#paintIcon(java.awt.Component, java.awt.Graphics, int, int) 143 | */ 144 | public void paintIcon(Component c, Graphics g, int x, int y) { 145 | 146 | // Fill the background 147 | Graphics2D g2d = (Graphics2D) g; 148 | g2d.setColor(c.getBackground()); 149 | g2d.fillRect(x, y, getIconWidth(), getIconHeight()); 150 | 151 | // Draw a line centered in the foreground 152 | g2d.setColor(c.getForeground()); 153 | g2d.setStroke(strokes.get(width)); 154 | int yCentered = y + getIconHeight() / 2; 155 | g2d.drawLine(x, yCentered, x + getIconWidth(), yCentered); 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/PopupListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.event.MouseAdapter; 17 | import java.awt.event.MouseEvent; 18 | 19 | import javax.swing.JPopupMenu; 20 | 21 | /** 22 | */ 23 | public class PopupListener extends MouseAdapter { 24 | 25 | private JPopupMenu menu; 26 | 27 | public PopupListener(JPopupMenu menu) { 28 | this.menu = menu; 29 | } 30 | 31 | public void mousePressed(MouseEvent e) { 32 | maybeShowPopup(e); 33 | } 34 | 35 | public void mouseReleased(MouseEvent e) { 36 | maybeShowPopup(e); 37 | } 38 | 39 | private void maybeShowPopup(MouseEvent e) { 40 | if (e.isPopupTrigger()) { 41 | menu.show(e.getComponent(), 42 | e.getX(), e.getY()); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/PositionalLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Component; 17 | import java.awt.Container; 18 | import java.awt.Dimension; 19 | import java.awt.LayoutManager2; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | import javax.swing.JButton; 24 | import javax.swing.JFrame; 25 | import javax.swing.JPanel; 26 | 27 | /** 28 | */ 29 | public class PositionalLayout implements LayoutManager2 { 30 | 31 | public enum Position { 32 | 33 | NW, N, NE, W, CENTER, E, SW, S, SE 34 | } 35 | 36 | private int padding = 0; 37 | 38 | private Map compPositionMap = new HashMap(); 39 | 40 | public PositionalLayout() { 41 | } 42 | 43 | public PositionalLayout(int edgePadding) { 44 | padding = edgePadding; 45 | } 46 | 47 | public void addLayoutComponent(Component comp, Object constraints) { 48 | if (!(constraints instanceof Position)) { 49 | return; 50 | } 51 | 52 | compPositionMap.put(comp, (Position) constraints); 53 | } 54 | 55 | public void addLayoutComponent(String name, Component comp) { 56 | throw new IllegalArgumentException("Use add(comp, Position)"); 57 | } 58 | 59 | public float getLayoutAlignmentX(Container target) { 60 | return 0; 61 | } 62 | 63 | public float getLayoutAlignmentY(Container target) { 64 | return 0; 65 | } 66 | 67 | public void invalidateLayout(Container target) { 68 | // Nothing to do right now 69 | } 70 | 71 | public void layoutContainer(Container parent) { 72 | 73 | Dimension size = parent.getSize(); 74 | 75 | Component[] compArray = parent.getComponents(); 76 | for (Component comp : compArray) { 77 | 78 | Position pos = compPositionMap.get(comp); 79 | Dimension compSize = comp.getSize(); 80 | 81 | int x = 0; 82 | int y = 0; 83 | 84 | switch (pos) { 85 | case NW: { 86 | x = padding; 87 | y = padding; 88 | break; 89 | } 90 | case N: { 91 | x = center(size.width, compSize.width); 92 | y = padding; 93 | break; 94 | } 95 | case NE: { 96 | x = size.width - compSize.width - padding; 97 | y = padding; 98 | break; 99 | } 100 | case W: { 101 | x = padding; 102 | y = center(size.height, compSize.height); 103 | break; 104 | } 105 | case E: { 106 | x = size.width - compSize.width - padding; 107 | y = center(size.height, compSize.height); 108 | break; 109 | } 110 | case SW: { 111 | x = padding; 112 | y = size.height - compSize.height - padding; 113 | break; 114 | } 115 | case S: { 116 | x = center(size.width, compSize.width); 117 | y = size.height - compSize.height - padding; 118 | break; 119 | } 120 | case SE: { 121 | x = size.width - compSize.width - padding; 122 | y = size.height - compSize.height - padding; 123 | break; 124 | } 125 | case CENTER: { 126 | x = 0; 127 | y = 0; 128 | 129 | // Fill available space 130 | comp.setSize(size); 131 | } 132 | } 133 | 134 | comp.setLocation(x, y); 135 | } 136 | } 137 | 138 | private int center(int outsideWidth, int insideWidth) { 139 | return (outsideWidth - insideWidth) / 2; 140 | } 141 | 142 | public Dimension maximumLayoutSize(Container target) { 143 | return preferredLayoutSize(target); 144 | } 145 | 146 | public Dimension minimumLayoutSize(Container parent) { 147 | return preferredLayoutSize(parent); 148 | } 149 | 150 | public Dimension preferredLayoutSize(Container parent) { 151 | return new Dimension(0, 0); 152 | } 153 | 154 | public void removeLayoutComponent(Component comp) { 155 | 156 | compPositionMap.remove(comp); 157 | } 158 | 159 | public static void main(String[] args) { 160 | 161 | JFrame frame = new JFrame(); 162 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 163 | JPanel panel = new PositionalPanel(); 164 | 165 | panel.add(createButton("NW"), Position.NW); 166 | panel.add(createButton("N"), Position.N); 167 | panel.add(createButton("NE"), Position.NE); 168 | panel.add(createButton("W"), Position.W); 169 | panel.add(createButton("E"), Position.E); 170 | panel.add(createButton("SW"), Position.SW); 171 | panel.add(createButton("S"), Position.S); 172 | panel.add(createButton("SE"), Position.SE); 173 | panel.add(createButton("CENTER"), Position.CENTER); 174 | 175 | frame.setContentPane(panel); 176 | 177 | frame.setSize(200, 200); 178 | frame.setVisible(true); 179 | } 180 | 181 | private static JButton createButton(String label) { 182 | JButton button = new JButton(label); 183 | button.setSize(button.getMinimumSize()); 184 | 185 | return button; 186 | } 187 | } 188 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/PositionalPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Component; 17 | 18 | import javax.swing.JPanel; 19 | 20 | @SuppressWarnings("serial") 21 | public class PositionalPanel extends JPanel { 22 | 23 | public PositionalPanel() { 24 | setLayout(new PositionalLayout()); 25 | } 26 | 27 | public void addImpl(Component comp, Object constraints, int index) { 28 | 29 | if (!(constraints instanceof PositionalLayout.Position)) { 30 | throw new IllegalArgumentException("Use add(Component, PositionalLayout.Position)"); 31 | } 32 | 33 | super.addImpl(comp, constraints, index); 34 | 35 | if (((PositionalLayout.Position) constraints) == PositionalLayout.Position.CENTER) { 36 | 37 | setComponentZOrder(comp, getComponents().length - 1); 38 | } else { 39 | setComponentZOrder(comp, 0); 40 | } 41 | } 42 | 43 | /* (non-Javadoc) 44 | * @see javax.swing.JComponent#isOptimizedDrawingEnabled() 45 | */ 46 | public boolean isOptimizedDrawingEnabled() { 47 | return false; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/RoundedTitledPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Component; 17 | import java.awt.Container; 18 | import java.awt.Dimension; 19 | import java.awt.LayoutManager; 20 | 21 | import javax.swing.JPanel; 22 | 23 | @SuppressWarnings("serial") 24 | public class RoundedTitledPanel extends JPanel { 25 | 26 | public RoundedTitledPanel() { 27 | super.setLayout(new RoundedTitlePanelLayout()); 28 | } 29 | 30 | @Override 31 | public void setLayout(LayoutManager mgr) { 32 | throw new IllegalAccessError("Can't change the layout"); 33 | } 34 | 35 | private class RoundedTitlePanelLayout implements LayoutManager { 36 | 37 | public void addLayoutComponent(String name, Component comp) { 38 | 39 | } 40 | 41 | public void layoutContainer(Container parent) { 42 | } 43 | 44 | public Dimension minimumLayoutSize(Container parent) { 45 | return null; 46 | } 47 | 48 | public Dimension preferredLayoutSize(Container parent) { 49 | return null; 50 | } 51 | 52 | public void removeLayoutComponent(Component comp) { 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/SelectionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.util.List; 17 | 18 | public interface SelectionListener { 19 | 20 | public void selectionPerformed(List selectedList); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/TaskPanel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.BorderLayout; 17 | import java.awt.Color; 18 | import java.awt.Component; 19 | import java.awt.Dimension; 20 | import java.awt.Graphics; 21 | import java.awt.GridBagConstraints; 22 | import java.awt.GridBagLayout; 23 | import java.awt.event.MouseAdapter; 24 | import java.awt.event.MouseEvent; 25 | import java.io.IOException; 26 | 27 | import javax.swing.BorderFactory; 28 | import javax.swing.Icon; 29 | import javax.swing.ImageIcon; 30 | import javax.swing.JLabel; 31 | import javax.swing.JPanel; 32 | 33 | import net.rptools.lib.image.ImageUtil; 34 | /* 35 | * $Id: TaskPanel.java 5381 2010-09-07 17:17:26Z azhrei_fje $ 36 | * 37 | * Copyright (C) 2005, Digital Motorworks LP, a wholly owned subsidiary of ADP. 38 | * The contents of this file are protected under the copyright laws of the 39 | * United States of America with all rights reserved. This document is 40 | * confidential and contains proprietary information. Any unauthorized use or 41 | * disclosure is expressly prohibited. 42 | */ 43 | 44 | public class TaskPanel extends JPanel { 45 | 46 | private static final Color DEFAULT_TOP_COLOR = new Color(191, 197, 255); 47 | private static final Color DEFAULT_BOTTOM_COLOR = new Color(175, 185, 255); 48 | 49 | private Color topColor = DEFAULT_TOP_COLOR; 50 | private Color bottomColor = DEFAULT_BOTTOM_COLOR; 51 | 52 | public enum State { 53 | OPEN, CLOSED 54 | } 55 | 56 | public void setTopColor(Color color) { 57 | topColor = color; 58 | repaint(); 59 | } 60 | 61 | public void setBottomColor(Color color) { 62 | bottomColor = color; 63 | repaint(); 64 | } 65 | 66 | public static final String TASK_PANEL_STATE = "taskPanel.state"; 67 | 68 | private static Icon closeIcon; 69 | private static Icon openIcon; 70 | 71 | static { 72 | try { 73 | closeIcon = new ImageIcon(ImageUtil.getImage("net/rptools/lib/swing/image/collapse.png")); 74 | openIcon = new ImageIcon(ImageUtil.getImage("net/rptools/lib/swing/image/expand.png")); 75 | } catch (IOException ioe) { 76 | ioe.printStackTrace(); 77 | } 78 | } 79 | 80 | private State state; 81 | private JPanel contentPanel; 82 | private JLabel toggleButton; 83 | private String title; 84 | 85 | public TaskPanel(String title, Component component) { 86 | 87 | this.title = title; 88 | 89 | setLayout(new BorderLayout()); 90 | add(BorderLayout.NORTH, createTitlePanel(title)); 91 | add(BorderLayout.CENTER, getContentPanel(component)); 92 | 93 | setState(State.OPEN); 94 | } 95 | 96 | public String getTitle() { 97 | return title; 98 | } 99 | 100 | public void toggleState() { 101 | setState(state == State.OPEN ? State.CLOSED : State.OPEN); 102 | } 103 | 104 | public void setState(State state) { 105 | State oldState = this.state; 106 | this.state = state; 107 | contentPanel.setVisible(state == State.OPEN); 108 | toggleButton.setIcon(state != State.OPEN ? openIcon : closeIcon); 109 | 110 | firePropertyChange(TASK_PANEL_STATE, oldState, state); 111 | 112 | doLayout(); 113 | invalidate(); 114 | repaint(); 115 | } 116 | 117 | public boolean isOpen() { 118 | return state == State.OPEN; 119 | } 120 | 121 | public State getState() { 122 | return state; 123 | } 124 | 125 | private JPanel getContentPanel(Component component) { 126 | 127 | if (contentPanel == null) { 128 | contentPanel = new JPanel(new BorderLayout()); 129 | contentPanel.add(BorderLayout.CENTER, component); 130 | //contentPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 131 | 132 | } 133 | 134 | return contentPanel; 135 | } 136 | 137 | private JPanel createTitlePanel(String title) { 138 | 139 | //JPanel panel = new GradientPanel(new Color(0, 0, 100), Color.lightGray, new GridBagLayout()) { 140 | JPanel panel = new JPanel(new GridBagLayout()) { 141 | @Override 142 | protected void paintComponent(Graphics g) { 143 | super.paintComponent(g); 144 | 145 | Dimension size = getSize(); 146 | 147 | g.setColor(topColor); 148 | g.fillRect(0, 0, size.width, size.height / 2); 149 | 150 | //((Graphics2D)g).setPaint(new GradientPaint(0, size.height/2, TOP_COLOR, 0, size.height, BOTTOM_COLOR)); 151 | g.setColor(bottomColor); 152 | g.fillRect(0, size.height / 2, size.width, size.height / 2); 153 | 154 | g.setColor(Color.gray); 155 | g.drawLine(0, 0, size.width, 0); 156 | g.drawLine(0, 0, 0, size.height); 157 | g.drawLine(size.width - 1, 0, size.width - 1, size.height); 158 | g.drawLine(0, size.height - 1, size.width - 1, size.height - 1); 159 | 160 | } 161 | }; 162 | panel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); 163 | GridBagConstraints constraints = new GridBagConstraints(); 164 | 165 | constraints.gridx = 1; 166 | panel.add(createButtonPanel(), constraints); 167 | 168 | constraints.gridx = 0; 169 | constraints.weightx = 1; 170 | constraints.fill = GridBagConstraints.BOTH; 171 | 172 | JLabel titleLabel = new JLabel(title); 173 | panel.add(titleLabel, constraints); 174 | 175 | return panel; 176 | } 177 | 178 | private JPanel createButtonPanel() { 179 | 180 | JPanel panel = new JPanel(); 181 | panel.setOpaque(false); 182 | panel.add(getToggleButton()); 183 | 184 | return panel; 185 | } 186 | 187 | private JLabel getToggleButton() { 188 | if (toggleButton == null) { 189 | toggleButton = new JLabel(closeIcon); 190 | toggleButton.addMouseListener(new MouseAdapter() { 191 | public void mouseClicked(MouseEvent e) { 192 | toggleState(); 193 | } 194 | }); 195 | } 196 | 197 | return toggleButton; 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/TaskPanelGroup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing; 15 | 16 | import java.awt.Component; 17 | import java.awt.Container; 18 | import java.awt.Dimension; 19 | import java.awt.Insets; 20 | import java.awt.LayoutManager; 21 | import java.util.ArrayList; 22 | import java.util.Collections; 23 | import java.util.List; 24 | 25 | import javax.swing.BorderFactory; 26 | import javax.swing.Box; 27 | import javax.swing.JButton; 28 | import javax.swing.JComponent; 29 | import javax.swing.JFrame; 30 | import javax.swing.JPanel; 31 | /* 32 | * $Id: TaskPanelGroup.java 5381 2010-09-07 17:17:26Z azhrei_fje $ 33 | * 34 | * Copyright (C) 2005, Digital Motorworks LP, a wholly owned subsidiary of ADP. 35 | * The contents of this file are protected under the copyright laws of the 36 | * United States of America with all rights reserved. This document is 37 | * confidential and contains proprietary information. Any unauthorized use or 38 | * disclosure is expressly prohibited. 39 | */ 40 | 41 | @SuppressWarnings("serial") 42 | public class TaskPanelGroup extends JPanel { 43 | 44 | private int gap = 0; 45 | 46 | public static final String TASK_PANEL_LIST = "taskPanelGroup.panelList"; 47 | 48 | private List taskPanelList = new ArrayList(); 49 | 50 | public TaskPanelGroup() { 51 | this(0); 52 | } 53 | 54 | public TaskPanelGroup(int gap) { 55 | this.gap = gap; 56 | setLayout(new TaskPanelGroupLayout()); 57 | } 58 | 59 | public TaskPanel getTaskPanel(String title) { 60 | 61 | for (TaskPanel taskPanel : taskPanelList) { 62 | if (title.equals(taskPanel.getTitle())) { 63 | return taskPanel; 64 | } 65 | } 66 | 67 | return null; 68 | } 69 | 70 | @Override 71 | public Component add(String name, Component comp) { 72 | add(comp, name); 73 | return comp; 74 | } 75 | 76 | @Override 77 | public void add(Component comp, Object title) { 78 | if (!(title instanceof String)) { 79 | // LATER: Title should be able to handle any component 80 | throw new IllegalArgumentException("Must supply a string title"); 81 | } 82 | 83 | TaskPanel taskPanel = new TaskPanel((String) title, comp); 84 | firePropertyChange(TASK_PANEL_LIST, null, taskPanel); 85 | 86 | taskPanelList.add(taskPanel); 87 | add(taskPanel); 88 | } 89 | 90 | public List getTaskPanels() { 91 | return Collections.unmodifiableList(taskPanelList); 92 | } 93 | 94 | private class TaskPanelGroupLayout implements LayoutManager { 95 | 96 | public void addLayoutComponent(String name, Component comp) { 97 | } 98 | 99 | public void layoutContainer(Container parent) { 100 | 101 | Dimension size = getSize(); 102 | Insets insets = getInsets(); 103 | 104 | int heightRemaining = size.height - insets.bottom - insets.top; 105 | int openPanelCount = 0; 106 | 107 | TaskPanel lastPanel = null; 108 | for (Component comp : getComponents()) { 109 | if (!(comp instanceof TaskPanel)) { 110 | continue; 111 | } 112 | 113 | TaskPanel panel = (TaskPanel) comp; 114 | 115 | if (!panel.isOpen()) { 116 | heightRemaining -= panel.getPreferredSize().height; 117 | } else { 118 | openPanelCount++; 119 | heightRemaining -= gap; 120 | } 121 | 122 | lastPanel = panel; 123 | } 124 | 125 | // Add back the last gap 126 | if (lastPanel != null && lastPanel.isOpen()) { 127 | heightRemaining += gap; 128 | } 129 | 130 | int openSize = openPanelCount > 0 ? heightRemaining / openPanelCount : 0; 131 | int currentHeight = insets.top; 132 | 133 | for (Component comp : getComponents()) { 134 | if (!(comp instanceof TaskPanel)) { 135 | continue; 136 | } 137 | 138 | TaskPanel panel = (TaskPanel) comp; 139 | int height = panel.isOpen() ? openSize : panel.getPreferredSize().height; 140 | panel.setSize(size.width - insets.left - insets.right, height); 141 | panel.setLocation(insets.left, currentHeight); 142 | 143 | currentHeight += height; 144 | if (panel.isOpen()) { 145 | currentHeight += gap; 146 | } 147 | } 148 | } 149 | 150 | public Dimension minimumLayoutSize(Container parent) { 151 | 152 | int width = 0; 153 | int height = 0; 154 | 155 | for (Component comp : getComponents()) { 156 | 157 | Dimension size = comp.getMinimumSize(); 158 | if (size.width > width) { 159 | width = size.width; 160 | } 161 | 162 | height += size.height; 163 | } 164 | 165 | return new Dimension(width, height); 166 | } 167 | 168 | public Dimension preferredLayoutSize(Container parent) { 169 | int width = 0; 170 | int height = 0; 171 | 172 | for (Component comp : getComponents()) { 173 | 174 | Dimension size = comp.getPreferredSize(); 175 | if (size.width > width) { 176 | width = size.width; 177 | } 178 | 179 | height += size.height; 180 | } 181 | 182 | return new Dimension(width, height); 183 | } 184 | 185 | public void removeLayoutComponent(Component comp) { 186 | } 187 | } 188 | 189 | public static void main(String[] args) { 190 | 191 | JFrame f = new JFrame(); 192 | f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 193 | 194 | TaskPanelGroup group = new TaskPanelGroup(5); 195 | group.add(new TaskPanel("Testing", new JButton("Hello World"))); 196 | group.add(Box.createHorizontalGlue()); 197 | group.add(new TaskPanel("Testing 2", new JButton("Hello World2"))); 198 | group.add(Box.createHorizontalGlue()); 199 | group.add(new TaskPanel("Testing 2", new JButton("Hello World2"))); 200 | group.add(Box.createHorizontalGlue()); 201 | 202 | ((JComponent) f.getContentPane()).setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 203 | f.add(group); 204 | f.pack(); 205 | SwingUtil.centerOnScreen(f); 206 | 207 | f.setVisible(true); 208 | 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/preference/SplitPanePreferences.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing.preference; 15 | 16 | import java.beans.PropertyChangeEvent; 17 | import java.beans.PropertyChangeListener; 18 | import java.util.prefs.Preferences; 19 | 20 | import javax.swing.JSplitPane; 21 | 22 | public class SplitPanePreferences implements PropertyChangeListener { 23 | 24 | private JSplitPane splitPane; 25 | private Preferences prefs; 26 | 27 | private static final String PREF_LOCATION_KEY = "location"; 28 | 29 | public SplitPanePreferences(String appName, String controlName, JSplitPane splitPane) { 30 | this.splitPane = splitPane; 31 | 32 | prefs = Preferences.userRoot().node(appName + "/control/" + controlName); 33 | 34 | splitPane.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, this); 35 | 36 | restorePreferences(); 37 | } 38 | 39 | private void restorePreferences() { 40 | 41 | int position = prefs.getInt(PREF_LOCATION_KEY, -1); 42 | if (position == -1) { 43 | // First time usage, don't change the position of the split pane 44 | return; 45 | } 46 | 47 | splitPane.setDividerLocation(position); 48 | } 49 | 50 | private void savePreferences() { 51 | 52 | prefs.putInt(PREF_LOCATION_KEY, splitPane.getDividerLocation()); 53 | } 54 | 55 | //// 56 | // PROPERTY CHANGE LISTENER 57 | public void propertyChange(PropertyChangeEvent evt) { 58 | savePreferences(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/preference/TaskPanelGroupPreferences.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing.preference; 15 | 16 | import java.beans.PropertyChangeEvent; 17 | import java.beans.PropertyChangeListener; 18 | import java.util.ArrayList; 19 | import java.util.Arrays; 20 | import java.util.Iterator; 21 | import java.util.List; 22 | import java.util.prefs.Preferences; 23 | 24 | import net.rptools.lib.swing.TaskPanel; 25 | import net.rptools.lib.swing.TaskPanelGroup; 26 | 27 | public class TaskPanelGroupPreferences implements PropertyChangeListener { 28 | 29 | private TaskPanelGroup group; 30 | 31 | private Preferences prefs; 32 | private boolean restoringState; // I don't like this, rethink it later. 33 | 34 | private static final String PREF_KEY = "state_list"; 35 | 36 | public TaskPanelGroupPreferences(String appName, String controlName, TaskPanelGroup group) { 37 | this.group = group; 38 | 39 | prefs = Preferences.userRoot().node(appName + "/control/" + controlName); 40 | 41 | restoreTaskPanelStates(); 42 | connect(); 43 | } 44 | 45 | protected void connect() { 46 | 47 | for (TaskPanel taskPanel : group.getTaskPanels()) { 48 | connectToTaskPanel(taskPanel); 49 | } 50 | 51 | // Make sure to get all future task panels 52 | group.addPropertyChangeListener(TaskPanelGroup.TASK_PANEL_LIST, this); 53 | } 54 | 55 | private void connectToTaskPanel(TaskPanel taskPanel) { 56 | 57 | taskPanel.addPropertyChangeListener(TaskPanel.TASK_PANEL_STATE, this); 58 | } 59 | 60 | public void disconnect() { 61 | 62 | group.removePropertyChangeListener(TaskPanelGroup.TASK_PANEL_LIST, this); 63 | 64 | for (TaskPanel taskPanel : group.getTaskPanels()) { 65 | disconnectFromTaskPanel(taskPanel); 66 | } 67 | 68 | group = null; 69 | prefs = null; 70 | } 71 | 72 | private void disconnectFromTaskPanel(TaskPanel taskPanel) { 73 | 74 | taskPanel.removePropertyChangeListener(TaskPanel.TASK_PANEL_STATE, this); 75 | } 76 | 77 | private void saveTaskPanelStates() { 78 | 79 | List stateList = new ArrayList(); 80 | 81 | for (TaskPanel taskPanel : group.getTaskPanels()) { 82 | stateList.add(taskPanel.getTitle()); 83 | stateList.add(taskPanel.getState().name()); 84 | } 85 | 86 | saveStates(stateList); 87 | } 88 | 89 | private void restoreTaskPanelState(TaskPanel taskPanel) { 90 | 91 | List states = loadStates(); 92 | 93 | try { 94 | restoringState = true; 95 | for (Iterator iter = states.iterator(); iter.hasNext();) { 96 | 97 | String title = iter.next(); 98 | String state = iter.next(); 99 | 100 | if (taskPanel.getTitle().equals(title)) { 101 | taskPanel.setState(TaskPanel.State.valueOf(state)); 102 | break; 103 | } 104 | } 105 | } catch (Exception e) { 106 | e.printStackTrace(); 107 | } finally { 108 | restoringState = false; 109 | } 110 | } 111 | 112 | private void restoreTaskPanelStates() { 113 | 114 | List states = loadStates(); 115 | 116 | try { 117 | restoringState = true; 118 | for (Iterator iter = states.iterator(); iter.hasNext();) { 119 | 120 | String title = iter.next(); 121 | String state = iter.next(); 122 | 123 | TaskPanel taskPanel = group.getTaskPanel(title); 124 | 125 | if (taskPanel == null) { 126 | continue; 127 | } 128 | 129 | taskPanel.setState(TaskPanel.State.valueOf(state)); 130 | } 131 | } catch (Exception e) { 132 | e.printStackTrace(); 133 | } finally { 134 | restoringState = false; 135 | } 136 | } 137 | 138 | private List loadStates() { 139 | 140 | String stateList = prefs.get(PREF_KEY, null); 141 | if (stateList == null) { 142 | return new ArrayList(); 143 | } 144 | 145 | String[] states = stateList.split("\\|"); 146 | 147 | return Arrays.asList(states); 148 | } 149 | 150 | private void saveStates(List stateList) { 151 | 152 | StringBuilder builder = new StringBuilder(); 153 | for (Iterator iter = stateList.iterator(); iter.hasNext();) { 154 | builder.append(iter.next()).append("|").append(iter.next()); 155 | if (iter.hasNext()) { 156 | builder.append("|"); 157 | } 158 | } 159 | 160 | prefs.put(PREF_KEY, builder.toString()); 161 | } 162 | 163 | //// 164 | // PROPERTY CHANGE LISTENER 165 | public void propertyChange(PropertyChangeEvent evt) { 166 | 167 | if (restoringState) { 168 | return; 169 | } 170 | 171 | if (TaskPanelGroup.TASK_PANEL_LIST.equals(evt.getPropertyName())) { 172 | TaskPanel taskPanel = (TaskPanel) evt.getNewValue(); 173 | connectToTaskPanel(taskPanel); 174 | restoreTaskPanelState(taskPanel); 175 | } else { 176 | 177 | saveTaskPanelStates(); 178 | } 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/preference/TreePreferences.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing.preference; 15 | 16 | import java.awt.EventQueue; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | import java.util.StringTokenizer; 20 | import java.util.prefs.Preferences; 21 | 22 | import javax.swing.JTree; 23 | import javax.swing.event.TreeSelectionEvent; 24 | import javax.swing.event.TreeSelectionListener; 25 | import javax.swing.tree.TreePath; 26 | 27 | public class TreePreferences implements TreeSelectionListener { 28 | private final JTree tree; 29 | private final Preferences prefs; 30 | private static final String PREF_PATH_KEY = "path"; 31 | private static final String PATH_DELIMITER = "|"; 32 | 33 | public TreePreferences(String appName, String controlName, JTree tree) { 34 | this.tree = tree; 35 | 36 | prefs = Preferences.userRoot().node(appName + "/control/" + controlName); 37 | tree.getSelectionModel().addTreeSelectionListener(this); 38 | 39 | // Wait until the UI has been built to do this 40 | EventQueue.invokeLater(new Runnable() { 41 | public void run() { 42 | restorePreferences(); 43 | } 44 | }); 45 | } 46 | 47 | private void restorePreferences() { 48 | String path = prefs.get(PREF_PATH_KEY, ""); 49 | if (path == null || path.length() == 0) { 50 | // First time usage 51 | return; 52 | } 53 | StringTokenizer strtok = new StringTokenizer(path, PATH_DELIMITER); 54 | List pathList = new ArrayList(); 55 | pathList.add(tree.getModel().getRoot()); 56 | Object currentStep = tree.getModel().getRoot(); 57 | 58 | while (strtok.hasMoreElements()) { 59 | boolean found = false; 60 | String nextStep = strtok.nextToken(); 61 | for (int i = 0; i < tree.getModel().getChildCount(currentStep); i++) { 62 | Object element = tree.getModel().getChild(currentStep, i); 63 | if (element != null && element.toString().equals(nextStep)) { 64 | pathList.add(element); 65 | currentStep = element; 66 | found = true; 67 | break; 68 | } 69 | } 70 | if (!found) { 71 | break; 72 | } 73 | } 74 | if (pathList.size() > 0) { 75 | TreePath treePath = new TreePath(pathList.toArray()); 76 | tree.expandPath(treePath); 77 | tree.setSelectionPath(treePath); 78 | } 79 | } 80 | 81 | private void savePreferences() { 82 | StringBuilder builder = new StringBuilder(); 83 | TreePath path = tree.getSelectionPath(); 84 | if (path == null) { 85 | return; 86 | } 87 | for (int i = 0; i < path.getPathCount(); i++) { 88 | Object o = path.getPathComponent(i); 89 | 90 | builder.append(o).append(PATH_DELIMITER); 91 | } 92 | if (builder.length() > 0) { 93 | // Kill the last delimiter 94 | builder.setLength(builder.length() - 1); 95 | } 96 | String composedPath = builder.toString(); 97 | if (composedPath.startsWith(PATH_DELIMITER)) { 98 | composedPath = composedPath.substring(1); 99 | } 100 | prefs.put(PREF_PATH_KEY, composedPath); 101 | } 102 | 103 | //// 104 | // TREE SELECTION LISTENER 105 | public void valueChanged(TreeSelectionEvent e) { 106 | savePreferences(); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/swing/preference/WindowPreferences.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.swing.preference; 15 | 16 | import java.awt.Dimension; 17 | import java.awt.Toolkit; 18 | import java.awt.Window; 19 | import java.awt.event.WindowAdapter; 20 | import java.awt.event.WindowEvent; 21 | import java.util.prefs.BackingStoreException; 22 | import java.util.prefs.Preferences; 23 | 24 | /** 25 | * Automatically keeps track of and restores frame size when opening/closing 26 | * the application. 27 | * 28 | * To use, simply add a line like this to you frame's constructor: 29 | * 30 | * new WindowPreferences(appName, identifier, this); 31 | */ 32 | public class WindowPreferences extends WindowAdapter { 33 | private final Preferences prefs; 34 | 35 | private static final String KEY_X = "x"; 36 | private static final String KEY_Y = "y"; 37 | private static final String KEY_WIDTH = "width"; 38 | private static final String KEY_HEIGHT = "height"; 39 | 40 | private static int DEFAULT_X; 41 | private static int DEFAULT_Y; 42 | private static int DEFAULT_WIDTH; 43 | private static int DEFAULT_HEIGHT; 44 | 45 | /** 46 | * Creates an object that holds the window boundary information after storing it into 47 | * {@link Preferences#userRoot()}. This object also registers a WindowListener on the 48 | * passed in Window object so that it is notified when the window is closed, 49 | * allowing this object to save the final window boundary into Preferences again. 50 | * 51 | * @param appName top-level name to use in the Preferences 52 | * @param controlName bottom level name to use 53 | * @param window the window whose boundary information is being recorded 54 | */ 55 | public WindowPreferences(String appName, String controlName, Window window) { 56 | prefs = Preferences.userRoot().node(appName + "/control/" + controlName); 57 | 58 | DEFAULT_X = window.getLocation().x; 59 | DEFAULT_Y = window.getLocation().y; 60 | DEFAULT_WIDTH = window.getSize().width; 61 | DEFAULT_HEIGHT = window.getSize().height; 62 | 63 | restorePreferences(window); 64 | window.addWindowListener(this); 65 | } 66 | 67 | /** 68 | * Clear out window preferences from the user's system 69 | */ 70 | public void clear() { 71 | try { 72 | prefs.clear(); 73 | } catch (BackingStoreException bse) { 74 | // This error shouldn't matter, really, 75 | // since it is an asthetic action 76 | bse.printStackTrace(); 77 | } 78 | } 79 | 80 | //// 81 | // Preferences 82 | 83 | protected int getX() { 84 | return prefs.getInt(KEY_X, DEFAULT_X); 85 | } 86 | 87 | protected void setX(int x) { 88 | prefs.putInt(KEY_X, x); 89 | } 90 | 91 | protected int getY() { 92 | return prefs.getInt(KEY_Y, DEFAULT_Y); 93 | } 94 | 95 | protected void setY(int y) { 96 | prefs.putInt(KEY_Y, y); 97 | } 98 | 99 | protected int getWidth() { 100 | return prefs.getInt(KEY_WIDTH, DEFAULT_WIDTH); 101 | } 102 | 103 | protected void setWidth(int width) { 104 | prefs.putInt(KEY_WIDTH, width); 105 | } 106 | 107 | protected int getHeight() { 108 | return prefs.getInt(KEY_HEIGHT, DEFAULT_HEIGHT); 109 | } 110 | 111 | protected void setHeight(int height) { 112 | prefs.putInt(KEY_HEIGHT, height); 113 | } 114 | 115 | protected void storePreferences(Window frame) { 116 | setX(frame.getLocation().x); 117 | setY(frame.getLocation().y); 118 | 119 | setWidth(frame.getSize().width); 120 | setHeight(frame.getSize().height); 121 | } 122 | 123 | protected void restorePreferences(Window frame) { 124 | Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 125 | 126 | int x = Math.max(Math.min(getX(), screenSize.width - getWidth()), 0); 127 | int y = Math.max(Math.min(getY(), screenSize.height - getHeight()), 0); 128 | 129 | frame.setSize(getWidth(), getHeight()); 130 | frame.setLocation(x, y); 131 | } 132 | 133 | //// 134 | // WINDOW ADAPTER 135 | @Override 136 | public final void windowClosing(WindowEvent e) { 137 | storePreferences((Window) e.getSource()); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/tool/DropTargetInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package net.rptools.lib.tool; 16 | 17 | import java.awt.datatransfer.DataFlavor; 18 | import java.awt.dnd.DnDConstants; 19 | import java.awt.dnd.DropTarget; 20 | import java.awt.dnd.DropTargetDragEvent; 21 | import java.awt.dnd.DropTargetDropEvent; 22 | import java.awt.dnd.DropTargetEvent; 23 | import java.awt.dnd.DropTargetListener; 24 | 25 | import javax.swing.ImageIcon; 26 | import javax.swing.JFrame; 27 | import javax.swing.JLabel; 28 | 29 | import net.rptools.lib.transferable.ImageTransferableHandler; 30 | 31 | /** 32 | * This class will show a frame that accepts system drag-and-drop events 33 | * it is a discovery tool useful to determine which flavors a drop from a specific application 34 | * supports (such as a browser) 35 | */ 36 | @SuppressWarnings("serial") 37 | public class DropTargetInfo extends JFrame implements DropTargetListener { 38 | JLabel label = new JLabel("Drop here"); 39 | 40 | public DropTargetInfo() { 41 | super("Drag and drop into this window"); 42 | setDefaultCloseOperation(EXIT_ON_CLOSE); 43 | setLocation(300, 200); 44 | setSize(200, 200); 45 | 46 | new DropTarget(this, this); 47 | 48 | add(label); 49 | } 50 | 51 | public static void main(String[] args) { 52 | DropTargetInfo dti = new DropTargetInfo(); 53 | dti.setVisible(true); 54 | } 55 | 56 | //// 57 | // DROP TARGET LISTENER 58 | public void dragEnter(DropTargetDragEvent dtde) { 59 | } 60 | 61 | public void dragExit(DropTargetEvent dte) { 62 | } 63 | 64 | public void dragOver(DropTargetDragEvent dtde) { 65 | } 66 | 67 | public void drop(DropTargetDropEvent dtde) { 68 | dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); 69 | 70 | @SuppressWarnings("unused") 71 | Object handlerObj = null; 72 | try { 73 | handlerObj = new ImageTransferableHandler().getTransferObject(dtde.getTransferable()); 74 | 75 | System.out.println("DropAction:" + dtde.getDropAction()); 76 | System.out.println("Source:" + dtde.getSource()); 77 | System.out.println("DropTargetContext:" + dtde.getDropTargetContext()); 78 | System.out.println("Data Flavors:"); 79 | for (DataFlavor flavor : dtde.getCurrentDataFlavorsAsList()) { 80 | try { 81 | System.out.println("\t" + flavor.getMimeType()); 82 | } catch (Exception e) { 83 | System.out.println("\t\tfailed"); 84 | } 85 | } 86 | System.out.println("--------------------"); 87 | label.setIcon(new ImageIcon(new ImageTransferableHandler().getTransferObject(dtde.getTransferable()))); 88 | } catch (Exception e) { 89 | e.printStackTrace(); 90 | } 91 | } 92 | 93 | public void dropActionChanged(DropTargetDragEvent dtde) { 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/transferable/FileListTransferable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.transferable; 15 | 16 | import java.awt.datatransfer.DataFlavor; 17 | import java.awt.datatransfer.Transferable; 18 | import java.awt.datatransfer.UnsupportedFlavorException; 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.util.LinkedList; 22 | import java.util.List; 23 | 24 | public class FileListTransferable implements Transferable { 25 | 26 | public static final DataFlavor FLAVOR = new DataFlavor("application/x-java-file-list;class=java.util.List", null); 27 | 28 | private List fileList; 29 | 30 | public FileListTransferable(List fileList) { 31 | this.fileList = fileList; 32 | } 33 | 34 | public FileListTransferable(File file) { 35 | fileList = new LinkedList(); 36 | fileList.add(file); 37 | } 38 | 39 | public DataFlavor[] getTransferDataFlavors() { 40 | return new DataFlavor[] { FLAVOR }; 41 | } 42 | 43 | public boolean isDataFlavorSupported(DataFlavor flavor) { 44 | return flavor.equals(FLAVOR); 45 | } 46 | 47 | public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 48 | 49 | if (!flavor.equals(FLAVOR)) { 50 | throw new UnsupportedFlavorException(flavor); 51 | } 52 | 53 | return fileList; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/transferable/FileTransferableHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.transferable; 15 | 16 | import java.awt.datatransfer.DataFlavor; 17 | import java.awt.datatransfer.Transferable; 18 | import java.awt.datatransfer.UnsupportedFlavorException; 19 | import java.io.File; 20 | import java.io.IOException; 21 | import java.net.URL; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | public class FileTransferableHandler extends TransferableHandler { 26 | private static final DataFlavor fileList = DataFlavor.javaFileListFlavor; 27 | 28 | @Override 29 | public List getTransferObject(Transferable transferable) throws IOException, UnsupportedFlavorException { 30 | if (transferable.isDataFlavorSupported(fileList)) { 31 | @SuppressWarnings("unchecked") 32 | List files = (List) transferable.getTransferData(fileList); 33 | List urls = new ArrayList(files.size()); 34 | for (File file : files) 35 | urls.add(file.toURI().toURL()); 36 | return urls; 37 | } 38 | throw new UnsupportedFlavorException(null); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/transferable/GroupTokenTransferData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package net.rptools.lib.transferable; 16 | 17 | import java.awt.datatransfer.DataFlavor; 18 | import java.util.ArrayList; 19 | 20 | /** 21 | * A list of token transfer data that came from the Group Tool. Need to specify app in the class 22 | * so that drag and drop functionality can check the mime type to see if it supports tokens from 23 | * that particular app. 24 | * 25 | * @author jgorrell 26 | * @version $Revision$ $Date$ $Author$ 27 | */ 28 | @SuppressWarnings("serial") 29 | public class GroupTokenTransferData extends ArrayList { 30 | /** 31 | * The data flavor that describes a list of tokens for exporting to maptool. 32 | */ 33 | public final static DataFlavor GROUP_TOKEN_LIST_FLAVOR = new DataFlavor(GroupTokenTransferData.class, "Group Tool Token List"); 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/transferable/ImageTransferable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.transferable; 15 | 16 | import java.awt.Image; 17 | import java.awt.datatransfer.DataFlavor; 18 | import java.awt.datatransfer.Transferable; 19 | import java.awt.datatransfer.UnsupportedFlavorException; 20 | import java.io.IOException; 21 | 22 | public class ImageTransferable implements Transferable { 23 | 24 | public static final DataFlavor FLAVOR = new DataFlavor("image/x-java-image; class=java.awt.Image", "Image"); 25 | 26 | private Image image; 27 | 28 | public ImageTransferable(Image image) { 29 | this.image = image; 30 | } 31 | 32 | public DataFlavor[] getTransferDataFlavors() { 33 | return new DataFlavor[] { FLAVOR }; 34 | } 35 | 36 | public boolean isDataFlavorSupported(DataFlavor flavor) { 37 | return flavor.equals(FLAVOR); 38 | } 39 | 40 | public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { 41 | 42 | if (!flavor.equals(FLAVOR)) { 43 | throw new UnsupportedFlavorException(flavor); 44 | } 45 | 46 | return image; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/transferable/ImageTransferableHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.transferable; 15 | 16 | import java.awt.Image; 17 | import java.awt.MediaTracker; 18 | import java.awt.Toolkit; 19 | import java.awt.datatransfer.DataFlavor; 20 | import java.awt.datatransfer.Transferable; 21 | import java.awt.datatransfer.UnsupportedFlavorException; 22 | import java.awt.image.BufferedImage; 23 | import java.io.File; 24 | import java.io.IOException; 25 | import java.net.MalformedURLException; 26 | import java.net.URL; 27 | import java.util.List; 28 | 29 | import javax.imageio.ImageIO; 30 | import javax.swing.JPanel; 31 | 32 | import net.rptools.lib.image.ImageUtil; 33 | 34 | public class ImageTransferableHandler extends TransferableHandler { 35 | private enum Flavor { 36 | image(new DataFlavor("image/x-java-image; class=java.awt.Image", "Image")), url(new DataFlavor("text/plain; class=java.lang.String", "Image")); 37 | 38 | DataFlavor flavor; 39 | 40 | private Flavor(DataFlavor flavor) { 41 | this.flavor = flavor; 42 | } 43 | 44 | public DataFlavor getFlavor() { 45 | return flavor; 46 | } 47 | } 48 | 49 | @Override 50 | public Image getTransferObject(Transferable transferable) throws IOException, UnsupportedFlavorException { 51 | if (transferable.isDataFlavorSupported(Flavor.image.getFlavor())) { 52 | Image image = (Image) transferable.getTransferData(Flavor.image.getFlavor()); 53 | 54 | if (!(image instanceof BufferedImage)) { 55 | image = ImageUtil.createCompatibleImage(image); 56 | } 57 | return image; 58 | } 59 | 60 | if (transferable.isDataFlavorSupported(Flavor.url.getFlavor())) { 61 | String urlStr = (String) transferable.getTransferData(Flavor.url.getFlavor()); 62 | 63 | try { 64 | URL url = new URL(urlStr); 65 | Image image = null; 66 | try { 67 | image = ImageIO.read(url); 68 | } catch (Exception e) { 69 | // try the old fasioned way 70 | image = Toolkit.getDefaultToolkit().getImage(url); 71 | MediaTracker mt = new MediaTracker(new JPanel()); 72 | mt.addImage(image, 0); 73 | try { 74 | mt.waitForID(0); 75 | } catch (InterruptedException ie) { 76 | ie.printStackTrace(); 77 | } 78 | } 79 | if (!(image instanceof BufferedImage)) { 80 | image = ImageUtil.createCompatibleImage(image); 81 | } 82 | return image; 83 | } catch (MalformedURLException mue) { 84 | // TODO: this can probably be ignored 85 | mue.printStackTrace(); 86 | } 87 | } 88 | if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { 89 | @SuppressWarnings("unchecked") 90 | List fileList = (List) transferable.getTransferData(DataFlavor.javaFileListFlavor); 91 | return ImageUtil.getImage(fileList.get(0)); 92 | } 93 | throw new UnsupportedFlavorException(null); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/transferable/MapToolTokenTransferData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package net.rptools.lib.transferable; 16 | 17 | import java.awt.datatransfer.DataFlavor; 18 | import java.util.ArrayList; 19 | 20 | /** 21 | * A list of token transfer data that came from the Map Tool. Need to specify app in the class 22 | * so that drag and drop functionality can check the mime type to see if it supports tokens from 23 | * that particular app. 24 | * 25 | * @author jgorrell 26 | * @version $Revision$ $Date$ $Author$ 27 | */ 28 | @SuppressWarnings("serial") 29 | public class MapToolTokenTransferData extends ArrayList { 30 | /** 31 | * The data flavor that describes a list of tokens for exporting to maptool. 32 | */ 33 | public final static DataFlavor MAP_TOOL_TOKEN_LIST_FLAVOR = new DataFlavor(MapToolTokenTransferData.class, "Map Tool Token List"); 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/transferable/TokenTransferData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | 15 | package net.rptools.lib.transferable; 16 | 17 | import java.awt.Point; 18 | import java.io.Serializable; 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | import java.util.Set; 22 | 23 | import javax.swing.ImageIcon; 24 | 25 | import net.rptools.lib.MD5Key; 26 | 27 | /** 28 | * Class used to transfer token information between applications. Used in Drag & Drop. Some properties are shared 29 | * between applications, and some are specific. Those specific properties are stored in the map with a key that 30 | * indicates what app owns that data. 31 | * 32 | * @author jgorrell 33 | * @version $Revision$ $Date$ $Author$ 34 | */ 35 | public class TokenTransferData extends HashMapimplements Serializable { 36 | 37 | /*--------------------------------------------------------------------------------------------- 38 | * Instance Variables 39 | *-------------------------------------------------------------------------------------------*/ 40 | 41 | /** Name of the token. */ 42 | private String name; 43 | 44 | /** The image used to display the token. An image icon is used because it is serializable */ 45 | private ImageIcon token; 46 | 47 | /** The players that own this token. When null there are no owners */ 48 | private Set players; 49 | 50 | /** Flag indicating if this token is visible to players */ 51 | private boolean isVisible; 52 | 53 | /** Location of the token on the map. These may be cell coordinates or map coordinates **/ 54 | private Point location; 55 | 56 | /** The facing of the token on the map. A null value indicates no facing */ 57 | private Integer facing; 58 | 59 | /*--------------------------------------------------------------------------------------------- 60 | * Class Variables 61 | *-------------------------------------------------------------------------------------------*/ 62 | 63 | /** Prefix for all values that are used by map tool */ 64 | public final static String MAPTOOL = "maptool:"; 65 | 66 | /** Maptool's token id key. The value is an String that can be used to create a GUID */ 67 | public final static String ID = MAPTOOL + "id"; 68 | 69 | /** Maptool's Z-order key. The value is an {@link MD5Key} used to identify an asset. */ 70 | public final static String ASSET_ID = MAPTOOL + "assetId"; 71 | 72 | /** Maptool's Z-order key. The value is an Integer. */ 73 | public final static String Z = MAPTOOL + "z"; 74 | 75 | /** Maptool's snap to scale key. The value is a Boolean. */ 76 | public final static String SNAP_TO_SCALE = MAPTOOL + "snapToScale"; 77 | 78 | /** Maptool's token width key. The value is an Integer. */ 79 | public final static String WIDTH = MAPTOOL + "width"; 80 | 81 | /** Maptool's token height key. The value is an Integer. */ 82 | public final static String HEIGHT = MAPTOOL + "height"; 83 | 84 | /** 85 | * Maptool's snap to grid key. Tells if x,y are cell or zone coordinates. The value is a Boolean. 86 | */ 87 | public final static String SNAP_TO_GRID = MAPTOOL + "snapToGrid"; 88 | 89 | /** 90 | * Maptool's owned by all or just by list key. The value is an Integer. The value 0 means that the 91 | * token is owned by all, the value 1 indicates that the owners are specified in the OWNER_LIST 92 | * property. 93 | */ 94 | public final static String OWNER_TYPE = MAPTOOL + "ownerType"; 95 | 96 | /** 97 | * The setting of the token's VisibleOnlyToOwner flag. 98 | */ 99 | public final static String VISIBLE_OWNER_ONLY = MAPTOOL + "visibleOnlyToOwner"; 100 | 101 | /** 102 | * Maptool's type of token used by facing or stamping key. The value is a String containing the name of 103 | * a Type enumeration value. 104 | */ 105 | public final static String TOKEN_TYPE = MAPTOOL + "tokenType"; 106 | 107 | /** Maptool's notes for all key. The value is a String. */ 108 | public final static String NOTES = MAPTOOL + "notes"; 109 | 110 | /** Maptool's notes for GM key. The value is a String. */ 111 | public final static String GM_NOTES = MAPTOOL + "gmNotes"; 112 | 113 | /** Maptool's name for GM key. The value is a String. */ 114 | public final static String GM_NAME = MAPTOOL + "gmName"; 115 | 116 | /** Maptool's name for the portrait. The value is an {@link ImageIcon}. */ 117 | public final static String PORTRAIT = MAPTOOL + "portrait"; 118 | 119 | /** Maptool's name for the portrait. The value is an {@link Map}. */ 120 | public final static String MACROS = MAPTOOL + "macros"; 121 | 122 | /** Serial version id to hide changes during transfer */ 123 | private static final long serialVersionUID = -1838917777325573062L; 124 | 125 | /*--------------------------------------------------------------------------------------------- 126 | * Instance Methods 127 | *-------------------------------------------------------------------------------------------*/ 128 | 129 | /** @return Getter for isVisible */ 130 | public boolean isVisible() { 131 | return isVisible; 132 | } 133 | 134 | /** 135 | * @param aIsVisible 136 | * Setter for isVisible 137 | */ 138 | public void setVisible(boolean aIsVisible) { 139 | isVisible = aIsVisible; 140 | } 141 | 142 | /** @return Getter for name */ 143 | public String getName() { 144 | return name; 145 | } 146 | 147 | /** 148 | * @param aName 149 | * Setter for name 150 | */ 151 | public void setName(String aName) { 152 | name = aName; 153 | } 154 | 155 | /** @return Getter for players */ 156 | public Set getPlayers() { 157 | return players; 158 | } 159 | 160 | /** 161 | * @param aPlayers 162 | * Setter for players 163 | */ 164 | public void setPlayers(Set aPlayers) { 165 | players = aPlayers; 166 | } 167 | 168 | /** @return Getter for token */ 169 | public ImageIcon getToken() { 170 | return token; 171 | } 172 | 173 | /** 174 | * @param aToken 175 | * Setter for token 176 | */ 177 | public void setToken(ImageIcon aToken) { 178 | token = aToken; 179 | } 180 | 181 | /** @return Getter for facing */ 182 | public Integer getFacing() { 183 | return facing; 184 | } 185 | 186 | /** 187 | * @param aFacing 188 | * Setter for facing 189 | */ 190 | public void setFacing(Integer aFacing) { 191 | facing = aFacing; 192 | } 193 | 194 | /** @return Getter for location */ 195 | public Point getLocation() { 196 | return location; 197 | } 198 | 199 | /** 200 | * @param aLocation 201 | * Setter for location 202 | */ 203 | public void setLocation(Point aLocation) { 204 | location = aLocation; 205 | } 206 | } -------------------------------------------------------------------------------- /src/main/java/net/rptools/lib/transferable/TransferableHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 3 | * use this file except in compliance with the License. You may obtain a copy of 4 | * the License at 5 | * 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 10 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 11 | * License for the specific language governing permissions and limitations under 12 | * the License. 13 | */ 14 | package net.rptools.lib.transferable; 15 | 16 | import java.awt.datatransfer.Transferable; 17 | import java.awt.datatransfer.UnsupportedFlavorException; 18 | import java.io.IOException; 19 | 20 | public abstract class TransferableHandler { 21 | 22 | public abstract Object getTransferObject(Transferable transferable) throws IOException, UnsupportedFlavorException; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/contrast_high.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/contrast_high.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/cross.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/eraser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/eraser.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/freehand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/freehand.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/freehand2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/freehand2.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/paintbrush.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/paintbrush.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/paintcan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/paintcan.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/palette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/palette.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/pencil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/pencil.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/pencil_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/pencil_add.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/pencil_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/pencil_delete.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/round_cap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/round_cap.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/round_cap2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/round_cap2.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/shape_handles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/shape_handles.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/shape_handles2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/shape_handles2.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/shape_no_handles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/shape_no_handles.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/square_cap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/square_cap.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/square_cap2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/square_cap2.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/transparent.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/icons/transparent2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/icons/transparent2.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/jide_logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/jide_logo_small.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/image/rptools-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/image/rptools-logo.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/blue/bl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/blue/bl.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/blue/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/blue/bottom.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/blue/br.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/blue/br.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/blue/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/blue/left.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/blue/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/blue/right.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/blue/tl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/blue/tl.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/blue/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/blue/top.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/blue/tr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/blue/tr.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/gray/bl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/gray/bl.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/gray/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/gray/bottom.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/gray/br.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/gray/br.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/gray/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/gray/left.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/gray/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/gray/right.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/gray/tl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/gray/tl.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/gray/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/gray/top.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/gray/tr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/gray/tr.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/red/bl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/red/bl.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/red/bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/red/bottom.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/red/br.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/red/br.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/red/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/red/left.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/red/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/red/right.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/red/tl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/red/tl.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/red/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/red/top.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/border/red/tr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/border/red/tr.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/collapse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/collapse.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/downArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/downArrow.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/empty.png -------------------------------------------------------------------------------- /src/main/resources/net/rptools/lib/swing/image/expand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RPTools/rplib/93f640cf2bd9077eaef3d5e88ae337900ffa599c/src/main/resources/net/rptools/lib/swing/image/expand.png -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | 1.4.1.7 2 | --------------------------------------------------------------------------------