Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe Commits: 7d0c1930 by Tony Chemit at 2022-08-03T18:31:38+02:00 Client - Aucune barre de progression Closes #2409 - - - - - 27 changed files: - client/core/src/main/java/fr/ird/observe/client/ClientUIContext.java - client/core/src/main/java/fr/ird/observe/client/ClientUIContextApi.java - client/core/src/main/java/fr/ird/observe/client/WithClientUIContextApi.java - client/core/src/main/java/fr/ird/observe/client/main/MainUIModel.java - client/core/src/main/java/fr/ird/observe/client/main/ObserveMainUI.jaxx - client/core/src/main/java/fr/ird/observe/client/main/ObserveMainUIHandler.java - client/core/src/main/java/fr/ird/observe/client/main/focus/MainUIFocusModel.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/DataSourceEditorBodyContent.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/DataSourceEditorModel.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/avdth/ImportDialogHandler.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/avdth/ImportDialogModel.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/mode/ChangeModeExecutor.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/edit/actions/DeleteEdit.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/edit/actions/SaveContentEditUIAdapter.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/open/actions/SaveContentOpenableUIAdapter.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/ropen/actions/SaveContentRootOpenableUIAdapter.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/menu/DataSourceEditorMenu.jaxx - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/menu/DataSourceEditorMenuModel.java - client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationTree.java - toolkit/api/src/main/i18n/getters/java.getter - toolkit/api/src/main/i18n/translations/toolkit_en_GB.properties - toolkit/api/src/main/i18n/translations/toolkit_es_ES.properties - toolkit/api/src/main/i18n/translations/toolkit_fr_FR.properties - toolkit/api/src/main/java/fr/ird/observe/navigation/tree/navigation/NavigationTreeSelectionModel.java - toolkit/api/src/main/java/fr/ird/observe/navigation/tree/navigation/NavigationTreeSupport.java - client/core/src/main/java/fr/ird/observe/client/util/busy/BusyLayerUI.java → toolkit/api/src/main/java/fr/ird/observe/spi/ui/BusyLayerUI.java - client/core/src/main/java/fr/ird/observe/client/util/busy/BusyModel.java → toolkit/api/src/main/java/fr/ird/observe/spi/ui/BusyModel.java Changes: ===================================== client/core/src/main/java/fr/ird/observe/client/ClientUIContext.java ===================================== @@ -33,7 +33,7 @@ import fr.ird.observe.client.main.body.NoBodyContentComponent; import fr.ird.observe.client.main.callback.ObserveUICallbackManager; import fr.ird.observe.client.main.focus.MainUIFocusModel; import fr.ird.observe.client.util.action.ObserveExecutorService; -import fr.ird.observe.client.util.busy.BusyModel; +import fr.ird.observe.spi.ui.BusyModel; import fr.ird.observe.client.util.session.ObserveSwingSessionHelper; import fr.ird.observe.dto.data.ps.dcp.FloatingObjectPresetsManager; import fr.ird.observe.navigation.id.IdProjectManager; ===================================== client/core/src/main/java/fr/ird/observe/client/ClientUIContextApi.java ===================================== @@ -32,7 +32,7 @@ import fr.ird.observe.client.main.ObserveMainUI; import fr.ird.observe.client.main.callback.ObserveUICallbackManager; import fr.ird.observe.client.main.focus.MainUIFocusModel; import fr.ird.observe.client.util.UIHelper; -import fr.ird.observe.client.util.busy.BusyModel; +import fr.ird.observe.spi.ui.BusyModel; import fr.ird.observe.client.util.session.ObserveSwingSessionHelper; import fr.ird.observe.dto.ObserveUtil; import fr.ird.observe.dto.data.ps.dcp.FloatingObjectPresetsManager; ===================================== client/core/src/main/java/fr/ird/observe/client/WithClientUIContextApi.java ===================================== @@ -31,7 +31,7 @@ import fr.ird.observe.client.main.MainUIModel; import fr.ird.observe.client.main.ObserveMainUI; import fr.ird.observe.client.main.callback.ObserveUICallbackManager; import fr.ird.observe.client.main.focus.MainUIFocusModel; -import fr.ird.observe.client.util.busy.BusyModel; +import fr.ird.observe.spi.ui.BusyModel; import fr.ird.observe.client.util.session.ObserveSwingSessionHelper; import fr.ird.observe.dto.data.ps.dcp.FloatingObjectPresetsManager; import fr.ird.observe.navigation.id.IdProjectManager; ===================================== client/core/src/main/java/fr/ird/observe/client/main/MainUIModel.java ===================================== @@ -24,7 +24,7 @@ package fr.ird.observe.client.main; import fr.ird.observe.client.configuration.ClientConfig; import fr.ird.observe.client.main.focus.MainUIFocusModel; -import fr.ird.observe.client.util.busy.BusyModel; +import fr.ird.observe.spi.ui.BusyModel; import io.ultreia.java4all.bean.AbstractJavaBean; import io.ultreia.java4all.bean.spi.GenerateJavaBeanDefinition; ===================================== client/core/src/main/java/fr/ird/observe/client/main/ObserveMainUI.jaxx ===================================== @@ -22,7 +22,7 @@ <import> fr.ird.observe.client.util.JMenuWithAccelerator - fr.ird.observe.client.util.busy.BusyModel + fr.ird.observe.spi.ui.BusyModel fr.ird.observe.client.configuration.ClientConfig fr.ird.observe.client.main.MainUIModel fr.ird.observe.client.main.body.MainUIBodyContentManager ===================================== client/core/src/main/java/fr/ird/observe/client/main/ObserveMainUIHandler.java ===================================== @@ -27,8 +27,8 @@ import fr.ird.observe.client.configuration.ClientConfig; import fr.ird.observe.client.main.body.MainUIBodyContentManager; import fr.ird.observe.client.util.ObserveKeyStrokesSupport; import fr.ird.observe.client.util.UIHelper; -import fr.ird.observe.client.util.busy.BusyLayerUI; -import fr.ird.observe.client.util.busy.BusyModel; +import fr.ird.observe.spi.ui.BusyLayerUI; +import fr.ird.observe.spi.ui.BusyModel; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.nuiton.jaxx.runtime.spi.UIHandler; @@ -102,7 +102,7 @@ public class ObserveMainUIHandler implements UIHandler<ObserveMainUI>, WithClien ui.getStatus().init(); - // installation layer de blocage en mode busy + // init blocking layer associated with the busy model BusyLayerUI.create(ui, busyModel); ui.getMenu().setEnabled(!busyModel.isBusy()); ===================================== client/core/src/main/java/fr/ird/observe/client/main/focus/MainUIFocusModel.java ===================================== @@ -22,7 +22,7 @@ package fr.ird.observe.client.main.focus; * #L% */ -import fr.ird.observe.client.util.busy.BusyModel; +import fr.ird.observe.spi.ui.BusyModel; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/DataSourceEditorBodyContent.java ===================================== @@ -44,7 +44,7 @@ import fr.ird.observe.client.main.ObserveMainUI; import fr.ird.observe.client.main.body.MainUIBodyContent; import fr.ird.observe.client.main.focus.MainUIFocusModel; import fr.ird.observe.client.util.UIHelper; -import fr.ird.observe.client.util.busy.BusyModel; +import fr.ird.observe.spi.ui.BusyModel; import fr.ird.observe.dto.ProgressionModel; import fr.ird.observe.dto.ProtectedIdsCommon; import fr.ird.observe.dto.db.BabModelVersionException; ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/DataSourceEditorModel.java ===================================== @@ -78,4 +78,13 @@ public class DataSourceEditorModel extends AbstractJavaBean { return messageTableModel; } + /** + * apply extra actions from previous opened content (go back to correct tab if any, ...) + * + * @param previousUi previous ui with ui states to apply + */ + public void resetFromPreviousUi(ContentUI previousUi) { + ContentUI newUi = getTypedContent(); + newUi.resetFromPreviousUi(previousUi); + } } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/avdth/ImportDialogHandler.java ===================================== @@ -25,7 +25,7 @@ package fr.ird.observe.client.datasource.editor.api.avdth; import fr.ird.observe.client.WithClientUIContextApi; import fr.ird.observe.client.util.ObserveBlockingLayerUI; import fr.ird.observe.client.util.UIHelper; -import fr.ird.observe.client.util.busy.BusyLayerUI; +import fr.ird.observe.spi.ui.BusyLayerUI; import fr.ird.observe.client.util.init.UIInitHelper; import fr.ird.observe.dto.referential.common.OceanReference; import fr.ird.observe.dto.referential.ps.common.ProgramReference; ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/avdth/ImportDialogModel.java ===================================== @@ -27,7 +27,7 @@ import fr.ird.observe.client.configuration.ClientConfig; import fr.ird.observe.client.datasource.api.ObserveSwingDataSource; import fr.ird.observe.client.datasource.validation.ContentMessageTableModel; import fr.ird.observe.client.main.focus.FocusDispatcher; -import fr.ird.observe.client.util.busy.BusyModel; +import fr.ird.observe.spi.ui.BusyModel; import fr.ird.observe.dto.ProgressionModel; import fr.ird.observe.services.service.data.ps.AvdthDataImportConfiguration; import fr.ird.observe.services.service.data.ps.AvdthDataImportResult; ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/actions/mode/ChangeModeExecutor.java ===================================== @@ -94,15 +94,10 @@ public class ChangeModeExecutor<U extends ContentUI> { node.nodeChangedDeep(); log.info(String.format("Will reselect node: %s", node)); - tree.reSelectSafeNode(node); - // apply extra actions from previous opened content (go back to correct tab if any, ...) - U newUi = dataSourceEditor.getModel().getTypedContent(); - newUi.resetFromPreviousUi(ui); + tree.reSelectSafeNodeThen(node, () -> dataSourceEditor.getModel().resetFromPreviousUi(ui)); } protected void afterOpen(U ui, DataSourceEditor dataSourceEditor, NavigationNode previousOpenedNode, String id) { - - // on repaint le parent (le program devient alors ouvert) NavigationTree tree = dataSourceEditor.getNavigationUI().getTree(); if (previousOpenedNode != null) { @@ -117,14 +112,12 @@ public class ChangeModeExecutor<U extends ContentUI> { selectedNode.nodeChangedDeep(); afterOpenReselectNode(ui, dataSourceEditor, tree, selectedNode, id); SwingUtilities.invokeLater(tree::invalidateCellSizeCache); +// SwingUtilities.invokeLater(tree::repaint); } protected void afterOpenReselectNode(U ui, DataSourceEditor dataSourceEditor, NavigationTree tree, NavigationNode selectedNode, String id) { log.info(String.format("Will reselect node: %s", selectedNode)); - tree.reSelectSafeNode(selectedNode); - // apply extra actions from previous opened content (go back to correct tab if any, ...) - U newUi = dataSourceEditor.getModel().getTypedContent(); - newUi.resetFromPreviousUi(ui); + tree.reSelectSafeNodeThen(selectedNode, () -> dataSourceEditor.getModel().resetFromPreviousUi(ui)); } } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/edit/actions/DeleteEdit.java ===================================== @@ -29,7 +29,7 @@ import fr.ird.observe.client.datasource.editor.api.content.ContentUIHandler; import fr.ird.observe.client.datasource.editor.api.content.data.edit.ContentEditUI; import fr.ird.observe.client.datasource.editor.api.navigation.NavigationTree; import fr.ird.observe.client.datasource.editor.api.navigation.tree.NavigationNode; -import fr.ird.observe.client.util.busy.BusyModel; +import fr.ird.observe.spi.ui.BusyModel; import fr.ird.observe.dto.IdDto; import fr.ird.observe.dto.data.EditableDto; import fr.ird.observe.spi.decoration.DecoratorService; ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/edit/actions/SaveContentEditUIAdapter.java ===================================== @@ -48,14 +48,12 @@ public class SaveContentEditUIAdapter<D extends EditableDto, U extends ContentEd node.updateReference(savedBean.getId()); //FIXME A startEdit should do the math? - dataSourceEditor.getNavigationUI().getTree().reSelectSafeNode(node); + dataSourceEditor.getNavigationUI().getTree().reSelectSafeNodeThen(node, () -> { + dataSourceEditor.getModel().resetFromPreviousUi(ui); + if (notPersisted) { + dataSourceEditor.getNavigationUI().getTree().expandPath(dataSourceEditor.getNavigationUI().getTree().getSelectionPath()); + } + }); - // apply extra actions from previous opened content (go back to correct tab if any, ...) - U newUi = dataSourceEditor.getModel().getTypedContent(); - newUi.resetFromPreviousUi(ui); - - if (notPersisted) { - dataSourceEditor.getNavigationUI().getTree().expandPath(dataSourceEditor.getNavigationUI().getTree().getSelectionPath()); - } } } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/open/actions/SaveContentOpenableUIAdapter.java ===================================== @@ -76,21 +76,19 @@ public class SaveContentOpenableUIAdapter<D extends OpenableDto, U extends Conte protected void afterNodeUpdated(DataSourceEditor dataSourceEditor, U ui, NavigationTree tree, ContentOpenableUINavigationNode node, boolean notPersisted, D bean) { //FIXME A startEdit should do the math? - tree.reSelectSafeNode(node); - - U newUi = dataSourceEditor.getModel().getTypedContent(); - - if (notPersisted && predicate.test(bean)) { - // reload ui and do click - SwingUtilities.invokeLater(() -> Objects.requireNonNull(buttonGetter).apply(newUi).doClick()); - return; - } else { - // apply extra actions from previous opened content (go back to correct tab if any, ...) - newUi.resetFromPreviousUi(ui); - } - - if (notPersisted) { - tree.expandPath(tree.getSelectionPath()); - } + tree.reSelectSafeNodeThen(node, () -> { + if (notPersisted && predicate.test(bean)) { + // reload ui and do click + U newUi = dataSourceEditor.getModel().getTypedContent(); + SwingUtilities.invokeLater(() -> Objects.requireNonNull(buttonGetter).apply(newUi).doClick()); + return; + } else { + dataSourceEditor.getModel().resetFromPreviousUi(ui); + } + + if (notPersisted) { + tree.expandPath(tree.getSelectionPath()); + } + }); } } ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/content/data/ropen/actions/SaveContentRootOpenableUIAdapter.java ===================================== @@ -58,21 +58,17 @@ public class SaveContentRootOpenableUIAdapter<D extends RootOpenableDto, U exten updateReference(node, bean.getId()); NavigationTree tree = dataSourceEditor.getNavigationUI().getTree(); - tree.reSelectSafeNode(node); - - U newUi = dataSourceEditor.getModel().getTypedContent(); - - // apply extra actions from previous opened content (go back to correct tab if any, ...) - newUi.resetFromPreviousUi(ui); - - if (notPersisted) { - tree.expandPath(tree.getSelectionPath()); - } - NavigationUIHandler.updateStatistics(dataSourceEditor.getNavigationUI(), 0, 1); + tree.reSelectSafeNodeThen(node, () -> { + dataSourceEditor.getModel().resetFromPreviousUi(ui); + if (notPersisted) { + tree.expandPath(tree.getSelectionPath()); + } + NavigationUIHandler.updateStatistics(dataSourceEditor.getNavigationUI(), 0, 1); + }); } - public void updateReference(ContentRootOpenableUINavigationNode node , String id) { + public void updateReference(ContentRootOpenableUINavigationNode node, String id) { boolean notPersisted = node.getInitializer().isNotPersisted(); NavigationNode parent = node.getParent(); int oldPosition = parent.getIndex(node); ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/menu/DataSourceEditorMenu.jaxx ===================================== @@ -18,20 +18,7 @@ #L% --> <JMenu id='menuStorage'> - - <!-- <import>--> - <!-- fr.ird.observe.client.main.MainUIModel--> - <!-- fr.ird.observe.client.util.busy.BusyModel--> - <!-- fr.ird.observe.client.util.UIHelper--> - <!-- java.util.Locale--> - <!-- java.awt.Dimension--> - <!-- javax.swing.BoxLayout--> - <!-- javax.swing.JComponent--> - <!-- </import>--> - <DataSourceEditorMenuModel id="uiModel" initializer="getContextValue(DataSourceEditorMenuModel.class)"/> - <!-- <BusyModel id='busyModel' initializer='uiModel.getBusyModel()'/>--> - <!-- <MainUIModel id="mainUiModel" initializer="uiModel.getMainUIModel()"/>--> <JMenuItem id='changeStorage'/> <JMenuItem id='reloadStorage' styleClass="optional"/> <JMenuItem id='closeStorage' styleClass="optional"/> ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/menu/DataSourceEditorMenuModel.java ===================================== @@ -30,7 +30,7 @@ import fr.ird.observe.client.main.MainUIModel; import fr.ird.observe.client.main.body.MainUIBodyContentManager; import fr.ird.observe.client.main.body.NoBodyContentComponent; import fr.ird.observe.client.util.UIHelper; -import fr.ird.observe.client.util.busy.BusyModel; +import fr.ird.observe.spi.ui.BusyModel; import io.ultreia.java4all.bean.AbstractJavaBean; import io.ultreia.java4all.bean.spi.GenerateJavaBeanDefinition; import org.apache.logging.log4j.LogManager; ===================================== client/datasource/editor/api/src/main/java/fr/ird/observe/client/datasource/editor/api/navigation/NavigationTree.java ===================================== @@ -93,7 +93,7 @@ public class NavigationTree extends JXTree implements WithClientUIContextApi { @Override public void updateUI() { - setSelectionModel(new NavigationTreeSelectionModel()); + setSelectionModel(new NavigationTreeSelectionModel(getBusyModel())); super.updateUI(); } @@ -142,25 +142,39 @@ public class NavigationTree extends JXTree implements WithClientUIContextApi { log.info(String.format("try to select safe node [%s]", node)); TreePath path = new TreePath(getModel().getPathToRoot(node)); getSelectionModel().setSkipCheckPreviousContent(true); + getSelectionModel().setSkipBusyModel(true); try { setSelectionPath(path); } finally { getSelectionModel().setSkipCheckPreviousContent(false); + getSelectionModel().setSkipBusyModel(false); } SwingUtilities.invokeLater(() -> scrollPathToVisible(path)); } - public void reSelectSafeNode(TreeNode node) { + public void reSelectSafeNodeThen(TreeNode node, Runnable then) { log.info(String.format("try to reselect safe node [%s]", node)); TreePath path = new TreePath(getModel().getPathToRoot(node)); - getSelectionModel().clearSelection(); - getSelectionModel().setSkipCheckPreviousContent(true); + getSelectionModel().setSkipBusyModel(true); try { - setSelectionPath(path); + getSelectionModel().clearSelection(); + getSelectionModel().setSkipCheckPreviousContent(true); + try { + setSelectionPath(path); + } finally { + getSelectionModel().setSkipCheckPreviousContent(false); + } } finally { - getSelectionModel().setSkipCheckPreviousContent(false); + getSelectionModel().setSkipBusyModel(false); } SwingUtilities.invokeLater(() -> scrollPathToVisible(path)); + if (then != null) { + then.run(); + } + } + + public void reSelectSafeNode(TreeNode node) { + reSelectSafeNodeThen(node, null); } public boolean isRowSelected(int requiredRow) { ===================================== toolkit/api/src/main/i18n/getters/java.getter ===================================== @@ -76,6 +76,10 @@ observe.services.topia.error.h2.database.locked observe.services.topia.error.h2.database.notFound observe.services.topia.error.id.not.found observe.services.topia.error.incompatible.data.source.create.configuration +observe.ui.busy.end.block +observe.ui.busy.end.task +observe.ui.busy.start.block +observe.ui.busy.start.task observe.ui.datasource.storage.error.rest.adminApiKey.invalid observe.ui.datasource.storage.error.rest.adminApiKey.required observe.ui.datasource.storage.error.rest.apiAccess.invalid @@ -87,3 +91,4 @@ observe.ui.datasource.storage.error.rest.password.required observe.ui.datasource.storage.error.rest.user.required observe.ui.datasource.storage.error.rest.user.unknown observe.ui.message.warning.will.be.delete +observe.ui.tree.loading.node ===================================== toolkit/api/src/main/i18n/translations/toolkit_en_GB.properties ===================================== @@ -144,6 +144,10 @@ observe.services.topia.error.h2.database.locked=The H2 database is locked observe.services.topia.error.h2.database.notFound=The H2 database was not found. observe.services.topia.error.id.not.found=Data [%s] not found. observe.services.topia.error.incompatible.data.source.create.configuration=Can not create database, import of data and referential in same time.. +observe.ui.busy.end.block=End main task [%10s] « %s » +observe.ui.busy.end.task=End task (%d) [%10s] « %s » +observe.ui.busy.start.block=Start main task « %s » +observe.ui.busy.start.task=Start task (%d) « %s » observe.ui.datasource.storage.error.rest.adminApiKey.invalid=Admin key not valid observe.ui.datasource.storage.error.rest.adminApiKey.required=Admin key not found observe.ui.datasource.storage.error.rest.apiAccess.invalid=Unauthorized api access (required\: %s, yours is\: %s) @@ -155,3 +159,4 @@ observe.ui.datasource.storage.error.rest.password.required=Password is mandatory observe.ui.datasource.storage.error.rest.user.required=User login is mandatory observe.ui.datasource.storage.error.rest.user.unknown=User "%s" is not defined on server observe.ui.message.warning.will.be.delete=%1$s\n\nBe ware, export will replace existing data. +observe.ui.tree.loading.node=Loading selected node ===================================== toolkit/api/src/main/i18n/translations/toolkit_es_ES.properties ===================================== @@ -144,6 +144,10 @@ observe.services.topia.error.h2.database.locked=La base de datos H2 ya está sie observe.services.topia.error.h2.database.notFound=No se pudó encontrar La base de datos H2. observe.services.topia.error.id.not.found=Data [%s] not found. observe.services.topia.error.incompatible.data.source.create.configuration=Can not create database, import of data and referential in same time.. +observe.ui.busy.end.block=End main task [%10s] « %s » +observe.ui.busy.end.task=End task (%d) [%10s] « %s » +observe.ui.busy.start.block=Start main task « %s » +observe.ui.busy.start.task=Start task (%d) « %s » observe.ui.datasource.storage.error.rest.adminApiKey.invalid=Admin key not valid \#TODO observe.ui.datasource.storage.error.rest.adminApiKey.required=Admin key not found \#TODO observe.ui.datasource.storage.error.rest.apiAccess.invalid=Unauthorized api access (required\: %s, yours is\: %s) \#TODO @@ -155,3 +159,4 @@ observe.ui.datasource.storage.error.rest.password.required=Le contraseña es obl observe.ui.datasource.storage.error.rest.user.required=El usuario es obligatorio observe.ui.datasource.storage.error.rest.user.unknown=El usuario "%s" no es conocido del servidor observe.ui.message.warning.will.be.delete=%1$s\n\nAtención, la exportación reemplazará la marea existente. +observe.ui.tree.loading.node=Loading selected node ===================================== toolkit/api/src/main/i18n/translations/toolkit_fr_FR.properties ===================================== @@ -144,6 +144,10 @@ observe.services.topia.error.h2.database.locked=La base H2 est déjà utilisé p observe.services.topia.error.h2.database.notFound=La base H2 n'a pas été trouvée. observe.services.topia.error.id.not.found=Donnée [%s] non trouvée. observe.services.topia.error.incompatible.data.source.create.configuration=Impossible de créer la base (import données et référentiel demandé en meme temps) +observe.ui.busy.end.block=Action terminée [%10s] « %s » +observe.ui.busy.end.task=Tâche terminée (%d) [%10s] « %s » +observe.ui.busy.start.block=Action en cours « %s » +observe.ui.busy.start.task=Tâche en cours (%d) « %s » observe.ui.datasource.storage.error.rest.adminApiKey.invalid=Pas de clef admin trouvée observe.ui.datasource.storage.error.rest.adminApiKey.required=Clef admin non valide observe.ui.datasource.storage.error.rest.apiAccess.invalid=Accès non autorisé à cette API (Accès requis\: %s, le votre\: %s) @@ -155,3 +159,4 @@ observe.ui.datasource.storage.error.rest.password.required=Le mot de passe est o observe.ui.datasource.storage.error.rest.user.required=L'utilisateur est obligatoire observe.ui.datasource.storage.error.rest.user.unknown=L'utilisateur "%s" est inconnu sur le serveur observe.ui.message.warning.will.be.delete=%1$s\n\nAttention, l'export remplacera la marée existante. +observe.ui.tree.loading.node=Chargement du nœud sélectionné ===================================== toolkit/api/src/main/java/fr/ird/observe/navigation/tree/navigation/NavigationTreeSelectionModel.java ===================================== @@ -25,9 +25,12 @@ package fr.ird.observe.navigation.tree.navigation; import fr.ird.observe.navigation.tree.navigation.event.NavigationTreeSelectionEvent; import fr.ird.observe.navigation.tree.navigation.event.NavigationTreeSelectionListener; import fr.ird.observe.navigation.tree.navigation.event.NavigationTreeSelectionVetoException; +import fr.ird.observe.spi.ui.BusyModel; +import io.ultreia.java4all.i18n.I18n; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import javax.swing.SwingUtilities; import javax.swing.event.TreeExpansionEvent; import javax.swing.tree.DefaultTreeSelectionModel; import javax.swing.tree.ExpandVetoException; @@ -46,9 +49,12 @@ public class NavigationTreeSelectionModel extends DefaultTreeSelectionModel { private static final Logger log = LogManager.getLogger(NavigationTreeSelectionModel.class); + private final BusyModel busyModel; private boolean skipCheckPreviousContent; + private boolean skipBusyModel; - public NavigationTreeSelectionModel() { + public NavigationTreeSelectionModel(BusyModel busyModel) { + this.busyModel = busyModel; setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); } @@ -84,29 +90,35 @@ public class NavigationTreeSelectionModel extends DefaultTreeSelectionModel { return; } TreePath path = pPaths[0]; - boolean[] newness = new boolean[pPaths.length]; - Arrays.fill(newness, true); - NavigationTreeSelectionEvent event = new NavigationTreeSelectionEvent(this, pPaths, newness, getLeadSelectionPath(), path, skipCheckPreviousContent); boolean canChange = !Objects.equals(path, getSelectionPath()); if (canChange) { + boolean[] newness = new boolean[pPaths.length]; + Arrays.fill(newness, true); + NavigationTreeSelectionEvent event = new NavigationTreeSelectionEvent(this, pPaths, newness, getLeadSelectionPath(), path, skipCheckPreviousContent); try { fireVetoValueChanged(event); } catch (NavigationTreeSelectionVetoException e) { canChange = false; } } - -// boolean canChange = skipCheckPreviousContent || (!Objects.equals(path, getSelectionPath()) && contentUIManager.closeSelectedContentUI()); if (!canChange) { // cancel the change of node log.warn(String.format("Do not change selection path: %s against: %s", path, getSelectionPath())); return; } -// FIXME Move this in a listener -// if (skipCheckPreviousContent) { -// contentUIManager.closeSafeSelectedContentUI(); -// } - super.setSelectionPaths(pPaths); + // can now safely select new path + if (busyModel == null || skipBusyModel) { + super.setSelectionPaths(pPaths); + } else { + busyModel.addTask(I18n.t("observe.ui.tree.loading.node")); + SwingUtilities.invokeLater(() -> { + try { + super.setSelectionPaths(pPaths); + } finally { + busyModel.popTask(); + } + }); + } } @Override @@ -135,4 +147,12 @@ public class NavigationTreeSelectionModel extends DefaultTreeSelectionModel { public void setSkipCheckPreviousContent(boolean skipCheckPreviousContent) { this.skipCheckPreviousContent = skipCheckPreviousContent; } + + public boolean isSkipBusyModel() { + return skipBusyModel; + } + + public void setSkipBusyModel(boolean skipBusyModel) { + this.skipBusyModel = skipBusyModel; + } } ===================================== toolkit/api/src/main/java/fr/ird/observe/navigation/tree/navigation/NavigationTreeSupport.java ===================================== @@ -54,7 +54,7 @@ public class NavigationTreeSupport<R extends NavigationTreeNode, M extends Navig @Override public void updateUI() { - setSelectionModel(new NavigationTreeSelectionModel()); + setSelectionModel(new NavigationTreeSelectionModel(null)); super.updateUI(); } ===================================== client/core/src/main/java/fr/ird/observe/client/util/busy/BusyLayerUI.java → toolkit/api/src/main/java/fr/ird/observe/spi/ui/BusyLayerUI.java ===================================== @@ -1,8 +1,8 @@ -package fr.ird.observe.client.util.busy; +package fr.ird.observe.spi.ui; /*- * #%L - * ObServe Client :: Core + * ObServe Toolkit :: API * %% * Copyright (C) 2008 - 2022 IRD, Ultreia.io * %% @@ -22,10 +22,6 @@ package fr.ird.observe.client.util.busy; * #L% */ -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import io.ultreia.java4all.util.TimeLog; - import javax.swing.JComponent; import javax.swing.JLayer; import javax.swing.RootPaneContainer; @@ -40,6 +36,7 @@ import java.awt.Cursor; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.InputEvent; +import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.Closeable; import java.util.Objects; @@ -48,18 +45,13 @@ import java.util.Objects; * @author Tony Chemit - dev@tchemit.fr * @since 8.0.0 */ -public class BusyLayerUI<U extends Component> extends LayerUI<U> implements Closeable { - - private static final Logger log = LogManager.getLogger(BusyLayerUI.class); - private static final TimeLog timeLog = new TimeLog(BusyLayerUI.class, 0, 1000); +public class BusyLayerUI<U extends Component> extends LayerUI<U> implements Closeable, PropertyChangeListener { private final RootPaneContainer rootPanecontainer; private final Container container; private final BusyModel model; private final Color busyColor; - private final PropertyChangeListener listener; private transient Color color; - private long blockingTime; public static void create(RootPaneContainer container, BusyModel busyModel) { Container contentPane = container.getRootPane().getContentPane(); @@ -81,8 +73,7 @@ public class BusyLayerUI<U extends Component> extends LayerUI<U> implements Clos this.container = Objects.requireNonNull(rootPanecontainer.getRootPane()); this.model = Objects.requireNonNull(model); this.busyColor = UIManager.getColor("BlockingLayerUI.busyColor"); - this.listener = evt -> onBusyStateChanged((boolean) evt.getOldValue(), (boolean) evt.getNewValue()); - this.model.addPropertyChangeListener(BusyModel.BUSY_PROPERTY_NAME, listener); + this.model.addPropertyChangeListener(BusyModel.BUSY_PROPERTY_NAME, this); } @Override @@ -125,32 +116,32 @@ public class BusyLayerUI<U extends Component> extends LayerUI<U> implements Clos @Override public void close() { - this.model.removePropertyChangeListener(BusyModel.BUSY_PROPERTY_NAME, listener); + model.removePropertyChangeListener(BusyModel.BUSY_PROPERTY_NAME, this); } public Container getContainer() { return container; } - public void onBusyStateChanged(boolean wasBusy, boolean isBusy) { - if (wasBusy == isBusy) { - return; - } - - color = isBusy ? busyColor : null; - if (isBusy) { - blockingTime = TimeLog.getTime(); - log.debug("Blocking ui at " + blockingTime); - container.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - } else { - timeLog.log(blockingTime, "unblock"); - container.setCursor(Cursor.getDefaultCursor()); - } - rootPanecontainer.getRootPane().repaint(); - } - public boolean isBusy() { return color != null; } + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (BusyModel.BUSY_PROPERTY_NAME.equals(evt.getPropertyName())) { + boolean wasBusy = (boolean) evt.getOldValue(); + boolean isBusy = (boolean) evt.getNewValue(); + if (wasBusy == isBusy) { + return; + } + color = isBusy ? busyColor : null; + if (isBusy) { + container.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } else { + container.setCursor(Cursor.getDefaultCursor()); + } + rootPanecontainer.getRootPane().repaint(); + } + } } ===================================== client/core/src/main/java/fr/ird/observe/client/util/busy/BusyModel.java → toolkit/api/src/main/java/fr/ird/observe/spi/ui/BusyModel.java ===================================== @@ -1,8 +1,8 @@ -package fr.ird.observe.client.util.busy; +package fr.ird.observe.spi.ui; /*- * #%L - * ObServe Client :: Core + * ObServe Toolkit :: API * %% * Copyright (C) 2008 - 2022 IRD, Ultreia.io * %% @@ -24,6 +24,9 @@ package fr.ird.observe.client.util.busy; import io.ultreia.java4all.bean.AbstractJavaBean; import io.ultreia.java4all.bean.spi.GenerateJavaBeanDefinition; +import io.ultreia.java4all.i18n.I18n; +import io.ultreia.java4all.lang.Strings; +import io.ultreia.java4all.util.TimeLog; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -36,36 +39,76 @@ import java.util.Deque; */ @GenerateJavaBeanDefinition public class BusyModel extends AbstractJavaBean { - + private static final TimeLog timeLog = new TimeLog(BusyModel.class, 500, 1000); private static final Logger log = LogManager.getLogger(BusyModel.class); + static class BusyTask { + private final String taskName; + private final int rank; + private final long startTime; + + BusyTask(String taskName, int rank) { + this.taskName = taskName; + this.rank = rank; + this.startTime = TimeLog.getTime(); + } + + public int getRank() { + return rank; + } + + public String getTaskName() { + return taskName; + } + + public long getStartTime() { + return startTime; + } + + } + public static final String BUSY_PROPERTY_NAME = "busy"; - private final Deque<String> tasks; + private final Deque<BusyTask> tasks; public BusyModel() { tasks = new ArrayDeque<>(); } - public synchronized void addTask(String task) { - log.debug("Add task: " + task); + public synchronized void addTask(String taskName) { boolean oldValue = isBusy(); + BusyTask task = new BusyTask(taskName, tasks.size() + 1); + log.info(I18n.t("observe.ui.busy.start.task", task.getRank(), taskName)); tasks.add(task); - fireBusyStateChanged(oldValue); + fireBusyStateChanged(oldValue, task, null); } public synchronized void popTask() { boolean oldValue = isBusy(); - String task = tasks.removeLast(); - log.debug("Remove task: " + task); - fireBusyStateChanged(oldValue); + BusyTask task = tasks.removeLast(); + String taskName = task.getTaskName(); + long startTime = task.getStartTime(); + String delay = Strings.convertTime(TimeLog.getTime() - startTime); + log.info(I18n.t("observe.ui.busy.end.task", task.getRank(), delay, taskName)); + timeLog.log(startTime, "task done", taskName); + fireBusyStateChanged(oldValue, task, delay); } public boolean isBusy() { return !tasks.isEmpty(); } - void fireBusyStateChanged(boolean oldValue) { + void fireBusyStateChanged(boolean oldValue, BusyTask task, String delay) { boolean busy = isBusy(); - firePropertyChange(BUSY_PROPERTY_NAME, oldValue, busy); + if (oldValue != busy) { + String taskName = task.getTaskName(); + if (busy) { + log.info(I18n.t("observe.ui.busy.start.block", taskName)); + } else { + long startTime = task.getStartTime(); + log.info(I18n.t("observe.ui.busy.end.block", delay, taskName)); + timeLog.log(startTime, "unblock", taskName); + } + firePropertyChange(BUSY_PROPERTY_NAME, oldValue, busy); + } } } View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/commit/7d0c19308e21d631e84c16c2a2... -- View it on GitLab: https://gitlab.com/ultreiaio/ird-observe/-/commit/7d0c19308e21d631e84c16c2a2... You're receiving this email because of your account on gitlab.com.
participants (1)
-
Tony CHEMIT (@tchemit)