UpdateFX with maven build (tested only on mac)

This commit is contained in:
Manfred Karrer 2015-02-27 23:47:21 +01:00
parent 491e15c3de
commit 6b4f528f47
706 changed files with 6520 additions and 737 deletions

View file

@ -1,24 +0,0 @@
language: java
jdk: oraclejdk8
before_install:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
notifications:
irc:
channels: chat.freenode.net#bitsquare
template:
- '%{message} (%{repository}#%{build_number}, %{duration})'
- '%{repository}/%{branch} %{commit} %{author}: %{commit_message}'
- '%{build_url}'
on_success: change
on_failure: always
use_notice: true
skip_join: true
env:
- TERM=dumb
after_success:
- ./gradlew jacocoTestReport coveralls

View file

@ -1,102 +0,0 @@
import org.apache.tools.ant.filters.ReplaceTokens
import org.apache.tools.ant.taskdefs.condition.Os
plugins {
id "com.github.johnrengelman.shadow" version "1.1.2"
id "com.github.kt3k.coveralls" version "2.0.1x"
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'application'
apply plugin: 'jacoco'
wrapper.gradleVersion = '2.1'
version = '0.1.1-SNAPSHOT'
sourceCompatibility = 1.8
sourceSets.main.resources.srcDirs += 'src/main/java'
sourceSets.test.resources.srcDirs += 'src/test/java'
mainClassName = "io.bitsquare.app.gui.BitsquareAppMain"
run {
if (project.hasProperty('args')) {
args project.args.split(',')
}
}
processResources {
from(sourceSets.main.resources.srcDirs) {
include '**/*.properties'
filter(ReplaceTokens, tokens: ['app.version': project.version])
}
}
repositories {
jcenter()
maven { url 'http://tomp2p.net/dev/mvn/' }
}
dependencies {
compile 'org.bitcoinj:bitcoinj-core:0.12.2'
compile 'net.tomp2p:tomp2p-all:5.0-Beta3'
compile 'io.reactivex:rxjava:1.0.0'
compile 'org.springframework:spring-core:4.1.1.RELEASE'
compile 'net.sf.jopt-simple:jopt-simple:4.8'
compile 'org.slf4j:slf4j-api:1.7.7'
compile 'ch.qos.logback:logback-core:1.1.2'
compile 'ch.qos.logback:logback-classic:1.1.2'
compile 'com.google.inject:guice:3.0'
compile 'com.google.guava:guava:16.0.1'
compile 'com.google.code.gson:gson:2.2.4'
compile 'org.controlsfx:controlsfx:8.0.6_20'
compile 'de.jensd:fontawesomefx:8.0.0'
compile 'net.glxn:qrgen:1.3'
compile 'com.google.code.findbugs:jsr305:2.0.3'
compile 'net.jcip:jcip-annotations:1.0'
compile 'org.jetbrains:annotations:13.0'
compile 'eu.hansolo.enzo:Enzo:0.1.5'
compile 'com.vinumeris:updatefx:1.2'
testCompile 'junit:junit:4.11'
testCompile "org.mockito:mockito-core:1.+"
testCompile 'org.springframework:spring-test:4.1.1.RELEASE'
}
shadowJar.classifier = 'app'
task packageNative(type: Exec, dependsOn: shadowJar) {
if (Os.isFamily(Os.FAMILY_MAC))
executable "${project.rootDir}/package/mac.sh"
else if (Os.isFamily(Os.FAMILY_UNIX))
executable "${project.rootDir}/package/linux.sh"
else if (Os.isFamily(Os.FAMILY_WINDOWS))
executable "${project.rootDir}/package/windows.bat"
else
throw new GradleException("Unsupported OS: " + System.properties['os.name'])
args project.version, shadowJar.archivePath, mainClassName
}
task appJar(dependsOn: shadowJar) {
group = "shadow"
description = "Builds a Bitsquare client UI executable jar"
}
task bootstrapNodeJar(type: com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar) {
group = "shadow"
description = "Builds a Bitsquare bootstrap node executable jar"
manifest.attributes 'Main-Class': 'io.bitsquare.app.cli.BootstrapNodeMain'
classifier = 'bootstrapNode'
from(project.convention.getPlugin(JavaPluginConvention).sourceSets.main.output)
configurations = [project.configurations.runtime]
exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA')
}
jacocoTestReport {
reports {
xml.enabled = true
html.enabled = true
}
}

13
build_create_app_mac.sh Normal file
View file

@ -0,0 +1,13 @@
#!/bin/bash
# edit path
cd /Users/mk/Documents/_intellij/bitsquare_UpdateFX_maven
mvn clean package -DskipTests -Dmaven.javadoc.skip=true
cp gui/target/shaded.jar gui/updatefx/builds/1.jar
# edit url
java -jar ./updatefx/updatefx-app-1.2.jar --url=http://localhost:8000/ gui/updatefx
# edit JAVA_HOME and different OS binaries
/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/bin/javapackager -deploy -outdir gui/deploy/ -outfile Bitsquare.dmg -name Bitsquare -native dmg -appclass io.bitsquare.app.gui.BitsquareAppMain -srcfiles gui/updatefx/builds/processed/1.jar

19
build_setup.sh Normal file
View file

@ -0,0 +1,19 @@
#!/bin/bash
# setup dirs
cd /Users/admin_mbp/Dropbox/Bitsquare2
mkdir gui/updatefx
mkdir gui/updatefx/builds
mkdir gui/updatefx/builds/processed
mkdir gui/updatefx/site
mkdir gui/deploy
# create key/wallet
java -jar ./updatefx/updatefx-app-1.2.jar --url=http://localhost:8000/ gui/updatefx
# start webserver for update data
cd /Users/admin_mbp/Dropbox/Bitsquare2/gui/updatefx/site
# python -m SimpleHTTPServer 8000
# create icons
# iconutil -c icns package/bitsquare.iconset

11
build_update.sh Normal file
View file

@ -0,0 +1,11 @@
#!/bin/bash
# edit path
cd /Users/mk/Documents/_intellij/bitsquare_UpdateFX_maven
mvn clean package -DskipTests -Dmaven.javadoc.skip=true
# edit version /*.jar
cp gui/target/shaded.jar gui/updatefx/builds/2.jar
# edit url
java -jar ./updatefx/updatefx-app-1.2.jar --url=http://localhost:8000/ gui/updatefx

30
common/common.iml Normal file
View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Maven: org.bitcoinj:bitcoinj-core:0.12.2" level="project" />
<orderEntry type="library" name="Maven: com.madgag.spongycastle:core:1.51.0.0" level="project" />
<orderEntry type="library" name="Maven: com.google.protobuf:protobuf-java:2.5.0" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:2.0.1" level="project" />
<orderEntry type="library" name="Maven: net.jcip:jcip-annotations:1.0" level="project" />
<orderEntry type="library" name="Maven: com.lambdaworks:scrypt:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.bitcoinj:orchid:1.0" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.6" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:16.0.1" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.11" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Maven: org.mockito:mockito-core:1.10.19" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.objenesis:objenesis:2.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-test:4.1.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:4.1.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.1.3" level="project" />
</component>
</module>

15
common/pom.xml Executable file
View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent</artifactId>
<groupId>io.bitsquare</groupId>
<version>0.1.1-SNAPSHOT</version>
</parent>
<artifactId>common</artifactId>
<dependencies>
</dependencies>
</project>

29
doc/update_fork_tomp2p.sh Executable file
View file

@ -0,0 +1,29 @@
#!/bin/bash
cd /Users/mk/Documents/_intellij/TomP2P-master_fork/TomP2P
git reset --hard
git remote add upstream https://github.com/tomp2p/TomP2P.git
git checkout master
git pull upstream master
git push origin master
git checkout published
git reset --hard master
export COMMITHASH=$(git log --oneline -1 | cut -d" " -f1)
git grep -l 5.0-Alpha | xargs perl -p -i -e "s/5.0-Alpha(..?)-SNAPSHOT/5.0-Alpha$1.$COMMITHASH-SNAPSHOT/"
git commit -am"Qualify pom version for publication"
echo $COMMITHASH
mvn clean install -DskipTests
git show bitsquare-published-91276e8:README > README
git add README
git commit -m"Add README with publication instructions"
git tag bitsquare-published-$COMMITHASH published
git push -f origin published
git push --tags
echo $COMMITHASH

View file

@ -1,2 +0,0 @@
org.gradle.jvmargs=-Xmx1024m
org.gradle.daemon=true

Binary file not shown.

View file

@ -1,6 +0,0 @@
#Tue Sep 30 23:44:09 CEST 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.1-all.zip

164
gradlew vendored
View file

@ -1,164 +0,0 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
gradlew.bat vendored
View file

@ -1,90 +0,0 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View file

@ -0,0 +1,141 @@
/* splash screen */
#image-splash-logo {
-fx-image: url("../../../images/logo_splash.png");
}
/* notification */
#notification-logo {
-fx-image: url("../../../images/notification_logo.png");
}
/* shared*/
#image-info {
-fx-image: url("../../../images/info.png");
}
#image-alert-round {
-fx-image: url("../../../images/alert_round.png");
}
#image-remove {
-fx-image: url("../../../images/remove.png");
}
#image-buy {
-fx-image: url("../../../images/buy.png");
}
#image-sell {
-fx-image: url("../../../images/sell.png");
}
#image-expand {
-fx-image: url("../../../images/expand.png");
}
#image-collapse {
-fx-image: url("../../../images/collapse.png");
}
#image-buy-large {
-fx-image: url("../../../images/buy_large.png");
}
#image-sell-large {
-fx-image: url("../../../images/sell_large.png");
}
/* navigation buttons */
#image-nav-home {
-fx-image: url("../../../images/nav/home.png");
}
#image-nav-home-active {
-fx-image: url("../../../images/nav/home_active.png");
}
#image-nav-buy {
-fx-image: url("../../../images/nav/buy.png");
}
#image-nav-buy-active {
-fx-image: url("../../../images/nav/buy_active.png");
}
#image-nav-sell {
-fx-image: url("../../../images/nav/sell.png");
}
#image-nav-sell-active {
-fx-image: url("../../../images/nav/sell_active.png");
}
#image-nav-portfolio {
-fx-image: url("../../../images/nav/portfolio.png");
}
#image-nav-portfolio-active {
-fx-image: url("../../../images/nav/portfolio_active.png");
}
#image-nav-funds {
-fx-image: url("../../../images/nav/funds.png");
}
#image-nav-funds-active {
-fx-image: url("../../../images/nav/funds_active.png");
}
#image-nav-msg {
-fx-image: url("../../../images/nav/msg.png");
}
#image-nav-msg-active {
-fx-image: url("../../../images/nav/msg_active.png");
}
#image-nav-settings {
-fx-image: url("../../../images/nav/settings.png");
}
#image-nav-settings-active {
-fx-image: url("../../../images/nav/settings_active.png");
}
#image-nav-account {
-fx-image: url("../../../images/nav/account.png");
}
#image-nav-account-active {
-fx-image: url("../../../images/nav/account_active.png");
}
/* account*/
#image-tick {
-fx-image: url("../../../images/tick.png");
}
#image-arrow-blue {
-fx-image: url("../../../images/arrow_blue.png");
}
#image-arrow-grey {
-fx-image: url("../../../images/arrow_grey.png");
}
/* connection state*/
#image-connection-direct {
-fx-image: url("../../../images/connection/direct.png");
}
#image-connection-nat {
-fx-image: url("../../../images/connection/nat.png");
}
#image-connection-relay {
-fx-image: url("../../../images/connection/relay.png");
}
#image-connection-synced {
-fx-image: url("../../../images/connection/synced.png");
}

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ This file is part of Bitsquare.
~
~ Bitsquare is free software: you can redistribute it and/or modify it
~ under the terms of the GNU Affero General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or (at
~ your option) any later version.
~
~ Bitsquare is distributed in the hope that it will be useful, but WITHOUT
~ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
~ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
~ License for more details.
~
~ You should have received a copy of the GNU Affero General Public License
~ along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
-->
<?import javafx.scene.layout.*?>
<StackPane fx:id="root" fx:controller="io.bitsquare.gui.main.MainView"
prefHeight="750" prefWidth="1000"
xmlns:fx="http://javafx.com/fxml">
</StackPane>

69
gui/gui.iml Normal file
View file

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/target/classes" />
<output-test url="file://$MODULE_DIR$/target/test-classes" />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/../client/target" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="common" />
<orderEntry type="module" module-name="common" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.1.2" level="project" />
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.1.2" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.6" level="project" />
<orderEntry type="library" name="Maven: net.tomp2p:tomp2p-all:5.0-Beta3" level="project" />
<orderEntry type="library" name="Maven: net.tomp2p:tomp2p-core:5.0-Beta3" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-transport:4.0.25.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-buffer:4.0.25.Final" level="project" />
<orderEntry type="library" name="Maven: io.netty:netty-common:4.0.25.Final" level="project" />
<orderEntry type="library" name="Maven: net.tomp2p:tomp2p-nat:5.0-Beta3" level="project" />
<orderEntry type="library" name="Maven: org.bitlet:weupnp:0.1.2" level="project" />
<orderEntry type="library" name="Maven: com.ganyo:gcm-server:1.0.2" level="project" />
<orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1" level="project" />
<orderEntry type="library" name="Maven: net.tomp2p:tomp2p-android:5.0-Beta3" level="project" />
<orderEntry type="library" name="Maven: net.tomp2p:tomp2p-replication:5.0-Beta3" level="project" />
<orderEntry type="library" name="Maven: net.tomp2p:tomp2p-storage:5.0-Beta3" level="project" />
<orderEntry type="library" name="Maven: org.mapdb:mapdb:1.0.6" level="project" />
<orderEntry type="library" name="Maven: net.tomp2p:tomp2p-dht:5.0-Beta3" level="project" />
<orderEntry type="library" name="Maven: net.tomp2p:tomp2p-tracker:5.0-Beta3" level="project" />
<orderEntry type="library" name="Maven: io.reactivex:rxjava:1.0.0" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-core:4.1.1.RELEASE" level="project" />
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.1.3" level="project" />
<orderEntry type="library" name="Maven: net.sf.jopt-simple:jopt-simple:4.8" level="project" />
<orderEntry type="library" name="Maven: com.google.inject:guice:3.0" level="project" />
<orderEntry type="library" name="Maven: javax.inject:javax.inject:1" level="project" />
<orderEntry type="library" name="Maven: aopalliance:aopalliance:1.0" level="project" />
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.2.4" level="project" />
<orderEntry type="library" name="Maven: org.controlsfx:controlsfx:8.0.6_20" level="project" />
<orderEntry type="library" name="Maven: de.jensd:fontawesomefx:8.0.0" level="project" />
<orderEntry type="library" name="Maven: net.glxn:qrgen:1.3" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:javase:2.0" level="project" />
<orderEntry type="library" name="Maven: com.google.zxing:core:2.0" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:2.0.1" level="project" />
<orderEntry type="library" name="Maven: net.jcip:jcip-annotations:1.0" level="project" />
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
<orderEntry type="library" name="Maven: eu.hansolo.enzo:Enzo:0.1.5" level="project" />
<orderEntry type="library" name="Maven: org.fxmisc.easybind:easybind:1.0.2" level="project" />
<orderEntry type="library" name="Maven: com.vinumeris:updatefx:1.2" level="project" />
<orderEntry type="library" name="Maven: com.google.protobuf:protobuf-java:2.5.0" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-jdk14:1.7.6" level="project" />
<orderEntry type="library" name="Maven: net.sf.trove4j:trove4j:3.0.3" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.51" level="project" />
<orderEntry type="library" name="Maven: org.bitcoinj:bitcoinj-core:0.12.2" level="project" />
<orderEntry type="library" name="Maven: com.madgag.spongycastle:core:1.51.0.0" level="project" />
<orderEntry type="library" name="Maven: com.lambdaworks:scrypt:1.4.0" level="project" />
<orderEntry type="library" name="Maven: org.bitcoinj:orchid:1.0" level="project" />
<orderEntry type="library" name="Maven: com.google.guava:guava:16.0.1" level="project" />
<orderEntry type="library" name="Maven: junit:junit:4.11" level="project" />
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
<orderEntry type="library" name="Maven: org.mockito:mockito-core:1.10.19" level="project" />
<orderEntry type="library" scope="RUNTIME" name="Maven: org.objenesis:objenesis:2.1" level="project" />
<orderEntry type="library" name="Maven: org.springframework:spring-test:4.1.1.RELEASE" level="project" />
</component>
</module>

210
gui/pom.xml Executable file
View file

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>parent</artifactId>
<groupId>io.bitsquare</groupId>
<version>0.1.1-SNAPSHOT</version>
</parent>
<artifactId>gui</artifactId>
<build>
<resources>
<resource>
<filtering>false</filtering>
<directory>${basedir}/src/main/java</directory>
<includes>
<include>**/*.fxml</include>
<include>**/*.css</include>
</includes>
</resource>
<resource>
<filtering>false</filtering>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<configuration>
<!-- broken with Java 8 (MSHADE-174), using ProGuard instead. -->
<minimizeJar>false</minimizeJar>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>io.bitsquare.app.gui.BitsquareAppMain</mainClass>
</transformer>
</transformers>
<filters>
<filter>
<!-- exclude signatures, the bundling process breaks them for some reason -->
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>bundled</shadedClassifierName>
<finalName>shaded</finalName>
</configuration>
</execution>
</executions>
</plugin>
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>enforce</id>
<configuration>
<rules>
<DependencyConvergence />
</rules>
</configuration>
<goals>
<goal>enforce</goal>
</goals>
</execution>
</executions>
</plugin>-->
</plugins>
</build>
<repositories>
<repository>
<id>sonatype-oss-snapshot</id>
<snapshots/>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
<repository>
<id>repository.tomp2p.net</id>
<url>http://tomp2p.net/dev/mvn</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.bitsquare</groupId>
<artifactId>common</artifactId>
<version>${parent.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>net.tomp2p</groupId>
<artifactId>tomp2p-all</artifactId>
<version>5.0-Beta3</version>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>net.sf.jopt-simple</groupId>
<artifactId>jopt-simple</artifactId>
<version>4.8</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.controlsfx</groupId>
<artifactId>controlsfx</artifactId>
<version>8.0.6_20</version>
</dependency>
<dependency>
<groupId>de.jensd</groupId>
<artifactId>fontawesomefx</artifactId>
<version>8.0.0</version>
</dependency>
<dependency>
<groupId>net.glxn</groupId>
<artifactId>qrgen</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>net.jcip</groupId>
<artifactId>jcip-annotations</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>13.0</version>
</dependency>
<dependency>
<groupId>eu.hansolo.enzo</groupId>
<artifactId>Enzo</artifactId>
<version>0.1.5</version>
</dependency>
<dependency>
<groupId>org.fxmisc.easybind</groupId>
<artifactId>easybind</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>com.vinumeris</groupId>
<artifactId>updatefx</artifactId>
<version>1.2</version>
</dependency>
<!--
<dependency>
<groupId>com.vinumeris</groupId>
<artifactId>crashfx-client</artifactId>
<version>1.1</version>
</dependency>
-->
</dependencies>
</project>

View file

@ -45,7 +45,6 @@ public class BitsquareEnvironment extends StandardEnvironment {
public static final String APP_VERSION_KEY = "app.version";
// TODO what is the difference to APP_DATA_DIR ?
public static final String USER_DATA_DIR_KEY = "user.data.dir";
public static final String DEFAULT_USER_DATA_DIR = defaultUserDataDir();
@ -99,7 +98,6 @@ public class BitsquareEnvironment extends StandardEnvironment {
}
}
PropertySource<?> appDirProperties() throws Exception {
String location = String.format("file:%s/bitsquare.properties", appDataDir);
Resource resource = resourceLoader.getResource(location);

View file

@ -58,7 +58,7 @@ import org.springframework.util.FileSystemUtils;
import static io.bitsquare.app.BitsquareEnvironment.*;
public class BitsquareApp extends Application {
private static final Logger log = LoggerFactory.getLogger(BitsquareAppMain.class);
private static final Logger log = LoggerFactory.getLogger(BitsquareApp.class);
private static Environment env;
@ -71,9 +71,7 @@ public class BitsquareApp extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
// For some reason the JavaFX launch process results in us losing the thread context class loader: reset it.
Thread.currentThread().setContextClassLoader(BitsquareApp.class.getClassLoader());
log.trace("BitsquareApp.start");
bitsquareAppModule = new BitsquareAppModule(env, primaryStage);
injector = Guice.createInjector(bitsquareAppModule);
injector.getInstance(InjectorViewFactory.class).setInjector(injector);
@ -107,6 +105,7 @@ public class BitsquareApp extends Application {
// load the main view and create the main scene
log.trace("viewLoader.load(MainView.class)");
ViewLoader viewLoader = injector.getInstance(CachingViewLoader.class);
View view = viewLoader.load(MainView.class);
@ -152,6 +151,7 @@ public class BitsquareApp extends Application {
// make the UI visible
log.trace("primaryStage.show");
primaryStage.show();
}

View file

@ -30,6 +30,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vinumeris.updatefx.UpdateFX;
import joptsimple.OptionException;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
@ -42,14 +43,38 @@ public class BitsquareAppMain extends BitsquareExecutable {
private static final Logger log = LoggerFactory.getLogger(BitsquareAppMain.class);
public static void main(String[] args) throws Exception {
// We don't want to do the whole arg parsing/setup here as that might easily change in update versions
// So we only handle the absolute minimum which is APP_NAME and USER_DATA_DIR
// TODO Not impl. yet, just use default for first testings
UpdateFX.bootstrap(BitsquareAppMain.class, new File(BitsquareEnvironment.DEFAULT_APP_DATA_DIR).toPath(), args);
// We don't want to do the full argument parsing here as that might easily change in update versions
// So we only handle the absolute minimum which is APP_NAME, APP_DATA_DIR_KEY and USER_DATA_DIR
OptionParser parser = new OptionParser();
parser.accepts(USER_DATA_DIR_KEY, description("User data directory", DEFAULT_USER_DATA_DIR))
.withRequiredArg();
parser.accepts(APP_NAME_KEY, description("Application name", DEFAULT_APP_NAME))
.withRequiredArg();
parser.accepts(APP_DATA_DIR_KEY, description("Application data directory", DEFAULT_APP_DATA_DIR))
.withRequiredArg();
OptionSet options;
try {
options = parser.parse(args);
} catch (OptionException ex) {
System.out.println("error: " + ex.getMessage());
System.out.println();
parser.printHelpOn(System.out);
System.exit(EXIT_FAILURE);
return;
}
BitsquareEnvironment bitsquareEnvironment = new BitsquareEnvironment(options);
String updatesDirectory = bitsquareEnvironment.getProperty(BitsquareEnvironment.APP_DATA_DIR_KEY);
UpdateFX.bootstrap(BitsquareAppMain.class, new File(updatesDirectory).toPath(), args);
}
// That will be called from UpdateFX after updates are checked
public static void realMain(String[] args) throws Exception {
log.trace("realMain");
// For some reason the JavaFX launch process results in us losing the thread context class loader: reset it.
// In order to work around a bug in JavaFX 8u25 and below, you must include the following code as the first line of your realMain method:
Thread.currentThread().setContextClassLoader(BitsquareAppMain.class.getClassLoader());
new BitsquareAppMain().execute(args);
}

View file

@ -61,10 +61,8 @@ class BitsquareAppModule extends BitsquareModule {
bindConstant().annotatedWith(named(Persistence.PREFIX_KEY)).to(env.getRequiredProperty(Persistence.PREFIX_KEY));
bind(Persistence.class).asEagerSingleton();
// TODO UpdateFXHelper needs Environment. Should we just expose the 2 properties needed?
bind(Environment.class).toInstance(env);
// for temp testing with mock
bind(UpdateProcess.class).to(MockUpdateProcess.class).asEagerSingleton();
bind(UpdateProcess.class).asEagerSingleton();
install(messageModule());
install(bitcoinModule());

View file

@ -51,14 +51,15 @@ import rx.subjects.Subject;
public class UpdateProcess {
private static final Logger log = LoggerFactory.getLogger(UpdateProcess.class);
private static final int VERSION = 1;
private static final List<ECPoint> UPDATE_SIGNING_KEYS = Crypto.decode(
"028B41BDDCDCAD97B6AE088FEECA16DC369353B717E13319370C729CB97D677A11",
"031E3D80F21A4D10D385A32ABEDC300DACBEDBC839FBA58376FBD5D791D806BA68"
);
private static final int UPDATE_SIGNING_THRESHOLD = 1;
// Edit version for updateFX
private static final int VERSION = 12;
private static final List<ECPoint> UPDATE_SIGNING_KEYS = Crypto.decode("03C00C9B7894A072A459FFF87DBA8CFE76366D5BF4C013E41AE8D7A314625DFB30");
private static final String UPDATES_BASE_URL = "http://localhost:8000/";
private static final int UPDATE_SIGNING_THRESHOLD = 1;
private static final Path ROOT_CLASS_PATH = UpdateFX.findCodePath(BitsquareAppMain.class);
private Environment environment;
public enum State {
@ -72,22 +73,11 @@ public class UpdateProcess {
protected String errorMessage;
protected final Subject<State, State> process = BehaviorSubject.create();
protected final AnimationTimer timeoutTimer;
protected AnimationTimer timeoutTimer;
@Inject
public UpdateProcess(Environment environment) {
// process.timeout() will cause an error state back but we dont want to break startup in case of an update
// timeout
timeoutTimer = Utilities.setTimeout(10000, new Function<AnimationTimer, Void>() {
@Override
public Void apply(AnimationTimer animationTimer) {
process.onCompleted();
return null;
}
});
timeoutTimer.start();
init(environment);
this.environment = environment;
}
public void restart() {
@ -102,16 +92,26 @@ public class UpdateProcess {
return errorMessage;
}
protected void init(Environment environment) {
log.info("version " + VERSION);
public void init() {
log.info("UpdateFX current version " + VERSION);
// process.timeout() will cause an error state back but we don't want to break startup in case of an timeout
timeoutTimer = Utilities.setTimeout(10000, new Function<AnimationTimer, Void>() {
@Override
public Void apply(AnimationTimer animationTimer) {
process.onCompleted();
return null;
}
});
timeoutTimer.start();
String agent = environment.getProperty(BitsquareEnvironment.APP_NAME_KEY) + VERSION;
Path dataDirPath = new File(environment.getProperty(BitsquareEnvironment.APP_DATA_DIR_KEY)).toPath();
Updater updater = new Updater(UPDATES_BASE_URL, agent, VERSION, dataDirPath, ROOT_CLASS_PATH,
UPDATE_SIGNING_KEYS, UPDATE_SIGNING_THRESHOLD) {
@Override
protected void updateProgress(long workDone, long max) {
log.debug("updateProgress " + workDone + "/" + max);
//log.trace("updateProgress " + workDone + "/" + max);
super.updateProgress(workDone, max);
}
};
@ -127,24 +127,24 @@ public class UpdateProcess {
updater.setOnSucceeded(event -> {
try {
UpdateSummary summary = updater.get();
if (summary.descriptions.size() > 0) {
log.info("summary " +summary.toString());
if (summary.descriptions != null && summary.descriptions.size() > 0) {
log.info("One liner: {}", summary.descriptions.get(0).getOneLiner());
log.info("{}", summary.descriptions.get(0).getDescription());
}
if (summary.highestVersion > VERSION) {
log.info("UPDATE_AVAILABLE");
state.set(State.UPDATE_AVAILABLE);
// We stop the timeout and treat it not completed.
// The user should click the restart button manually if there are updates available.
timeoutTimer.stop();
}
else if (summary.highestVersion == VERSION) {
log.info("UP_TO_DATE");
state.set(State.UP_TO_DATE);
timeoutTimer.stop();
process.onCompleted();
}
/* if (summary.highestVersion > VERSION) {
log.info("Restarting to get version " + summary.highestVersion);
if (UpdateFX.getVersionPin(dataDirPath) == 0)
UpdateFX.restartApp();
}*/
} catch (Throwable e) {
log.error("Exception at processing UpdateSummary: " + e.getMessage());
@ -172,5 +172,4 @@ public class UpdateProcess {
thread.setDaemon(true);
thread.start();
}
}
}

View file

@ -0,0 +1,489 @@
/*
Theme colors:
logo colors:
new blue: 0f87c3
new grey: 666666
00abff
orange webpage quotes : ff7f00
main bg grey: dddddd
content bg grey: f4f4f4
tab pane upper bg gradient color mid dark grey to bright grey: cfcfcf -> dddddd
upper border on tab: cfcfcf
lower border on tab: b5b5b5
upper gradient color on tab: d3d3d3
lower gradient color on tab: dddddd
*/
.root {
-bs-grey: #666666;
-bs-bg-grey: #dddddd;
-bs-error-red: #dd0000;
-fx-accent: #0f87c3;
-fx-default-button: derive(-fx-accent, 95%);
-fx-focus-color: -fx-accent;
-fx-faint-focus-color: #0f87c322;
-fx-selection-bar: derive(-fx-accent, 50%);
}
/* Splash */
#splash {
-fx-background-color: #ffffff;
}
#splash-error-state-msg {
-fx-text-fill: -bs-error-red;
}
#splash-bitcoin-network-label {
-fx-text-fill: -fx-accent;
-fx-weight: bold;
}
/* Main UI */
#base-content-container {
-fx-background-color: -bs-bg-grey;
}
#content-pane {
-fx-background-color: #f4f4f4;
}
#headline-label {
-fx-font-weight: bold;
-fx-font-size: 18;
}
/* Main navigation */
#nav-button {
-fx-cursor: hand;
-fx-background-color: transparent;
}
#nav-button .text {
-fx-font-size: 10;
}
#nav-button:selected .text {
-fx-font-size: 11;
-fx-font-weight: bold;
-fx-fill: -fx-accent;
}
#nav-button-label {
-fx-font-size: 10;
}
#nav-balance-label {
-fx-font-weight: bold;
-fx-alignment: center;
-fx-background-color: #dddddd;
}
#nav-alert-label {
-fx-font-weight: bold;
-fx-font-size: 11;
-fx-text-fill: white;
}
.text-field:readonly {
-fx-text-fill: #000000;
-fx-background-color: #FAFAFA;
}
#feedback-text {
-fx-font-size: 10;
}
#label-url {
-fx-cursor: hand;
-fx-text-fill: blue;
-fx-underline: true;
}
#icon-button {
-fx-cursor: hand;
-fx-background-color: transparent;
}
.copy-icon {
-fx-text-fill: -fx-accent;
-fx-cursor: hand;
}
.copy-icon:hover {
-fx-text-fill: black;
}
/*******************************************************************************
* *
* Tooltip *
* *
******************************************************************************/
.tooltip {
-fx-background: white;
-fx-text-fill: black;
-fx-background-color: white;
-fx-background-radius: 6px;
-fx-background-insets: 0;
-fx-padding: 0.667em 0.75em 0.667em 0.75em; /* 10px */
-fx-effect: dropshadow(three-pass-box, rgba(0, 0, 0, 0.5), 10, 0.0, 0, 3);
-fx-font-size: 0.85em;
}
/* Same style like non editable textfield. But textfield spans a whole column in a grid, so we use generally
textfield */
#label-with-background {
-fx-background-color: #FAFAFA;
-fx-border-radius: 4;
-fx-padding: 4 4 4 4;
}
#address-text-field {
-fx-cursor: hand;
-fx-text-fill: -fx-accent;
}
#address-text-field:hover {
-fx-text-fill: black;
}
#funds-confidence {
-fx-progress-color: dimgrey;
}
/* .table-view */
.table-view .table-cell {
-fx-alignment: center;
}
.table-view .column-header .label {
-fx-alignment: center;
}
.table-view .focus {
-fx-alignment: center;
}
.table-view .text {
-fx-fill: black;
}
.table-view .table-row-cell:selected .table-row-cell:row-selection .table-row-cell:cell-selection .text {
-fx-fill: white;
}
.table-view .table-row-cell:selected .button .text {
-fx-fill: black;
}
.table-view .table-row-cell .copy-icon .text {
-fx-fill: -fx-accent;
}
.table-view .table-row-cell .copy-icon .text:hover {
-fx-fill: black;
}
.table-view .table-row-cell:selected .copy-icon .text {
-fx-fill: white;
}
.table-view .table-row-cell:selected .copy-icon .text:hover {
-fx-fill: black;
}
.table-view .table-row-cell .hyperlink .text {
-fx-fill: -fx-accent;
}
.table-view .table-row-cell .hyperlink .text:hover {
-fx-fill: black;
}
.table-view .table-row-cell:selected .hyperlink .text {
-fx-fill: white;
}
.table-view .table-row-cell:selected .hyperlink .text:hover {
-fx-fill: black;
}
#form-header-text {
-fx-font-weight: bold;
-fx-font-size: 14;
}
#non-clickable-icon {
-fx-text-fill: #AAAAAA;
}
#clickable-icon {
-fx-text-fill: -fx-accent;
-fx-cursor: hand;
}
#clickable-icon:hover {
-fx-text-fill: #666666;
}
#form-title {
-fx-font-weight: bold;
}
/* tab pane */
.tab-pane .tab-label {
-fx-font-size: 15;
}
.tab-pane:focused {
-fx-background-color: transparent;
}
.tab-header-area:focused {
-fx-background-color: transparent;
}
.tab:focused {
-fx-background-color: transparent;
}
/* table-view */
.table-view:focused {
-fx-background-color: transparent;
}
/* scroll-pane */
.scroll-pane {
-fx-background-insets: 0;
-fx-padding: 0;
}
.scroll-pane:focused {
-fx-background-insets: 0;
}
.scroll-pane .corner {
-fx-background-insets: 0;
}
/* validation */
#validation-error {
-fx-text-fill: red;
}
/* Account */
#content-pane-top {
-fx-background-color: #cfcfcf,
linear-gradient(#cfcfcf 0%, #b5b5b5 100%),
linear-gradient(#d3d3d3 0%, -bs-bg-grey 100%);
-fx-background-insets: 0 0 0 0, 0, 1;
}
#info-icon-label {
-fx-font-size: 16;
-fx-text-fill: #333000;
}
/* Create offer */
#direction-icon-label {
-fx-font-weight: bold;
-fx-font-size: 16;
-fx-text-fill: -bs-grey;
}
#input-description-label {
-fx-font-size: 11;
-fx-alignment: center;
}
#create-offer-calc-label {
-fx-font-weight: bold;
-fx-font-size: 20;
-fx-padding: 15 5 0 5;
}
#currency-info-label {
-fx-border-radius: 0 4 4 0;
-fx-padding: 4 4 4 4;
-fx-background-color: #f6f6f6;
-fx-border-color: #aaa;
-fx-border-style: solid solid solid none;
-fx-border-insets: 0 0 0 -2;
}
#totals-separator {
-fx-background: #AAAAAA;
}
#payment-info {
-fx-background-color: #f4f4f4;
}
/* Account setup */
#wizard-title-deactivated {
-fx-font-weight: bold;
-fx-font-size: 16;
-fx-text-fill: #999999;
}
#wizard-title-active {
-fx-font-weight: bold;
-fx-font-size: 16;
-fx-text-fill: #333333;
}
#wizard-title-completed {
-fx-font-weight: bold;
-fx-font-size: 16;
-fx-text-fill: #333333;
}
#wizard-sub-title-deactivated {
-fx-text-fill: #999999;
}
#wizard-sub-title-active {
-fx-text-fill: #333333;
}
#wizard-sub-title-completed {
-fx-text-fill: #333333;
}
#wizard-item-background-deactivated {
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
-fx-outer-border: linear-gradient(to bottom, #dddddd, #ccc);
-fx-background-color: -fx-shadow-highlight-color,
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
-fx-background-radius: 3px, 3px, 2px, 1px;
}
#wizard-item-background-active {
-fx-body-color: linear-gradient(to bottom, #f1f6f7, #e7f5f9);
-fx-outer-border: linear-gradient(to bottom, #b5e1ef, #6aa4b6);
-fx-background-color: -fx-shadow-highlight-color,
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
-fx-background-radius: 3px, 3px, 2px, 1px;
}
#wizard-item-background-completed {
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
-fx-outer-border: linear-gradient(to bottom, #99ba9c, #619865);
-fx-background-color: -fx-shadow-highlight-color,
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
-fx-background-radius: 3px, 3px, 2px, 1px;
}
/* Account settings */
#wizard-title-disabled {
-fx-font-weight: bold;
-fx-font-size: 16;
-fx-text-fill: #999999;
}
#wizard-title-active {
-fx-font-weight: bold;
-fx-font-size: 16;
-fx-text-fill: #333333;
}
#wizard-title-selected {
-fx-font-weight: bold;
-fx-font-size: 16;
-fx-text-fill: -fx-accent;
}
#account-settings-item-background-disabled {
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
-fx-outer-border: linear-gradient(to bottom, #dddddd, #ccc);
-fx-background-color: -fx-shadow-highlight-color,
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
-fx-background-radius: 3px, 3px, 2px, 1px;
}
#account-settings-item-background-active {
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
-fx-outer-border: linear-gradient(to bottom, #dddddd, #ccc);
-fx-background-color: -fx-shadow-highlight-color,
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
-fx-background-radius: 3px, 3px, 2px, 1px;
}
#account-settings-item-background-selected {
-fx-body-color: linear-gradient(to bottom, #f1f6f7, #e7f5f9);
-fx-outer-border: linear-gradient(to bottom, #b5e1ef, #6aa4b6);
-fx-background-color: -fx-shadow-highlight-color,
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
-fx-background-radius: 3px, 3px, 2px, 1px;
}
/* TitledGroupBg */
#titled-group-bg-label {
-fx-font-weight: bold;
-fx-font-size: 14;
-fx-text-fill: -bs-grey;
-fx-background-color: #f4f4f4;
}
#titled-group-bg-label-active {
-fx-font-weight: bold;
-fx-font-size: 14;
-fx-text-fill: -fx-accent;
-fx-background-color: #f4f4f4;
}
#titled-group-bg {
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
-fx-outer-border: linear-gradient(to bottom, #dddddd, #ccc);
-fx-background-color: -fx-shadow-highlight-color,
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
-fx-background-radius: 3px, 3px, 2px, 1px;
}
#titled-group-bg-active {
-fx-body-color: linear-gradient(to bottom, #f4f4f4, #F0F0F0);
-fx-outer-border: linear-gradient(to bottom, #9bbdc9, #57acc9);
-fx-background-color: -fx-shadow-highlight-color,
-fx-outer-border,
-fx-inner-border,
-fx-body-color;
-fx-background-insets: 0 0 -1 0, 0, 1, 2;
-fx-background-radius: 3px, 3px, 2px, 1px;
}
/* TitledSeparator */
#titled-separator:horizontal .line {
-fx-border-color: transparent #f4f4f4 transparent #f4f4f4;
-fx-background-color: transparent;
-fx-border-width: 10px;
}

View file

@ -0,0 +1,247 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.components;
import io.bitsquare.locale.BSResources;
import javafx.application.Platform;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.text.*;
import de.jensd.fx.fontawesome.AwesomeDude;
import de.jensd.fx.fontawesome.AwesomeIcon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Convenience Component for info icon, info text and link display in a GridPane.
* Only the properties needed are supported.
* We need to extend from Parent so we can use it in FXML, but the InfoDisplay is not used as node,
* but add the children nodes to the gridPane.
*/
public class InfoDisplay2 extends Parent {
private static final Logger log = LoggerFactory.getLogger(InfoDisplay2.class);
private final StringProperty text = new SimpleStringProperty();
private final IntegerProperty rowIndex = new SimpleIntegerProperty(0);
private final IntegerProperty columnIndex = new SimpleIntegerProperty(0);
private final ObjectProperty<EventHandler<ActionEvent>> onAction = new SimpleObjectProperty<>();
private final ObjectProperty<GridPane> gridPane = new SimpleObjectProperty<>();
private final Label testLabel;
private boolean useReadMore;
private final Label icon = AwesomeDude.createIconLabel(AwesomeIcon.INFO_SIGN);
private final TextFlow textFlow;
private final Label label;
private final Hyperlink link;
private final ChangeListener<Number> listener;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
public InfoDisplay2() {
icon.setId("non-clickable-icon");
icon.visibleProperty().bind(visibleProperty());
GridPane.setValignment(icon, VPos.TOP);
GridPane.setMargin(icon, new Insets(-2, 0, 0, 0));
GridPane.setRowSpan(icon, 2);
label = new Label();
label.textProperty().bind(text);
label.setTextOverrun(OverrunStyle.WORD_ELLIPSIS);
// width is set a frame later so we hide it first
label.setVisible(false);
link = new Hyperlink(BSResources.get("shared.readMore"));
link.setPadding(new Insets(0, 0, 0, -2));
// We need that to know if we have a wrapping or not.
// Did not find a way to get that from the API.
testLabel = new Label();
testLabel.textProperty().bind(text);
textFlow = new TextFlow();
textFlow.visibleProperty().bind(visibleProperty());
textFlow.getChildren().addAll(testLabel);
// update the width when the window gets resized
listener = (ov2, oldValue2, windowWidth) -> {
if (label.prefWidthProperty().isBound())
label.prefWidthProperty().unbind();
label.setPrefWidth((double) windowWidth - localToScene(0, 0).getX() - 35);
};
// when clicking "Read more..." we expand and change the link to the Help
link.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
if (useReadMore) {
label.setWrapText(true);
link.setText(BSResources.get("shared.openHelp"));
getScene().getWindow().widthProperty().removeListener(listener);
if (label.prefWidthProperty().isBound())
label.prefWidthProperty().unbind();
label.prefWidthProperty().bind(textFlow.widthProperty());
link.setVisited(false);
// focus border is a bit confusing here so we remove it
link.setStyle("-fx-focus-color: transparent;");
link.setOnAction(onAction.get());
}
else {
onAction.get().handle(actionEvent);
}
}
});
managedProperty().addListener((ov, oldValue, newValue) -> {
if (newValue)
layoutItems();
});
}
private void layoutItems() {
testLabel.widthProperty().addListener((ov, o, n) -> {
log.debug("#### testLabel.heightProperty " + testLabel.getHeight());
log.debug("#### testLabel.widthProperty " + testLabel.getText());
log.debug("#### testLabel.widthProperty " + n);
log.debug("#### textFlow.getWidth() " + textFlow.getWidth());
useReadMore = (double) n > textFlow.getWidth();
link.setText(BSResources.get(useReadMore ? "shared.readMore" : "shared.openHelp"));
Platform.runLater(() -> textFlow.getChildren().setAll(label, link));
});
sceneProperty().addListener((ov, oldValue, newValue) -> {
if (oldValue == null && newValue != null && newValue.getWindow() != null) {
newValue.getWindow().widthProperty().addListener(listener);
// localToScene does deliver 0 instead of the correct x position when scene property gets set,
// so we delay for 1 render cycle
Platform.runLater(() -> {
log.debug("#### label.setVisible() ");
label.setVisible(true);
label.prefWidthProperty().unbind();
label.setPrefWidth(newValue.getWindow().getWidth() - localToScene(0, 0).getX() - 35);
});
}
});
}
///////////////////////////////////////////////////////////////////////////////////////////
// Setters
///////////////////////////////////////////////////////////////////////////////////////////
public void setText(String text) {
this.text.set(text);
layout();
}
public void setGridPane(GridPane gridPane) {
this.gridPane.set(gridPane);
gridPane.getChildren().addAll(icon, textFlow);
GridPane.setColumnIndex(icon, columnIndex.get());
GridPane.setColumnIndex(textFlow, columnIndex.get() + 1);
GridPane.setRowIndex(icon, rowIndex.get());
GridPane.setRowIndex(textFlow, rowIndex.get());
}
public void setRowIndex(int rowIndex) {
this.rowIndex.set(rowIndex);
GridPane.setRowIndex(icon, rowIndex);
GridPane.setRowIndex(textFlow, rowIndex);
}
public void setColumnIndex(int columnIndex) {
this.columnIndex.set(columnIndex);
GridPane.setColumnIndex(icon, columnIndex);
GridPane.setColumnIndex(textFlow, columnIndex + 1);
}
public final void setOnAction(EventHandler<ActionEvent> eventHandler) {
onAction.set(eventHandler);
}
///////////////////////////////////////////////////////////////////////////////////////////
// Getters
///////////////////////////////////////////////////////////////////////////////////////////
public String getText() {
return text.get();
}
public StringProperty textProperty() {
return text;
}
public int getColumnIndex() {
return columnIndex.get();
}
public IntegerProperty columnIndexProperty() {
return columnIndex;
}
public int getRowIndex() {
return rowIndex.get();
}
public IntegerProperty rowIndexProperty() {
return rowIndex;
}
public EventHandler<ActionEvent> getOnAction() {
return onAction.get();
}
public ObjectProperty<EventHandler<ActionEvent>> onActionProperty() {
return onAction;
}
public GridPane getGridPane() {
return gridPane.get();
}
public ObjectProperty<GridPane> gridPaneProperty() {
return gridPane;
}
}

View file

@ -0,0 +1,105 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.components.dialogs;
import io.bitsquare.gui.OverlayManager;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CustomPopups {
private static final Logger log = LoggerFactory.getLogger(CustomPopups.class);
private final Stage rootStage;
private final OverlayManager overlayManager;
private final Stage stage = new Stage();
private StackPane sceneRootPane;
public CustomPopups(Stage rootStage, OverlayManager overlayManager) {
this.rootStage = rootStage;
this.overlayManager = overlayManager;
setupStage();
}
public void showInfoPopup(String title, String message) {
BorderPane borderPane = new BorderPane();
borderPane.setMinWidth(400);
borderPane.setMinHeight(150);
borderPane.setMaxWidth(rootStage.getWidth() / 2);
borderPane.setMaxHeight(rootStage.getHeight() / 2);
borderPane.setPadding(new Insets(20, 20, 20, 20));
borderPane.setStyle("-fx-background-color: #ffffff;");
Label titleLabel = new Label(title);
titleLabel.setMouseTransparent(true);
BorderPane.setAlignment(titleLabel, Pos.TOP_CENTER);
borderPane.setTop(titleLabel);
titleLabel.setStyle("-fx-font-size: 16; -fx-font-weight: bold; -fx-text-fill: #333333;");
Label messageLabel = new Label(message);
messageLabel.setWrapText(true);
messageLabel.setMouseTransparent(true);
borderPane.setCenter(messageLabel);
messageLabel.setStyle("-fx-font-size: 12; -fx-text-fill: #000000;");
messageLabel.setPadding(new Insets(20, 0, 30, 0));
Button closeButton = getCloseButton();
BorderPane.setAlignment(closeButton, Pos.BOTTOM_RIGHT);
borderPane.setBottom(closeButton);
show(borderPane);
}
private void setupStage() {
stage.initModality(Modality.WINDOW_MODAL);
stage.initStyle(StageStyle.UNDECORATED);
stage.initOwner(rootStage);
sceneRootPane = new StackPane();
Scene scene = new Scene(sceneRootPane);
scene.getStylesheets().setAll(getClass().getResource("/io/bitsquare/gui/bitsquare.css").toExternalForm(),
getClass().getResource("/io/bitsquare/gui/images.css").toExternalForm());
stage.setScene(scene);
}
private void hide() {
stage.hide();
}
private void show(Pane pane) {
sceneRootPane.getChildren().setAll(pane);
stage.show();
}
private Button getCloseButton() {
Button closeButton = new Button("Close");
closeButton.setDefaultButton(true);
closeButton.setOnAction(e -> hide());
return closeButton;
}
}

View file

@ -0,0 +1,131 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.gui.components.dialogs;
import io.bitsquare.locale.BSResources;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import org.controlsfx.control.ButtonBar;
import org.controlsfx.control.action.AbstractAction;
import org.controlsfx.control.action.Action;
import org.controlsfx.dialog.Dialog;
import org.controlsfx.dialog.DialogStyle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// TODO under construction
public class InfoDialog {
private static final Logger log = LoggerFactory.getLogger(InfoDialog.class);
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////////////////
@Inject
public InfoDialog(Stage stage) {
final TextField username = new TextField();
final PasswordField password = new PasswordField();
final Action actionLogin = new AbstractAction("Login") {
// This method is called when the login button is clicked ...
public void handle(ActionEvent ae) {
Dialog d = (Dialog) ae.getSource();
// Do the login here.
d.hide();
}
};
// Create the custom dialog.
Dialog dlg = new Dialog(stage, "Login Dialog");
dlg.setIconifiable(false);
dlg.setClosable(false);
dlg.setResizable(false);
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(0, 10, 0, 10));
username.setPromptText("Username");
password.setPromptText("Password");
grid.add(new Label("Username:"), 0, 0);
grid.add(username, 1, 0);
grid.add(new Label("Password:"), 0, 1);
grid.add(password, 1, 1);
ButtonBar.setType(actionLogin, ButtonBar.ButtonType.OK_DONE);
actionLogin.disabledProperty().set(true);
// Do some validation (using the Java 8 lambda syntax).
username.textProperty().addListener((observable, oldValue, newValue) -> actionLogin.disabledProperty().set(newValue.trim().isEmpty()));
dlg.setMasthead("Look, a Custom Login Dialog");
dlg.setContent(grid);
dlg.getActions().addAll(actionLogin, Dialog.Actions.CANCEL);
// Request focus on the username field by default.
Platform.runLater(username::requestFocus);
dlg.show();
}
///////////////////////////////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////////////////////////////
public void show(Object owner, String title, String masthead, String message) {
Dialog dlg = new Dialog(owner, title, false, DialogStyle.CROSS_PLATFORM_DARK);
dlg.setResizable(false);
dlg.setIconifiable(false);
dlg.setClosable(false);
Image image = new Image(InfoDialog.class.getResource
("/impl/org/controlsfx/dialog/resources/oxygen/48/dialog-information.png").toString());
if (image != null) {
dlg.setGraphic(new ImageView(image));
}
dlg.setMasthead(masthead);
List<Action> actions = new ArrayList<>();
actions.add(new AbstractAction(BSResources.get("shared.close")) {
@Override
public void handle(ActionEvent actionEvent) {
getProperties().put("type", "CLOSE");
Dialog.Actions.CLOSE.handle(actionEvent);
// overlayManager.removeBlurContent();
}
});
dlg.getActions().addAll(actions);
// dlg.setBackgroundEffect(backgroundEffect);
}
}

View file

@ -149,6 +149,8 @@ class MainViewModel implements ViewModel {
}
public void initBackend() {
Platform.runLater(() -> updateProcess.init());
setBitcoinNetworkSyncProgress(-1);
walletService.getDownloadProgress().subscribe(
percentage -> Platform.runLater(() -> {
@ -195,16 +197,16 @@ class MainViewModel implements ViewModel {
log.trace("updateProcess completed");
});
Observable<?> backEnd = Observable.merge(message, wallet, updateProcess);
backEnd.subscribe(
Observable<?> allTasks = Observable.merge(message, wallet, updateProcess);
allTasks.subscribe(
next -> {
},
error -> log.error(error.toString()),
() -> Platform.runLater(() -> backEndCompleted())
() -> Platform.runLater(() -> allTasksCompleted())
);
}
private void backEndCompleted() {
private void allTasksCompleted() {
log.trace("backend completed");
tradeManager.getPendingTrades().addListener(

Some files were not shown because too many files have changed in this diff Show more