Commit dca6c0ba authored by Axel Howind's avatar Axel Howind

initial import

parents
FROM ubuntu:18.04
#
# UTF-8 by default
#
RUN apt-get -qq update && \
apt-get -qqy install gnupg2 locales && \
locale-gen en_US.UTF-8 && \
rm -rf /var/lib/apt/lists/*
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
#
# Pull Zulu OpenJDK binaries from official repository:
#
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9 && \
echo "deb http://repos.azulsystems.com/ubuntu stable main" >> /etc/apt/sources.list.d/zulu.list && \
apt-get -qq update && \
apt-get -qqy install zulu-11=11.2+3 && \
rm -rf /var/lib/apt/lists/*
plugins {
id 'com.github.spotbugs' version '1.6.8' apply false
id 'com.dua3.gradle.jpms' version '0.5.1' apply false
id 'com.jfrog.bintray' version '1.8.4' apply false
}
subprojects {
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: 'eclipse'
apply plugin: 'com.github.spotbugs'
apply plugin: 'com.dua3.gradle.jpms'
apply plugin: 'com.jfrog.bintray'
/////////////////////////////////////////////////////////////////////////////
group = 'com.dua3.fx'
version = '0.2'
ext.moduleName = project.group
ext.scm = ''
ext.repo = 'private'
ext.description = 'Java FX application utilities'
ext.developerId = 'axh'
ext.developerName = 'Axel Howind'
ext.developerEmail = 'axel@dua3.com'
/////////////////////////////////////////////////////////////////////////////
repositories {
jcenter()
maven { url "https://dl.bintray.com/dua3/public" }
mavenLocal()
}
// get OS (because JavaFX packages are OS dependent)
def currentOS = org.gradle.internal.os.OperatingSystem.current()
def platform
if (currentOS.isWindows()) {
platform = 'win'
} else if (currentOS.isLinux()) {
platform = 'linux'
} else if (currentOS.isMacOsX()) {
platform = 'mac'
}
dependencies {
implementation "com.dua3.utility:utility:2.0"
// JavaFX
def javafxversion = '11.0.1'
api "org.openjfx:javafx-base:${javafxversion}:${platform}"
api "org.openjfx:javafx-fxml:${javafxversion}:${platform}"
api "org.openjfx:javafx-graphics:${javafxversion}:${platform}"
api "org.openjfx:javafx-controls:${javafxversion}:${platform}"
api "org.openjfx:javafx-web:${javafxversion}:${platform}"
api "org.openjfx:javafx-media:${javafxversion}:${platform}"
// JUnit
def junitVersion = '5.3.1'
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
}
test {
useJUnitPlatform()
filter {
exclude '**/module-info.class'
}
}
javadoc {
doFirst {
options.addStringOption('-module-path', classpath.asPath)
}
}
sourceCompatibility = 11
targetCompatibility = 11
// === BINTRAY === >
bintray {
user = findProperty('BINTRAY_USER') ?: 'NONE'
key = findProperty('BINTRAY_KEY') ?: 'NONE'
configurations = ['archives']
dryRun = false //[Default: false] Whether to run this as dry-run, without deploying
publish = true //[Default: false] Whether version should be auto published after an upload
override = true //[Default: false] Whether to override version artifacts already published
pkg {
repo = project.repo
name = project.group
userOrg = findProperty('BINTRAY_USER_ORG') ?: 'NONE'
licenses = ['Apache-2.0']
vcsUrl = project.scm
version {
name = project.version
desc = project.name+version
released = new Date()
vcsTag = project.version
}
}
}
// === ARTIFACTS === >
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives jar
archives sourcesJar
archives javadocJar
}
// === MAVEN publication === >
// Create the pom configuration:
def pomConfig = {
licenses {
license {
name "The Apache Software License, Version 2.0"
url "http://www.apache.org/licenses/LICENSE-2.0.txt"
}
}
developers {
developer {
id project.developerId
name project.developerName
email project.developerEmail
}
}
scm {
url project.scm
}
}
// Create the publication with the pom configuration:
publishing {
publications {
Publication(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
groupId project.group
artifactId project.name
version version
pom.withXml {
def root = asNode()
root.appendNode('description', project.description)
root.appendNode('name', project.group)
root.appendNode('url', project.scm)
root.children().last() + pomConfig
}
}
}
}
// === SPOTBUGS === >
spotbugs.toolVersion = '3.1.10'
tasks.withType(com.github.spotbugs.SpotBugsTask) {
reports {
xml.enabled false
html.enabled true
}
// ignore failures until spotbugs bug is fixed: https://github.com/spotbugs/spotbugs/issues/756
ignoreFailures = true
}
// === DEFAULT TASKS === >
defaultTasks 'build', 'publishToMavenLocal', 'install'
}
\ No newline at end of file
#!/bin/bash
function die () {
echo $*
exit 1
}
pushd .
cd `dirname $0`
for P in utility fx.app fx.editors fx.samples query ; do
echo "building ${P} ..."
( cd "${P}" && ./gradlew && echo "${P}: OK." ) || die "${P}: FAIL."
done
popd
dependencies {
implementation "com.dua3.utility:utility:2.0"
}
package com.dua3.fx.app;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.Objects;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.dua3.utility.lang.LangUtil;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
public abstract class FxApp<A extends FxApp<A, C>, C extends FxController<A, C>> extends Application {
// - constants -
/** The command line argument to set the logging level (i.e. "--log=FINE"). */
public static final String ARG_LOG_LEVEL = "log";
/** Marker to indicate modified state in title. */
private static final String MARKER_MODIFIED = "*";
/** Marker to indicate unmodified state in title. */
private static final String MARKER_UNMODIFIED = " ";
// - static -
/** Logger */
protected static final Logger LOG = Logger.getLogger(FxApp.class.getSimpleName());
// - instance -
/** The application name. */
private final String applicationName;
/** Path to FXML file. */
private final String fxmlFile;
/** The controller instance. */
private C controller;
/** The main stage. */
private Stage stage;
// - UI -
// - static initialization -
// - Code -
/**
* Constructor.
*
* @param applicationName the name of the application to show in title bar
* @param fxmlFile the path to the FXML file to load, relative to the
* application class
*/
protected FxApp(String applicationName, String fxmlFile) {
this.applicationName = Objects.requireNonNull(applicationName);
this.fxmlFile = Objects.requireNonNull(fxmlFile);
}
/**
* Get named parameter value.
*
* Named parameters are command line arguments of the form "--parameter=value".
*
* @param name the parameter name
* @return an Optional holding the parameter value if present
*/
public Optional<String> getParameterValue(String name) {
return Optional.ofNullable(getParameters().getNamed().get(name));
}
/**
* Check if an unnamed parameter is present.
*
* @param name the parameter name
* @return true, if the parameter is present
*/
public boolean hasParameter(String name) {
return getParameters().getUnnamed().contains(name);
}
/**
* Initialize User Interface. The layout is defined in FXML.
*/
@SuppressWarnings("unchecked")
@Override
public void start(Stage stage) throws IOException {
LOG.log(Level.FINE, () -> "starting application ...");
// store reference to stage
this.stage = stage;
// handle program arguments
getParameterValue("log").ifPresent(level -> LangUtil.setLogLevel(Level.parse(level)));
// create a loader and load FXML
LOG.log(Level.FINE, () -> "loading FXML ...");
URL fxmlUrl = LangUtil.getResourceURL(getClass(), fxmlFile);
LOG.log(Level.FINER, () -> "FXML URL: " + fxmlUrl);
FXMLLoader loader = new FXMLLoader(fxmlUrl);
Parent root = loader.load();
// set controller
LOG.log(Level.FINER, () -> "setting FXML controller ...");
this.controller = Objects.requireNonNull(loader.getController(),
"controller is null; set fx:controller in root element of FXML (" + fxmlFile + ")");
this.controller.setApp((A) this);
// create scene
Scene scene = new Scene(root);
// setup stage
stage.setTitle(applicationName);
stage.setScene(scene);
stage.show();
// automatically update title on document change
controller.documentProperty().addListener((v,o,n) -> updateApplicationTitle());
controller.dirtyProperty().addListener((v,o,n) -> updateApplicationTitle());
LOG.fine(() -> "done.");
}
protected void updateApplicationTitle() {
URI doc = controller.getDocument();
String name = controller.hasDocument() ? doc.getPath() : "";
boolean dirty = controller.isDirty();
StringBuilder title = new StringBuilder();
title.append(applicationName);
if (!name.isEmpty()) {
title.append(" - ");
}
String marker = dirty ? MARKER_MODIFIED : MARKER_UNMODIFIED;
title.append(marker).append(name).append(marker);
stage.setTitle(title.toString());
}
public void close() {
stage.fireEvent(new WindowEvent(stage, javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST));
}
/**
* Get the stage.
* @return
* the application's primary stage
*/
public Stage getStage() {
return stage;
}
}
package com.dua3.fx.app;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Objects;
import java.util.logging.Logger;
import com.dua3.utility.lang.LangUtil;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;