You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by se...@apache.org on 2015/07/27 19:27:43 UTC
[7/7] incubator-ignite git commit: IGNITE-1155 Extract
ignite-schema-import-ui module.
IGNITE-1155 Extract ignite-schema-import-ui module.
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/e8d71b55
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/e8d71b55
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/e8d71b55
Branch: refs/heads/ignite-1155
Commit: e8d71b5523f8898d7a67a07f1b311c6f4cb19186
Parents: d5925e6
Author: sevdokimov <se...@gridgain.com>
Authored: Mon Jul 27 20:26:19 2015 +0300
Committer: sevdokimov <se...@gridgain.com>
Committed: Mon Jul 27 20:26:19 2015 +0300
----------------------------------------------------------------------
modules/schema-import-ui/pom.xml | 110 ++
.../main/java/media/data_connection_48x48.png | Bin 0 -> 4443 bytes
.../src/main/java/media/error_48x48.png | Bin 0 -> 4349 bytes
.../src/main/java/media/ignite_128x128.png | Bin 0 -> 4917 bytes
.../src/main/java/media/ignite_16x16.png | Bin 0 -> 608 bytes
.../src/main/java/media/ignite_24x24.png | Bin 0 -> 930 bytes
.../src/main/java/media/ignite_32x32.png | Bin 0 -> 1203 bytes
.../src/main/java/media/ignite_48x48.png | Bin 0 -> 1868 bytes
.../src/main/java/media/ignite_64x64.png | Bin 0 -> 2453 bytes
.../src/main/java/media/information_48x48.png | Bin 0 -> 4102 bytes
.../src/main/java/media/question_48x48.png | Bin 0 -> 3857 bytes
.../src/main/java/media/sign_warning_48x48.png | Bin 0 -> 2988 bytes
.../src/main/java/media/style.css | 134 ++
.../src/main/java/media/text_tree_48x48.png | Bin 0 -> 2567 bytes
.../ignite/schema/ui/ConfirmCallable.java | 103 +
.../org/apache/ignite/schema/ui/Controls.java | 692 +++++++
.../org/apache/ignite/schema/ui/GridPaneEx.java | 177 ++
.../apache/ignite/schema/ui/JavaFxUtils.java | 122 ++
.../org/apache/ignite/schema/ui/MessageBox.java | 261 +++
.../apache/ignite/schema/ui/ModalDialog.java | 50 +
.../ignite/schema/ui/SchemaImportApp.java | 1768 ++++++++++++++++++
.../ignite/schema/ui/TextColumnValidator.java | 32 +
.../schema/test/AbstractSchemaImportTest.java | 132 ++
.../test/generator/CodeGeneratorTest.java | 70 +
.../schema/test/generator/XmlGeneratorTest.java | 50 +
.../apache/ignite/schema/test/model/Objects.txt | 502 +++++
.../ignite/schema/test/model/ObjectsKey.txt | 96 +
.../ignite/schema/test/model/Primitives.txt | 506 +++++
.../ignite/schema/test/model/PrimitivesKey.txt | 96 +
.../schema/test/model/ignite-type-metadata.xml | 362 ++++
.../test/parser/DbMetadataParserTest.java | 118 ++
.../testsuites/IgniteSchemaImportTestSuite.java | 41 +
modules/schema-import/pom.xml | 34 -
.../main/java/media/data_connection_48x48.png | Bin 4443 -> 0 bytes
.../src/main/java/media/error_48x48.png | Bin 4349 -> 0 bytes
.../src/main/java/media/ignite_128x128.png | Bin 4917 -> 0 bytes
.../src/main/java/media/ignite_16x16.png | Bin 608 -> 0 bytes
.../src/main/java/media/ignite_24x24.png | Bin 930 -> 0 bytes
.../src/main/java/media/ignite_32x32.png | Bin 1203 -> 0 bytes
.../src/main/java/media/ignite_48x48.png | Bin 1868 -> 0 bytes
.../src/main/java/media/ignite_64x64.png | Bin 2453 -> 0 bytes
.../src/main/java/media/information_48x48.png | Bin 4102 -> 0 bytes
.../src/main/java/media/question_48x48.png | Bin 3857 -> 0 bytes
.../src/main/java/media/sign_warning_48x48.png | Bin 2988 -> 0 bytes
.../schema-import/src/main/java/media/style.css | 134 --
.../src/main/java/media/text_tree_48x48.png | Bin 2567 -> 0 bytes
.../ignite/schema/generator/CodeGenerator.java | 17 +-
.../schema/generator/ConfirmOverride.java | 42 +
.../ignite/schema/generator/XmlGenerator.java | 13 +-
.../ignite/schema/model/PojoDescriptor.java | 34 +-
.../apache/ignite/schema/model/PojoField.java | 62 +-
.../schema/parser/DatabaseMetadataParser.java | 5 +-
.../ignite/schema/ui/ConfirmCallable.java | 81 -
.../org/apache/ignite/schema/ui/Controls.java | 643 -------
.../org/apache/ignite/schema/ui/GridPaneEx.java | 177 --
.../org/apache/ignite/schema/ui/MessageBox.java | 261 ---
.../apache/ignite/schema/ui/ModalDialog.java | 50 -
.../ignite/schema/ui/SchemaImportApp.java | 1764 -----------------
.../ignite/schema/ui/TextColumnValidator.java | 32 -
.../ignite/schema/utils/ChangeListener.java | 30 +
.../apache/ignite/schema/utils/Property.java | 84 +
.../schema/test/AbstractSchemaImportTest.java | 134 --
.../test/generator/CodeGeneratorTest.java | 70 -
.../schema/test/generator/XmlGeneratorTest.java | 50 -
.../apache/ignite/schema/test/model/Objects.txt | 502 -----
.../ignite/schema/test/model/ObjectsKey.txt | 96 -
.../ignite/schema/test/model/Primitives.txt | 506 -----
.../ignite/schema/test/model/PrimitivesKey.txt | 96 -
.../schema/test/model/ignite-type-metadata.xml | 362 ----
.../test/parser/DbMetadataParserTest.java | 118 --
.../testsuites/IgniteSchemaImportTestSuite.java | 41 -
71 files changed, 5639 insertions(+), 5221 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/pom.xml
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/pom.xml b/modules/schema-import-ui/pom.xml
new file mode 100644
index 0000000..c56d050
--- /dev/null
+++ b/modules/schema-import-ui/pom.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+ POM file.
+-->
+<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>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-parent</artifactId>
+ <version>1</version>
+ <relativePath>../../parent</relativePath>
+ </parent>
+
+ <artifactId>ignite-schema-import-ui</artifactId>
+ <version>1.4.1-SNAPSHOT</version>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.ignite</groupId>
+ <artifactId>ignite-schema-import</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ <version>1.3.175</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/java</directory>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </resource>
+ </resources>
+
+ <testResources>
+ <testResource>
+ <directory>src/test/java</directory>
+ <excludes>
+ <exclude>**/*.java</exclude>
+ </excludes>
+ </testResource>
+ </testResources>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>org.apache.ignite.schema.ui.SchemaImportApp</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <profiles>
+ <profile>
+ <id>schema-import</id>
+ <activation>
+ <file>
+ <exists>${java.home}/lib/jfxrt.jar</exists>
+ </file>
+ </activation>
+ <dependencies>
+ <dependency>
+ <groupId>javafx</groupId>
+ <artifactId>jfxrt</artifactId>
+ <version>${java.version}</version>
+ <scope>system</scope>
+ <systemPath>${java.home}/lib/jfxrt.jar</systemPath>
+ </dependency>
+ </dependencies>
+ </profile>
+ </profiles>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/data_connection_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/data_connection_48x48.png b/modules/schema-import-ui/src/main/java/media/data_connection_48x48.png
new file mode 100644
index 0000000..475f219
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/data_connection_48x48.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/error_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/error_48x48.png b/modules/schema-import-ui/src/main/java/media/error_48x48.png
new file mode 100644
index 0000000..e341b8a
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/error_48x48.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/ignite_128x128.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/ignite_128x128.png b/modules/schema-import-ui/src/main/java/media/ignite_128x128.png
new file mode 100644
index 0000000..d99a83c
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/ignite_128x128.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/ignite_16x16.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/ignite_16x16.png b/modules/schema-import-ui/src/main/java/media/ignite_16x16.png
new file mode 100644
index 0000000..3e07d33
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/ignite_16x16.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/ignite_24x24.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/ignite_24x24.png b/modules/schema-import-ui/src/main/java/media/ignite_24x24.png
new file mode 100644
index 0000000..8da5c97
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/ignite_24x24.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/ignite_32x32.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/ignite_32x32.png b/modules/schema-import-ui/src/main/java/media/ignite_32x32.png
new file mode 100644
index 0000000..c6c6819
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/ignite_32x32.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/ignite_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/ignite_48x48.png b/modules/schema-import-ui/src/main/java/media/ignite_48x48.png
new file mode 100644
index 0000000..5b684cc
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/ignite_48x48.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/ignite_64x64.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/ignite_64x64.png b/modules/schema-import-ui/src/main/java/media/ignite_64x64.png
new file mode 100644
index 0000000..c1d348b
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/ignite_64x64.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/information_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/information_48x48.png b/modules/schema-import-ui/src/main/java/media/information_48x48.png
new file mode 100644
index 0000000..8712a1b
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/information_48x48.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/question_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/question_48x48.png b/modules/schema-import-ui/src/main/java/media/question_48x48.png
new file mode 100644
index 0000000..84683f9
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/question_48x48.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/sign_warning_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/sign_warning_48x48.png b/modules/schema-import-ui/src/main/java/media/sign_warning_48x48.png
new file mode 100644
index 0000000..5e7cccd
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/sign_warning_48x48.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/style.css
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/style.css b/modules/schema-import-ui/src/main/java/media/style.css
new file mode 100644
index 0000000..6eee5f9
--- /dev/null
+++ b/modules/schema-import-ui/src/main/java/media/style.css
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.root {
+ -fx-background-color: eeeeee;
+}
+
+.button {
+ -fx-font-size: 14;
+ -fx-focus-color: gray;
+}
+
+.label {
+ -fx-font-size: 14;
+}
+
+.check-box {
+ -fx-font-size: 14;
+ -fx-focus-color: gray;
+}
+
+.combo-box-base {
+ -fx-font-size: 14;
+ -fx-focus-color: gray;
+}
+
+.combo-box-popup .list-view {
+ -fx-font-size : 14;
+}
+
+.text-area {
+ -fx-font-size: 14;
+ -fx-background-color: transparent, transparent, transparent;
+}
+
+.text-area .scroll-pane {
+ -fx-background-color: transparent;
+}
+
+.text-area .scroll-pane .viewport{
+ -fx-background-color: transparent;
+}
+
+.text-area .scroll-pane .content{
+ -fx-background-color: transparent;
+}
+
+.text-area .scroll-bar:vertical:disabled {
+ -fx-opacity: 0;
+}
+
+.text-field {
+ -fx-font-size: 14;
+ -fx-background-color: -fx-text-box-border, -fx-control-inner-background, -fx-control-inner-background;
+}
+
+.text-field:focused {
+ -fx-background-color: -fx-text-box-border, -fx-control-inner-background, -fx-control-inner-background;
+}
+
+.table-view {
+ -fx-focus-color: gray;
+ -fx-font-size: 14;
+}
+
+.table-view .table-row-cell:selected {
+ -fx-background-color: -fx-table-cell-border-color, -fx-cell-hover-color;
+ -fx-background-insets: 0, 0 0 1 0;
+}
+
+.table-view:focused .table-row-cell:selected {
+ -fx-background-color: -fx-focus-color, -fx-cell-focus-inner-border, -fx-selection-bar;
+}
+
+.table-row-cell:empty {
+ -fx-background-color: white;
+}
+
+.table-row-cell:empty .table-cell {
+ -fx-border-width: 0px;
+}
+
+.tooltip {
+ -fx-font-size: 14;
+ -fx-background-radius: 0 0 0 0;
+}
+
+.page-corner {
+ -fx-shape: " ";
+}
+
+.progress-indicator {
+ -fx-progress-color: gray
+}
+
+.split-pane {
+ -fx-background-color: -fx-box-border, eeeeee;
+}
+
+.titled-pane {
+ -fx-font-size: 14;
+}
+
+.titled-pane:focused {
+ -fx-text-fill: -fx-text-base-color;
+}
+
+.titled-pane:focused > .title {
+ -fx-color: eeeeee;
+}
+
+.titled-pane:focused > .title > .arrow-button .arrow {
+ -fx-background-color: black;
+}
+
+#banner {
+ -fx-font-size: 20px;
+ -fx-font-weight: bold;
+ -fx-background-color: white
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/media/text_tree_48x48.png
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/media/text_tree_48x48.png b/modules/schema-import-ui/src/main/java/media/text_tree_48x48.png
new file mode 100644
index 0000000..6ca9e65
Binary files /dev/null and b/modules/schema-import-ui/src/main/java/media/text_tree_48x48.png differ
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/ConfirmCallable.java
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/ConfirmCallable.java b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/ConfirmCallable.java
new file mode 100644
index 0000000..92340d0
--- /dev/null
+++ b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/ConfirmCallable.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.schema.ui;
+
+import javafx.application.*;
+import javafx.stage.*;
+import org.apache.ignite.schema.generator.*;
+
+import java.util.concurrent.*;
+
+import static org.apache.ignite.schema.ui.MessageBox.Result.*;
+
+/**
+ * Callable to ask user for confirmation from non EDT thread.
+ */
+public class ConfirmCallable implements Callable<MessageBox.Result>, ConfirmOverride {
+ /** Owner window. */
+ private final Stage owner;
+
+ /** Message template. */
+ private final String template;
+
+ /** Message to show in confirmation dialog. */
+ private String msg;
+
+ /** User choice. */
+ private MessageBox.Result choice = NO;
+
+ /**
+ * @param owner Owner window.
+ * @param template Message template.
+ */
+ public ConfirmCallable(Stage owner, String template) {
+ this.owner = owner;
+ this.template = template;
+ }
+
+ /** {@inheritDoc} */
+ @Override public MessageBox.Result call() throws Exception {
+ choice = MessageBox.applyToAllChoiceDialog(owner, String.format(template, msg));
+
+ return choice;
+ }
+
+ /**
+ * Execute confirmation in EDT thread.
+ *
+ * @return Confirm result.
+ */
+ public ConfirmOverride.Result confirm(String msg) {
+ this.msg = msg;
+
+ if (choice == YES_TO_ALL)
+ return Result.OVERRIDE;
+
+ if (choice == NO_TO_ALL)
+ return Result.NO;
+
+ FutureTask<MessageBox.Result> fut = new FutureTask<>(this);
+
+ Platform.runLater(fut);
+
+ MessageBox.Result res;
+
+ try {
+ res = fut.get();
+ }
+ catch (Exception ignored) {
+ return Result.NO;
+ }
+
+ switch (res) {
+ case CANCEL:
+ return Result.CANCEL;
+
+ case NO:
+ case NO_TO_ALL:
+ return Result.NO;
+
+ case YES:
+ case YES_TO_ALL:
+ return Result.OVERRIDE;
+
+ default:
+ throw new RuntimeException("Unknown result: " + res);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/Controls.java
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/Controls.java b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/Controls.java
new file mode 100644
index 0000000..075a84b
--- /dev/null
+++ b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/Controls.java
@@ -0,0 +1,692 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.schema.ui;
+
+import com.sun.javafx.scene.control.skin.*;
+import javafx.application.*;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.*;
+import javafx.collections.*;
+import javafx.event.*;
+import javafx.geometry.*;
+import javafx.scene.*;
+import javafx.scene.control.*;
+import javafx.scene.control.cell.*;
+import javafx.scene.image.*;
+import javafx.scene.input.*;
+import javafx.scene.layout.*;
+import javafx.scene.text.*;
+import javafx.util.*;
+import javafx.util.converter.*;
+import org.apache.ignite.schema.utils.*;
+
+import java.lang.reflect.*;
+
+/**
+ * Utility class to create controls.
+ */
+public class Controls {
+ /** */
+ public static final Insets DFLT_PADDING = new Insets(10, 10, 10, 10);
+
+ /**
+ * Create scene with predefined style.
+ *
+ * @param root The root node of the scene graph.
+ * @return New {@code Scene} instance.
+ */
+ public static Scene scene(Parent root) {
+ Scene scene = new Scene(root);
+
+ scene.getStylesheets().add("media/style.css");
+
+ return scene;
+ }
+
+ /**
+ * Create grid pane with default padding.
+ *
+ * @param top Top padding
+ * @param right Right padding.
+ * @param bottom Bottom padding.
+ * @param left Left padding.
+ * @return New {@code GridPaneEx} instance.
+ */
+ public static GridPaneEx paneEx(double top, double right, double bottom, double left) {
+ GridPaneEx paneEx = new GridPaneEx();
+
+ paneEx.setPadding(new Insets(top, right, bottom, left));
+
+ return paneEx;
+ }
+
+ /**
+ * Create new {@code HBox} with default padding.
+ *
+ * @param spacing Amount of horizontal space between each child.
+ * @param dfltPadding If {@code true} than set default padding for pane.
+ * @return New {@code HBox} instance.
+ */
+ public static HBox hBox(int spacing, boolean dfltPadding) {
+ HBox hb = new HBox(spacing);
+
+ if (dfltPadding)
+ hb.setPadding(DFLT_PADDING);
+
+ return hb;
+ }
+
+ /**
+ * Create new {@code HBox} with default padding and add controls.
+ *
+ * @param spacing Amount of horizontal space between each child.
+ * @param dfltPadding If {@code true} than set default padding for pane.
+ * @param controls Controls to add.
+ * @return New {@code HBox} instance.
+ */
+ public static HBox hBox(int spacing, boolean dfltPadding, Node... controls) {
+ HBox hb = hBox(spacing, dfltPadding);
+
+ hb.getChildren().addAll(controls);
+
+ return hb;
+ }
+
+ /**
+ * Create new {@code VBox} with default padding.
+ *
+ * @param spacing Amount of horizontal space between each child.
+ * @return New {@code VBox} instance.
+ */
+ public static VBox vBox(int spacing) {
+ VBox vb = new VBox(spacing);
+
+ vb.setPadding(DFLT_PADDING);
+
+ return vb;
+ }
+
+ /**
+ * Create new {@code VBox} with default padding and add controls.
+ *
+ * @param spacing Amount of horizontal space between each child.
+ * @param controls Controls to add.
+ * @return New {@code VBox} instance.
+ */
+ public static VBox vBox(int spacing, Node... controls) {
+ VBox vb = vBox(spacing);
+
+ vb.getChildren().addAll(controls);
+
+ return vb;
+ }
+
+ /**
+ * Create stack pane.
+ *
+ * @param controls Controls to add.
+ * @return New {@code StackPane} instance.
+ */
+ public static StackPane stackPane(Node... controls) {
+ StackPane sp = new StackPane();
+
+ sp.getChildren().addAll(controls);
+
+ return sp;
+ }
+
+ /**
+ * Create border pane.
+ *
+ * @param top Optional top control.
+ * @param center Optional center control.
+ * @param bottom Optional bottom control.
+ * @param left Optional left control.
+ * @param right Optional right control.
+ * @return New {@code BorderPane} instance.
+ */
+ public static BorderPane borderPane(Node top, Node center, Node bottom, Node left, Node right) {
+ BorderPane bp = new BorderPane();
+
+ bp.setTop(top);
+ bp.setCenter(center);
+ bp.setBottom(bottom);
+ bp.setLeft(left);
+ bp.setRight(right);
+
+ return bp;
+ }
+
+ /**
+ * Sets control tooltip if needed.
+ *
+ * @param ctrl Target control.
+ * @param tip Tooltip text.
+ * @return Control itself for method chaining.
+ */
+ public static <T extends Control> T tooltip(T ctrl, String tip) {
+ if (!tip.isEmpty())
+ ctrl.setTooltip(new Tooltip(tip));
+
+ return ctrl;
+ }
+
+ /**
+ * Create label.
+ *
+ * @param text Label text.
+ * @return New {@code Label} instance.
+ */
+ public static Label label(String text) {
+ return new Label(text);
+ }
+
+ /**
+ * Create button with text only.
+ *
+ * @param text Button text.
+ * @param tip Tooltip text.
+ * @param onAct Button action.
+ * @return New {@code Button} instance.
+ */
+ public static Button button(String text, String tip, EventHandler<ActionEvent> onAct) {
+ Button btn = new Button(text);
+
+ btn.setOnAction(onAct);
+
+ tooltip(btn, tip);
+
+ return btn;
+ }
+
+ /**
+ * Create button with icon only.
+ *
+ * @param icon Button icon.
+ * @param tip Tooltip text.
+ * @param onAct Button action.
+ * @return New {@code Button} instance.
+ */
+ public static Button button(ImageView icon, String tip, EventHandler<ActionEvent> onAct) {
+ Button btn = new Button();
+
+ btn.setGraphic(icon);
+ btn.setOnAction(onAct);
+
+ tooltip(btn, tip);
+
+ return btn;
+ }
+
+ /**
+ * Create pane with buttons.
+ *
+ * @param alignment Alignment of buttons.
+ * @param dfltPadding If {@code true} than set default padding for pane.
+ * @param btns Buttons that will be added to pane.
+ * @return New {@code HBox} instance with buttons.
+ */
+ public static Pane buttonsPane(Pos alignment, boolean dfltPadding, Button... btns) {
+ HBox hb = hBox(10, dfltPadding, btns);
+
+ hb.setAlignment(alignment);
+
+ return hb;
+ }
+
+ /**
+ * Create checkbox.
+ *
+ * @param text Checkbox text.
+ * @param tip Tooltip tex.
+ * @param sel Checkbox selected state.
+ * @return New {@code Checkbox} instance.
+ */
+ public static CheckBox checkBox(String text, String tip, boolean sel) {
+ CheckBox ch = new CheckBox(text);
+
+ ch.setSelected(sel);
+
+ tooltip(ch, tip);
+
+ return ch;
+ }
+
+ /**
+ * Create text field.
+ *
+ * @param tip Tooltip text.
+ * @return New {@code TextField} instance.
+ */
+ public static TextField textField(String tip) {
+ TextField tf = new TextField();
+
+ tooltip(tf, tip);
+
+ return tf;
+ }
+
+ /**
+ * Create static text.
+ *
+ * @param text Text to show.
+ * @param wrap Text wrapping width.
+ * @return New {@code Text} instance.
+ */
+ public static Text text(String text, int wrap) {
+ Text t = new Text(text);
+
+ t.setFont(new Font(14));
+
+ if (wrap > 0)
+ t.setWrappingWidth(wrap);
+
+ return t;
+ }
+
+ /**
+ * Create password field.
+ *
+ * @param tip Tooltip text.
+ * @return New {@code PasswordField} instance.
+ */
+ public static PasswordField passwordField(String tip) {
+ PasswordField pf = new PasswordField();
+
+ tooltip(pf, tip);
+
+ return pf;
+ }
+
+ /**
+ * Create combo box.
+ *
+ * @param tip Tooltip text.
+ * @param items Combo box items.
+ * @return New {@code ComboBox} instance.
+ */
+ public static <T> ComboBox<T> comboBox(String tip, T... items) {
+ ComboBox<T> cb = new ComboBox<>(FXCollections.observableArrayList(items));
+
+ cb.setMaxWidth(Double.MAX_VALUE);
+ cb.getSelectionModel().select(0);
+
+ tooltip(cb, tip);
+
+ return cb;
+ }
+
+ /**
+ * Create split pane for provided nodes.
+ *
+ * @param node1 First node.
+ * @param node2 Second node.
+ * @param pos Initial divider position.
+ * @return New {@code SplitPane} instance.
+ */
+ public static SplitPane splitPane(Node node1, Node node2, double pos) {
+ SplitPane sp = new SplitPane();
+
+ sp.setOrientation(Orientation.VERTICAL);
+ sp.getItems().addAll(node1, node2);
+ sp.setDividerPosition(0, pos);
+
+ return sp;
+ }
+
+ /**
+ * Create titled pane.
+ *
+ * @param title Title.
+ * @param node Node.
+ * @return New {@code TitledPane} instance.
+ */
+ public static TitledPane titledPane(String title, Node node) {
+ TitledPane tp = new TitledPane(title, node);
+
+ tp.setExpanded(false);
+
+ return tp;
+ }
+
+ /**
+ * Create table column.
+ *
+ * @param colName Column name to display.
+ * @param propName Property name column is bound to.
+ * @param tip Column tooltip text.
+ * @param minWidth The minimum width column is permitted to be resized to.
+ * @param maxWidth The maximum width column is permitted to be resized to.
+ * @param editable {@code true} if column is editable.
+ * @return New {@code TableColumn} instance.
+ */
+ private static <S, T> TableColumn<S, T> tableColumn(String colName, String propName, String tip,
+ int minWidth, int maxWidth, boolean editable) {
+ TableColumn<S, T> col = new TableColumn<>();
+
+ col.setGraphic(tooltip(new Label(colName), tip));
+
+ col.setSortable(false);
+
+ if (minWidth > 0)
+ col.setMinWidth(minWidth);
+
+ if (maxWidth > 0)
+ col.setMaxWidth(maxWidth);
+
+ col.setCellValueFactory(new MyPropertyValueFactory<S, T>(propName));
+
+ col.setEditable(editable);
+
+ return col;
+ }
+
+ /** */
+ private static class MyPropertyValueFactory<S, T> implements Callback<TableColumn.CellDataFeatures<S, T>,
+ ObservableValue<T>> {
+ /** */
+ private final String name;
+
+ /**
+ * @param name Name.
+ */
+ public MyPropertyValueFactory(String name) {
+ this.name = name;
+ }
+
+ /** {@inheritDoc} */
+ @Override public ObservableValue<T> call(TableColumn.CellDataFeatures<S, T> features) {
+ Object val = features.getValue();
+
+ if (val == null)
+ return null;
+
+ Property prop;
+
+ try {
+ Method getter = val.getClass().getMethod(name + "Property");
+
+ getter.setAccessible(true);
+
+ prop = (Property)getter.invoke(val);
+
+ Type type = ((ParameterizedType)getter.getGenericReturnType()).getActualTypeArguments()[0];
+
+ if (type == Boolean.class)
+ return (ObservableValue<T>)JavaFxUtils.booleanProperty(prop);
+
+ if (type == String.class)
+ return (ObservableValue<T>)JavaFxUtils.stringProperty(prop);
+
+ throw new RuntimeException("Unknown field type: " + type);
+ }
+ catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Create table column.
+ *
+ * @param colName Column name to display.
+ * @param propName Property name column is bound to.
+ * @param tip Column tooltip text.
+ * @return New {@code TableColumn} instance.
+ */
+ public static <S, T> TableColumn<S, T> tableColumn(String colName, String propName, String tip) {
+ return tableColumn(colName, propName, tip, 100, 0, false);
+ }
+
+ /**
+ * Create table column.
+ *
+ * @param colName Column name to display.
+ * @param propName Property name column is bound to.
+ * @param tip Column tooltip text.
+ * @param cellFactory Custom cell factory.
+ * @return New {@code TableColumn} instance.
+ */
+ public static <S, T> TableColumn<S, T> customColumn(String colName, String propName, String tip,
+ Callback<TableColumn<S, T>, TableCell<S, T>> cellFactory) {
+ TableColumn<S, T> col = tableColumn(colName, propName, tip, 100, 0, true);
+
+ col.setCellFactory(cellFactory);
+
+ return col;
+ }
+
+ /**
+ * Create editable boolean table column.
+ *
+ * @param colName Column name to display.
+ * @param propName Property name column is bound to.
+ * @param tip Column tooltip text.
+ * @return New {@code TableColumn} instance.
+ */
+ public static <S> TableColumn<S, Boolean> booleanColumn(String colName, String propName, String tip) {
+ TableColumn<S, Boolean> col = tableColumn(colName, propName, tip, 50, 50, true);
+
+ col.setCellFactory(CheckBoxTableCellEx.<S>cellFactory());
+
+ return col;
+
+ }
+
+ /**
+ * Create editable text table column.
+ *
+ * @param colName Column name to display.
+ * @param propName Property name column is bound to.
+ * @param tip Column tooltip text.
+ * @return New {@code TableColumn} instance.
+ */
+ public static <S> TableColumn<S, String> textColumn(String colName, String propName, String tip,
+ TextColumnValidator<S> validator) {
+ TableColumn<S, String> col = tableColumn(colName, propName, tip, 100, 0, true);
+
+ col.setCellFactory(TextFieldTableCellEx.cellFactory(validator));
+
+ return col;
+ }
+
+ /**
+ * Create table view.
+ *
+ * @param placeholder Text to show if table model is empty.
+ * @param cols Columns to add.
+ * @return New {@code TableView} instance.
+ */
+ public static <S> TableView<S> tableView(String placeholder, TableColumn<S, ?>... cols) {
+ TableView<S> tbl = new TableView<>();
+
+ tbl.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
+ tbl.setEditable(true);
+ tbl.setMinHeight(70);
+ tbl.setPlaceholder(text(placeholder, 0));
+
+ tbl.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
+
+ tbl.getColumns().addAll(cols);
+
+ return tbl;
+ }
+
+ /**
+ * Create progress indicator.
+ *
+ * @param sz Indicator diameter.
+ * @return New {@code ProgressIndicator} instance.
+ */
+ public static ProgressIndicator progressIndicator(int sz) {
+ ProgressIndicator pi = new ProgressIndicator();
+
+ pi.setMaxWidth(sz);
+ pi.setMaxHeight(sz);
+
+ return pi;
+ }
+
+ /**
+ * Create image view.
+ *
+ * @param imgFileName Image filename.
+ * @return New {@code ImageView} instance.
+ */
+ public static ImageView imageView(String imgFileName, int sz) {
+ return new ImageView(image(imgFileName, sz));
+ }
+
+ /**
+ * Gets image by its filename.
+ *
+ * @param imgFileName Image filename.
+ * @return Loaded image.
+ */
+ public static Image image(String imgFileName, int sz) {
+ return new Image(Controls.class.getClassLoader()
+ .getResourceAsStream(String.format("media/%1$s_%2$dx%2$d.png", imgFileName, sz)));
+ }
+
+ /**
+ * Customized checkbox.
+ */
+ private static class CheckBoxTableCellEx<S> extends CheckBoxTableCell<S, Boolean> {
+ /** Creates a ComboBox cell factory for use in TableColumn controls. */
+ public static <S> Callback<TableColumn<S, Boolean>, TableCell<S, Boolean>> cellFactory() {
+ return new Callback<TableColumn<S, Boolean>, TableCell<S, Boolean>>() {
+ @Override public TableCell<S, Boolean> call(TableColumn<S, Boolean> col) {
+ return new CheckBoxTableCellEx<>();
+ }
+ };
+ }
+
+ /**
+ * Default constructor.
+ */
+ private CheckBoxTableCellEx() {
+ setAlignment(Pos.CENTER);
+ }
+ }
+
+ /**
+ * Special table text field cell that commit its content on focus lost.
+ */
+ private static class TextFieldTableCellEx<S> extends TextFieldTableCell<S, String> {
+ /** */
+ private final TextColumnValidator<S> validator;
+ /** */
+ private String curTxt = "";
+
+ /** Row value. */
+ private S rowVal;
+
+ /** Create cell factory. */
+ public static <S> Callback<TableColumn<S, String>, TableCell<S, String>>
+ cellFactory(final TextColumnValidator<S> validator) {
+ return new Callback<TableColumn<S, String>, TableCell<S, String>>() {
+ @Override public TableCell<S, String> call(TableColumn<S, String> col) {
+ return new TextFieldTableCellEx<>(validator);
+ }
+ };
+ }
+
+ /**
+ * Text field cell constructor.
+ *
+ * @param validator Input text validator.
+ */
+ private TextFieldTableCellEx(TextColumnValidator<S> validator) {
+ super(new DefaultStringConverter());
+
+ this.validator = validator;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void startEdit() {
+ String item = getItem();
+
+ if (item == null || item.isEmpty())
+ return;
+
+ super.startEdit();
+
+ rowVal = getTableView().getSelectionModel().getSelectedItem();
+
+ Node g = getGraphic();
+
+ if (g != null) {
+ final TextField tf = (TextField)g;
+
+ curTxt = tf.getText();
+
+ tf.textProperty().addListener(new ChangeListener<String>() {
+ @Override public void changed(ObservableValue<? extends String> val, String oldVal, String newVal) {
+ curTxt = newVal;
+ }
+ });
+
+ tf.setOnKeyPressed(new EventHandler<KeyEvent>() {
+ @Override public void handle(KeyEvent evt) {
+ if (KeyCode.ENTER == evt.getCode() || KeyCode.ESCAPE == evt.getCode())
+ cancelEdit();
+ }
+ });
+
+ tf.setOnKeyReleased(new EventHandler<KeyEvent>() {
+ @Override public void handle(KeyEvent evt) {
+ // No-op to overwrite JavaFX implementation.
+ }
+ });
+
+ // Special hack for editable TextFieldTableCell.
+ // Cancel edit when focus lost from text field, but do not cancel if focus lost to VirtualFlow.
+ tf.focusedProperty().addListener(new ChangeListener<Boolean>() {
+ @Override public void changed(ObservableValue<? extends Boolean> val, Boolean oldVal, Boolean newVal) {
+ Node fo = getScene().getFocusOwner();
+
+ if (!newVal) {
+ if (fo instanceof VirtualFlow) {
+ if (fo.getParent().getParent() != getTableView())
+ cancelEdit();
+ }
+ else
+ cancelEdit();
+ }
+ }
+ });
+
+ Platform.runLater(new Runnable() {
+ @Override public void run() {
+ tf.requestFocus();
+ }
+ });
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void cancelEdit() {
+ boolean editing = isEditing();
+
+ super.cancelEdit();
+
+ if (editing && validator.valid(rowVal, curTxt))
+ updateItem(curTxt, false);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/GridPaneEx.java
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/GridPaneEx.java b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/GridPaneEx.java
new file mode 100644
index 0000000..be1aae9
--- /dev/null
+++ b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/GridPaneEx.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.schema.ui;
+
+import javafx.geometry.*;
+import javafx.scene.*;
+import javafx.scene.control.*;
+import javafx.scene.layout.*;
+
+/**
+ * Utility extension of {@code GridPane}.
+ */
+public class GridPaneEx extends GridPane {
+ /** Current column. */
+ private int col;
+
+ /** Current row. */
+ private int row;
+
+ /**
+ * Create pane.
+ */
+ public GridPaneEx() {
+ setAlignment(Pos.TOP_LEFT);
+ setHgap(5);
+ setVgap(10);
+ }
+
+ /**
+ * Add default column.
+ */
+ public void addColumn() {
+ getColumnConstraints().add(new ColumnConstraints());
+ }
+
+ /**
+ * Add column with constraints and horizontal grow priority for the column.
+ *
+ * @param min Column minimum size.
+ * @param pref Column preferred size.
+ * @param max Column max size.
+ * @param hgrow Column horizontal grow priority.
+ */
+ public void addColumn(double min, double pref, double max, Priority hgrow) {
+ ColumnConstraints cc = new ColumnConstraints(min, pref, max);
+
+ cc.setHgrow(hgrow);
+
+ getColumnConstraints().add(cc);
+ }
+
+ /**
+ * Add default row.
+ */
+ public void addRow() {
+ getRowConstraints().add(new RowConstraints());
+ }
+
+ /**
+ * Add default rows.
+ *
+ * @param n Number of rows to add.
+ */
+ public void addRows(int n) {
+ for (int i = 0; i < n; i++)
+ addRow();
+ }
+
+ /**
+ * Add row with constraints and vertical grow priority for the row.
+ *
+ * @param min Row minimum size.
+ * @param pref Row preferred size.
+ * @param max Row max size.
+ * @param vgrow Row vertical grow priority.
+ */
+ public void addRow(double min, double pref, double max, Priority vgrow) {
+ RowConstraints rc = new RowConstraints(min, pref, max);
+
+ rc.setVgrow(vgrow);
+
+ getRowConstraints().add(rc);
+ }
+
+ /**
+ * Wrap to next row.
+ */
+ public void wrap() {
+ col = 0;
+
+ row++;
+ }
+
+ /**
+ * Skip columns.
+ *
+ * @param span How many columns should be skipped.
+ */
+ public void skip(int span) {
+ add(new Label(""), span);
+ }
+
+ /**
+ * Move to next column.
+ */
+ private void nextCol(int span) {
+ col += span;
+
+ if (col >= getColumnConstraints().size())
+ wrap();
+ }
+
+ /**
+ * Add control to grid pane.
+ *
+ * @param ctrl Control to add.
+ * @param span How many columns control should take.
+ * @return Added control.
+ */
+ public <T extends Node> T add(T ctrl, int span) {
+ add(ctrl, col, row, span, 1);
+
+ nextCol(span);
+
+ return ctrl;
+ }
+
+ /**
+ * Add control to grid pane.
+ *
+ * @param ctrl Control to add.
+ * @return Added control.
+ */
+ public <T extends Node> T add(T ctrl) {
+ return add(ctrl, 1);
+ }
+
+ /**
+ * Add control with label.
+ *
+ * @param text Label text.
+ * @param ctrl Control to add.
+ * @param span How many columns control should take.
+ * @return Added control.
+ */
+ public <T extends Node> T addLabeled(String text, T ctrl, int span) {
+ add(new Label(text));
+
+ return add(ctrl, span);
+ }
+
+ /**
+ * Add control with label.
+ *
+ * @param text Label text.
+ * @param ctrl Control to add.
+ * @return Added control.
+ */
+ public <T extends Node> T addLabeled(String text, T ctrl) {
+ return addLabeled(text, ctrl, 1);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/JavaFxUtils.java
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/JavaFxUtils.java b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/JavaFxUtils.java
new file mode 100644
index 0000000..579b649
--- /dev/null
+++ b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/JavaFxUtils.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.schema.ui;
+
+import javafx.beans.property.*;
+import javafx.beans.value.*;
+
+/**
+ *
+ */
+public class JavaFxUtils {
+ /**
+ * @param prop Property.
+ */
+ public static BooleanProperty booleanProperty(org.apache.ignite.schema.utils.Property<Boolean> prop) {
+ BooleanProperty res = (BooleanProperty)prop.fxProperty();
+
+ if (res == null) {
+ res = new SimpleBooleanProperty(prop.get());
+
+ new Bridge<>(res, prop);
+
+ prop.fxProperty(res);
+ }
+
+ return res;
+ }
+
+ /**
+ * @param prop Property.
+ */
+ public static StringProperty stringProperty(org.apache.ignite.schema.utils.Property<String> prop) {
+ StringProperty res = (StringProperty)prop.fxProperty();
+
+ if (res == null) {
+ res = new SimpleStringProperty(prop.get());
+
+ new Bridge<>(res, prop);
+
+ prop.fxProperty(res);
+ }
+
+ return res;
+ }
+
+ /**
+ *
+ * @param <T>
+ */
+ private static class Bridge<T> implements org.apache.ignite.schema.utils.ChangeListener<T>, ChangeListener<T> {
+ /** */
+ private final Property<T> fxProp;
+
+ /** */
+ private final org.apache.ignite.schema.utils.Property<T> igniteProp;
+
+ /**
+ * @param fxProp Fx property.
+ * @param igniteProp Ignite property.
+ */
+ public Bridge(Property<T> fxProp, org.apache.ignite.schema.utils.Property<T> igniteProp) {
+ this.fxProp = fxProp;
+ this.igniteProp = igniteProp;
+
+ fxProp.addListener(this);
+ igniteProp.addListener(this);
+ }
+
+ /** */
+ private boolean notificationInProgress;
+
+ /** {@inheritDoc} */
+ @Override public void changed(org.apache.ignite.schema.utils.Property<? extends T> prop, T oldVal, T newVal) {
+ if (notificationInProgress)
+ return;
+
+ notificationInProgress = true;
+
+ try {
+ assert prop == igniteProp;
+
+ fxProp.setValue(newVal);
+ }
+ finally {
+ notificationInProgress = false;
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public void changed(ObservableValue<? extends T> prop, T oldVal, T newVal) {
+ if (notificationInProgress)
+ return;
+
+ notificationInProgress = true;
+
+ try {
+ assert prop == fxProp;
+
+ igniteProp.set(newVal);
+ }
+ finally {
+ notificationInProgress = false;
+ }
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/MessageBox.java
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/MessageBox.java b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/MessageBox.java
new file mode 100644
index 0000000..7daf69f
--- /dev/null
+++ b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/MessageBox.java
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.schema.ui;
+
+import javafx.beans.value.*;
+import javafx.event.*;
+import javafx.geometry.*;
+import javafx.scene.control.*;
+import javafx.scene.layout.*;
+import javafx.stage.*;
+
+import java.util.logging.*;
+
+import static org.apache.ignite.schema.ui.Controls.*;
+
+/**
+ * Message box functionality.
+ */
+public class MessageBox extends ModalDialog {
+ /** Logger. */
+ private static final Logger log = Logger.getLogger(MessageBox.class.getName());
+
+ /** Message box type. */
+ private enum MessageType {
+ /** Information. */
+ INFO,
+ /** Warning. */
+ WARN,
+ /** Error. */
+ ERROR,
+ /** Confirm. */
+ CONFIRM,
+ /** Confirm with cancel option. */
+ CANCELLABLE_CONFIRM
+ }
+
+ /** Message box type. */
+ public enum Result {
+ /** Return value if YES is chosen. */
+ YES,
+ /** Return value if YES_TO_ALL is chosen. */
+ YES_TO_ALL,
+ /** Return value if NO is chosen. */
+ NO,
+ /** Return value if NO_TO_ALL is chosen. */
+ NO_TO_ALL,
+ /** Return value if CANCEL is chosen. */
+ CANCEL
+ }
+
+ /** Dialog result. */
+ private Result res = Result.CANCEL;
+
+ /**
+ * Create message box.
+ *
+ * @param owner Owner window.
+ * @param type Message box type.
+ * @param msg Message to show.
+ * @param applyToAll {@code true} if "Apply to all" check box should be displayed.
+ */
+ private MessageBox(Stage owner, MessageType type, String msg, final boolean applyToAll) {
+ super(owner, 480, 180);
+
+ String title;
+ String iconFile;
+
+ switch (type) {
+ case WARN:
+ title = "Warning";
+ iconFile = "sign_warning";
+ break;
+
+ case ERROR:
+ title = "Error";
+ iconFile = "error";
+ break;
+
+ case CONFIRM:
+ case CANCELLABLE_CONFIRM:
+ title = "Confirmation";
+ iconFile = "question";
+ break;
+
+ default:
+ title = "Information";
+ iconFile = "information";
+ break;
+ }
+
+ setTitle(title);
+ initStyle(StageStyle.UTILITY);
+ initModality(Modality.APPLICATION_MODAL);
+ initOwner(owner);
+ setResizable(false);
+
+ GridPaneEx contentPnl = paneEx(10, 10, 0, 10);
+
+ contentPnl.addColumn();
+ contentPnl.addColumn(100, 100, Double.MAX_VALUE, Priority.ALWAYS);
+
+ contentPnl.add(hBox(0, true, imageView(iconFile, 48)));
+
+ final TextArea ta = new TextArea(msg);
+ ta.setEditable(false);
+ ta.setWrapText(true);
+ ta.setFocusTraversable(false);
+
+ contentPnl.add(ta);
+
+ // Workaround for vertical scrollbar.
+ if (msg.length() < 100 && msg.split("\r\n|\r|\n").length < 4)
+ showingProperty().addListener(new ChangeListener<Boolean>() {
+ @Override public void changed(ObservableValue<? extends Boolean> val, Boolean oldVal, Boolean newVal) {
+ if (newVal) {
+ ScrollBar scrollBar = (ScrollBar)ta.lookup(".scroll-bar:vertical");
+
+ if (scrollBar != null)
+ scrollBar.setDisable(true);
+ }
+ }
+ });
+
+ final CheckBox applyToAllCh = checkBox("Apply to all", "", false);
+
+ if (applyToAll) {
+ contentPnl.skip(1);
+ contentPnl.add(applyToAllCh);
+ }
+
+ HBox btns = hBox(10, true);
+ btns.setAlignment(Pos.CENTER);
+
+ if (MessageType.CONFIRM == type || MessageType.CANCELLABLE_CONFIRM == type) {
+ res = Result.NO;
+
+ btns.getChildren().addAll(
+ button("Yes", "Approve the request", new EventHandler<ActionEvent>() {
+ @Override public void handle(ActionEvent e) {
+ res = applyToAll && applyToAllCh.isSelected() ? Result.YES_TO_ALL : Result.YES;
+
+ close();
+ }
+ }),
+ button("No", "Reject the request", new EventHandler<ActionEvent>() {
+ @Override public void handle(ActionEvent e) {
+ res = applyToAll && applyToAllCh.isSelected() ? Result.NO_TO_ALL : Result.NO;
+
+ close();
+ }
+ }));
+
+ if (MessageType.CANCELLABLE_CONFIRM == type)
+ btns.getChildren().addAll(
+ button("Cancel", "Cancel the request", new EventHandler<ActionEvent>() {
+ @Override public void handle(ActionEvent e) {
+ res = Result.CANCEL;
+
+ close();
+ }
+ }));
+ }
+ else
+ btns.getChildren().add(button("OK", "Close dialog", new EventHandler<ActionEvent>() {
+ @Override public void handle(ActionEvent e) {
+ close();
+ }
+ }));
+
+ setScene(scene(borderPane(null, contentPnl, btns, null, null)));
+ }
+
+ /**
+ * Show message in modal dialog.
+ *
+ * @param owner Owner window.
+ * @param type Message box type.
+ * @param msg Message to show.
+ * @param applyToAll {@code true} if "Apply to all" check box should be displayed.
+ * @return Option selected by the user.
+ */
+ private static Result showDialog(Stage owner, MessageType type, String msg, boolean applyToAll) {
+ MessageBox dlg = new MessageBox(owner, type, msg, applyToAll);
+
+ dlg.showModal();
+
+ return dlg.res;
+ }
+
+ /**
+ * Show confirmation dialog.
+ *
+ * @param owner Owner window.
+ * @param msg Message to show.
+ * @return {@code true} If user confirm.
+ */
+ public static boolean confirmDialog(Stage owner, String msg) {
+ return showDialog(owner, MessageType.CONFIRM, msg, false) == Result.YES;
+ }
+
+ /**
+ * Show confirmation dialog.
+ *
+ * @param owner Owner window.
+ * @param msg Message to show.
+ * @return User confirmation result.
+ */
+ public static Result applyToAllChoiceDialog(Stage owner, String msg) {
+ return showDialog(owner, MessageType.CANCELLABLE_CONFIRM, msg, true);
+ }
+
+ /**
+ * Show information dialog.
+ *
+ * @param owner Owner window.
+ * @param msg Message to show.
+ */
+ public static void informationDialog(Stage owner, String msg) {
+ showDialog(owner, MessageType.INFO, msg, false);
+ }
+
+ /**
+ * Show warning dialog.
+ *
+ * @param owner Owner window.
+ * @param msg Message to show.
+ */
+ public static void warningDialog(Stage owner, String msg) {
+ showDialog(owner, MessageType.WARN, msg, false);
+ }
+
+ /**
+ * Show error dialog.
+ *
+ * @param owner Owner window.
+ * @param msg Error message to show.
+ * @param e Optional exception to show.
+ */
+ public static void errorDialog(Stage owner, String msg, Throwable e) {
+ log.log(Level.SEVERE, msg, e);
+
+ String exMsg = e != null ? (e.getMessage() != null ? e.getMessage() : e.getClass().getName()) : null;
+
+ showDialog(owner, MessageType.ERROR, exMsg != null ? msg + "\n" + exMsg : msg, false);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e8d71b55/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/ModalDialog.java
----------------------------------------------------------------------
diff --git a/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/ModalDialog.java b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/ModalDialog.java
new file mode 100644
index 0000000..6d0acb7
--- /dev/null
+++ b/modules/schema-import-ui/src/main/java/org/apache/ignite/schema/ui/ModalDialog.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.schema.ui;
+
+import javafx.stage.*;
+
+/**
+ * Abstract base modal dialog.
+ */
+public abstract class ModalDialog extends Stage {
+ /** Owner window. */
+ protected final Stage owner;
+
+ /**
+ * @param owner Owner window.
+ * @param width Window width.
+ * @param height Window height.
+ */
+ protected ModalDialog(Stage owner, int width, int height) {
+ this.owner = owner;
+
+ this.setWidth(width);
+ this.setHeight(height);
+ }
+
+ /**
+ * Show modal dialog.
+ */
+ protected void showModal() {
+ setX(owner.getX() + owner.getWidth() / 2 - getWidth() / 2);
+ setY(owner.getY() + owner.getHeight() / 2 - getHeight() / 2);
+
+ showAndWait();
+ }
+}