Repository: incubator-ignite Updated Branches: refs/heads/ignite-32 f5c1ed148 -> 0ee13c673
# IGNITE-32 WIP: Confirm discard cahnges if user click prev button. Minor UI tweaks. Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/0ee13c67 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/0ee13c67 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/0ee13c67 Branch: refs/heads/ignite-32 Commit: 0ee13c673dd8ab08d2cd08ab313643de1bbfb8c4 Parents: f5c1ed1 Author: AKuznetsov <akuznet...@gridgain.com> Authored: Mon Jan 12 21:37:16 2015 +0700 Committer: AKuznetsov <akuznet...@gridgain.com> Committed: Mon Jan 12 21:37:16 2015 +0700 ---------------------------------------------------------------------- .../java/org/apache/ignite/schema/ui/Field.java | 23 ++++++ .../org/apache/ignite/schema/ui/MessageBox.java | 27 ++----- .../apache/ignite/schema/ui/ModalDialog.java | 43 +++++++++++ .../apache/ignite/schema/ui/NamingDialog.java | 14 +--- .../apache/ignite/schema/ui/SchemaLoadApp.java | 77 ++++++++++++++++---- 5 files changed, 137 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0ee13c67/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/Field.java ---------------------------------------------------------------------- diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/Field.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/Field.java index 10ea3c7..5d04612 100644 --- a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/Field.java +++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/Field.java @@ -41,6 +41,20 @@ public class Field { } /** + * Copy constructor. + * + * @param src Source field. + */ + public Field(Field src) { + desc = src.desc; + key = new SimpleBooleanProperty(src.isKey()); + javaName = new SimpleStringProperty(desc.getJavaName()); + javaTypeName = new SimpleStringProperty(desc.getJavaType().getName()); + dbName = new SimpleStringProperty(desc.getDbName()); + dbTypeName = new SimpleStringProperty(jdbcTypeName(desc.getDbType())); + } + + /** * @param jdbcType String name for JDBC type. */ private static String jdbcTypeName(int jdbcType) { @@ -172,4 +186,13 @@ public class Field { public StringProperty dbTypeNameProperty() { return dbTypeName; } + + /** + * @param other Some other instance of {@code Field} to compare with. + * @return {@code true} if fields are not the same. + */ + public boolean diff(Field other) { + // User can change via GUI only key and java name properties. + return isKey() != other.isKey() || !javaName.get().equals(other.javaName.get()); + } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0ee13c67/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/MessageBox.java ---------------------------------------------------------------------- diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/MessageBox.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/MessageBox.java index adace51..96bfafb 100644 --- a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/MessageBox.java +++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/MessageBox.java @@ -12,7 +12,7 @@ import static org.apache.ignite.schema.ui.Controls.*; /** * Message box functionality. */ -public class MessageBox extends Stage { +public class MessageBox extends ModalDialog { /** Message box type. */ private enum MessageType { /** Information. */ @@ -34,9 +34,6 @@ public class MessageBox extends Stage { /** Return value if CANCEL is chosen. */ public static final int CANCEL_OPTION = 2; - /** Owner window. */ - private final Stage owner; - /** Dialog result. */ private int res = CANCEL_OPTION; @@ -48,7 +45,7 @@ public class MessageBox extends Stage { * @param msg Message to show. */ private MessageBox(Stage owner, MessageType type, String msg) { - this.owner = owner; + super(owner); String title; String iconFile; @@ -112,18 +109,6 @@ public class MessageBox extends Stage { } /** - * Show modal dialog. - */ - public void showDialog() { - sizeToScene(); - - setX(owner.getX() + owner.getWidth() / 8); - setY(owner.getY() + owner.getHeight() / 4); - - showAndWait(); - } - - /** * Show message in modal dialog. * * @param owner Owner window. @@ -134,7 +119,7 @@ public class MessageBox extends Stage { private static int showDialog(Stage owner, MessageType type, String msg) { MessageBox dlg = new MessageBox(owner, type, msg); - dlg.showDialog(); + dlg.showModal(); return dlg.res; } @@ -144,10 +129,10 @@ public class MessageBox extends Stage { * * @param owner Owner window. * @param msg Message to show. - * @return Option selected by the user. + * @return {@code true} If user confirm. */ - public static int confirmDialog(Stage owner, String msg) { - return showDialog(owner, MessageType.CONFIRM, msg); + public static boolean confirmDialog(Stage owner, String msg) { + return showDialog(owner, MessageType.CONFIRM, msg) == YES_OPTION; } /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0ee13c67/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/ModalDialog.java ---------------------------------------------------------------------- diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/ModalDialog.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/ModalDialog.java new file mode 100644 index 0000000..56ed881 --- /dev/null +++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/ModalDialog.java @@ -0,0 +1,43 @@ +/* @java.file.header */ + +package org.apache.ignite.schema.ui; + +import javafx.application.*; +import javafx.stage.*; + +/** + * Abstract base modal dialog. + */ +public abstract class ModalDialog extends Stage { + /** Owner window. */ + protected final Stage owner; + + /** + * @param owner Owner window. + */ + protected ModalDialog(Stage owner) { + this.owner = owner; + } + + /** + * Show modal dialog. + */ + protected void showModal() { + sizeToScene(); + + setX(owner.getX() + owner.getWidth() / 8); + setY(owner.getY() + owner.getHeight() / 4); + + // We should set dialog position later (after show), + // because JavaFX will set actual width and height on dialog show. + Platform.runLater(new Runnable() { + /** {@inheritDoc} */ + @Override public void run() { + setX(owner.getX() + owner.getWidth() / 2 - getWidth() / 2); + setY(owner.getY() + owner.getHeight() / 2 - getHeight() / 2); + } + }); + + showAndWait(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0ee13c67/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/NamingDialog.java ---------------------------------------------------------------------- diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/NamingDialog.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/NamingDialog.java index 898ef19..0848866 100644 --- a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/NamingDialog.java +++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/NamingDialog.java @@ -13,10 +13,7 @@ import static org.apache.ignite.schema.ui.Controls.*; /** * Dialog with custom naming options. */ -public class NamingDialog extends Stage { - /** Owner window. */ - private final Stage owner; - +public class NamingDialog extends ModalDialog { /** */ private final TextField prefixTf; @@ -47,7 +44,7 @@ public class NamingDialog extends Stage { */ public NamingDialog(final Stage owner, final String prefix, String suffix, boolean regex, final String ptrn, final String replace) { - this.owner = owner; + super(owner); setTitle("Custom Naming"); initStyle(StageStyle.UTILITY); @@ -156,12 +153,7 @@ public class NamingDialog extends Stage { * Show modal dialog. */ public boolean showDialog() { - sizeToScene(); - - setX(owner.getX() + owner.getWidth() / 6); - setY(owner.getY() + owner.getHeight() / 4); - - showAndWait(); + showModal(); return ok; } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/0ee13c67/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/SchemaLoadApp.java ---------------------------------------------------------------------- diff --git a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/SchemaLoadApp.java b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/SchemaLoadApp.java index 7e018c6..9b85855 100644 --- a/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/SchemaLoadApp.java +++ b/modules/schema-load/src/main/java/org/apache/ignite/schema/ui/SchemaLoadApp.java @@ -20,9 +20,6 @@ import org.apache.ignite.schema.xml.*; import org.gridgain.grid.cache.query.*; import org.gridgain.grid.util.typedef.internal.*; -import java.awt.Image; -import java.awt.Desktop; -import java.awt.Toolkit; import java.io.*; import java.net.*; import java.sql.*; @@ -39,6 +36,7 @@ import static org.apache.ignite.schema.util.SchemaUtils.*; /** * Schema load application. */ +@SuppressWarnings("UnnecessaryFullyQualifiedName") public class SchemaLoadApp extends Application { /** */ private Stage owner; @@ -134,7 +132,10 @@ public class SchemaLoadApp extends Application { private LinkedHashMap<String, LinkedHashMap<String, GridCacheQueryTypeMetadata>> metas; /** Map with fields descriptors. */ - private Map<String, Map<String, ObservableList<Field>>> fields; + private Map<String, Map<String, ObservableList<Field>>> fields = Collections.emptyMap(); + + /** Map with previous fields descriptors, needed to detect for changes made by user. */ + private Map<String, Map<String, ObservableList<Field>>> fieldsPrev = Collections.emptyMap(); /** */ private static final ObservableList<Field> NO_DATA = FXCollections.emptyObservableList(); @@ -213,6 +214,7 @@ public class SchemaLoadApp extends Application { } fields = U.newHashMap(metas.size()); + fieldsPrev = U.newHashMap(metas.size()); for (Map.Entry<String, LinkedHashMap<String, GridCacheQueryTypeMetadata>> meta : metas.entrySet()) { String schema = meta.getKey(); @@ -220,8 +222,10 @@ public class SchemaLoadApp extends Application { LinkedHashMap<String, GridCacheQueryTypeMetadata> tbls = meta.getValue(); Map<String, ObservableList<Field>> tblsFields = U.newHashMap(tbls.size()); + Map<String, ObservableList<Field>> tblsFieldsPrev = U.newHashMap(tbls.size()); fields.put(schema, tblsFields); + fieldsPrev.put(schema, tblsFieldsPrev); for (Map.Entry<String, GridCacheQueryTypeMetadata> tbl : tbls.entrySet()) { GridCacheQueryTypeMetadata type = tbl.getValue(); @@ -238,7 +242,13 @@ public class SchemaLoadApp extends Application { for (GridCacheQueryTypeDescriptor val : vals) tblFields.add(new Field(false, val)); + List<Field> tblFieldsPrev = new ArrayList<>(tblFields.size()); + + for (Field fld : tblFields) + tblFieldsPrev.add(new Field(fld)); + tblsFields.put(type.getTableName(), FXCollections.observableList(tblFields)); + tblsFieldsPrev.put(type.getTableName(), FXCollections.observableList(tblFieldsPrev)); } } @@ -426,7 +436,7 @@ public class SchemaLoadApp extends Application { if (openFolderCh.isSelected()) try { - Desktop.getDesktop().open(destFolder); + java.awt.Desktop.getDesktop().open(destFolder); } catch (IOException e) { MessageBox.errorDialog(owner, "Failed to open folder with results.", e); @@ -490,9 +500,31 @@ public class SchemaLoadApp extends Application { } /** + * @return {@code true} if some changes were made to fields metadata. + */ + private boolean changed() { + for (Map.Entry<String, Map<String, ObservableList<Field>>> schema : fields.entrySet()) { + for (Map.Entry<String, ObservableList<Field>> tbl : schema.getValue().entrySet()) { + ObservableList<Field> cur = tbl.getValue(); + ObservableList<Field> prev = fieldsPrev.get(schema.getKey()).get(tbl.getKey()); + + for (int i = 0; i < cur.size(); i++) + if (cur.get(i).diff(prev.get(i))) + return true; + } + } + + return false; + } + + /** * Go to "Connect To Database" panel. */ private void prev() { + if (changed() && !MessageBox.confirmDialog(owner, "Are you sure you want to return to previous page?\n" + + "This will discard all your changes.")) + return; + titleLb.setText("Connect To Database"); titleLb.setGraphic(imageView("data_connection", 48)); @@ -683,8 +715,8 @@ public class SchemaLoadApp extends Application { tbl.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); tbl.setEditable(true); - tbl.getColumns().addListener(new ListChangeListener<TableColumn<Field,?>>() { - public boolean suspended; + tbl.getColumns().addListener(new ListChangeListener<TableColumn<Field, ?>>() { + private boolean suspended; /** {@inheritDoc} */ @Override public void onChanged(Change change) { @@ -713,9 +745,14 @@ public class SchemaLoadApp extends Application { if (selIdx > 0) { ObservableList<Field> items = tbl.getItems(); - items.add(selIdx - 1, items.remove(selIdx)); + int newId = selIdx - 1; + + items.add(newId, items.remove(selIdx)); - selMdl.select(selIdx - 1); + if (newId == 0) + tbl.requestFocus(); + + selMdl.select(newId); } } }); @@ -731,10 +768,18 @@ public class SchemaLoadApp extends Application { ObservableList<Field> items = tbl.getItems(); - if (selIdx < items.size() - 1) { - items.add(selIdx + 1, items.remove(selIdx)); + int maxIdx = items.size() - 1; + + if (selIdx < maxIdx) { + int newId = selIdx + 1; + + items.add(newId, items.remove(selIdx)); + + if (newId == maxIdx) + tbl.requestFocus(); + + selMdl.select(newId); - selMdl.select(selIdx + 1); } } }); @@ -956,21 +1001,23 @@ public class SchemaLoadApp extends Application { * @param args Command line arguments passed to the application. */ public static void main(String[] args) { + // Workaround for JavaFX ugly text AA. System.setProperty("prism.lcdtext", "false"); System.setProperty("prism.text", "t2k"); + // Workaround for AWT + JavaFX: we should initialize AWT before JavaFX. + java.awt.Toolkit.getDefaultToolkit(); + // Workaround for JavaFX + Mac OS dock icon. if (System.getProperty("os.name").toLowerCase().contains("mac os")) { System.setProperty("javafx.macosx.embedded", "true"); - Toolkit.getDefaultToolkit(); - try { Class<?> appCls = Class.forName("com.apple.eawt.Application"); Object osxApp = appCls.getDeclaredMethod("getApplication").invoke(null); - appCls.getDeclaredMethod("setDockIconImage", Image.class) + appCls.getDeclaredMethod("setDockIconImage", java.awt.Image.class) .invoke(osxApp, fromFXImage(image("ignite", 128), null)); } catch (Throwable ignore) {