Tony CHEMIT pushed to branch develop at ultreiaio / ird-observe
Commits:
-
7d0c1930
by Tony Chemit at 2022-08-03T18:31:38+02:00
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:
| ... | ... | @@ -33,7 +33,7 @@ import fr.ird.observe.client.main.body.NoBodyContentComponent; |
| 33 | 33 | import fr.ird.observe.client.main.callback.ObserveUICallbackManager;
|
| 34 | 34 | import fr.ird.observe.client.main.focus.MainUIFocusModel;
|
| 35 | 35 | import fr.ird.observe.client.util.action.ObserveExecutorService;
|
| 36 | -import fr.ird.observe.client.util.busy.BusyModel;
|
|
| 36 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 37 | 37 | import fr.ird.observe.client.util.session.ObserveSwingSessionHelper;
|
| 38 | 38 | import fr.ird.observe.dto.data.ps.dcp.FloatingObjectPresetsManager;
|
| 39 | 39 | import fr.ird.observe.navigation.id.IdProjectManager;
|
| ... | ... | @@ -32,7 +32,7 @@ import fr.ird.observe.client.main.ObserveMainUI; |
| 32 | 32 | import fr.ird.observe.client.main.callback.ObserveUICallbackManager;
|
| 33 | 33 | import fr.ird.observe.client.main.focus.MainUIFocusModel;
|
| 34 | 34 | import fr.ird.observe.client.util.UIHelper;
|
| 35 | -import fr.ird.observe.client.util.busy.BusyModel;
|
|
| 35 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 36 | 36 | import fr.ird.observe.client.util.session.ObserveSwingSessionHelper;
|
| 37 | 37 | import fr.ird.observe.dto.ObserveUtil;
|
| 38 | 38 | import fr.ird.observe.dto.data.ps.dcp.FloatingObjectPresetsManager;
|
| ... | ... | @@ -31,7 +31,7 @@ import fr.ird.observe.client.main.MainUIModel; |
| 31 | 31 | import fr.ird.observe.client.main.ObserveMainUI;
|
| 32 | 32 | import fr.ird.observe.client.main.callback.ObserveUICallbackManager;
|
| 33 | 33 | import fr.ird.observe.client.main.focus.MainUIFocusModel;
|
| 34 | -import fr.ird.observe.client.util.busy.BusyModel;
|
|
| 34 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 35 | 35 | import fr.ird.observe.client.util.session.ObserveSwingSessionHelper;
|
| 36 | 36 | import fr.ird.observe.dto.data.ps.dcp.FloatingObjectPresetsManager;
|
| 37 | 37 | import fr.ird.observe.navigation.id.IdProjectManager;
|
| ... | ... | @@ -24,7 +24,7 @@ package fr.ird.observe.client.main; |
| 24 | 24 | |
| 25 | 25 | import fr.ird.observe.client.configuration.ClientConfig;
|
| 26 | 26 | import fr.ird.observe.client.main.focus.MainUIFocusModel;
|
| 27 | -import fr.ird.observe.client.util.busy.BusyModel;
|
|
| 27 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 28 | 28 | import io.ultreia.java4all.bean.AbstractJavaBean;
|
| 29 | 29 | import io.ultreia.java4all.bean.spi.GenerateJavaBeanDefinition;
|
| 30 | 30 |
| ... | ... | @@ -22,7 +22,7 @@ |
| 22 | 22 | |
| 23 | 23 | <import>
|
| 24 | 24 | fr.ird.observe.client.util.JMenuWithAccelerator
|
| 25 | - fr.ird.observe.client.util.busy.BusyModel
|
|
| 25 | + fr.ird.observe.spi.ui.BusyModel
|
|
| 26 | 26 | fr.ird.observe.client.configuration.ClientConfig
|
| 27 | 27 | fr.ird.observe.client.main.MainUIModel
|
| 28 | 28 | fr.ird.observe.client.main.body.MainUIBodyContentManager
|
| ... | ... | @@ -27,8 +27,8 @@ import fr.ird.observe.client.configuration.ClientConfig; |
| 27 | 27 | import fr.ird.observe.client.main.body.MainUIBodyContentManager;
|
| 28 | 28 | import fr.ird.observe.client.util.ObserveKeyStrokesSupport;
|
| 29 | 29 | import fr.ird.observe.client.util.UIHelper;
|
| 30 | -import fr.ird.observe.client.util.busy.BusyLayerUI;
|
|
| 31 | -import fr.ird.observe.client.util.busy.BusyModel;
|
|
| 30 | +import fr.ird.observe.spi.ui.BusyLayerUI;
|
|
| 31 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 32 | 32 | import org.apache.logging.log4j.LogManager;
|
| 33 | 33 | import org.apache.logging.log4j.Logger;
|
| 34 | 34 | import org.nuiton.jaxx.runtime.spi.UIHandler;
|
| ... | ... | @@ -102,7 +102,7 @@ public class ObserveMainUIHandler implements UIHandler<ObserveMainUI>, WithClien |
| 102 | 102 | |
| 103 | 103 | ui.getStatus().init();
|
| 104 | 104 | |
| 105 | - // installation layer de blocage en mode busy
|
|
| 105 | + // init blocking layer associated with the busy model
|
|
| 106 | 106 | BusyLayerUI.create(ui, busyModel);
|
| 107 | 107 | |
| 108 | 108 | ui.getMenu().setEnabled(!busyModel.isBusy());
|
| ... | ... | @@ -22,7 +22,7 @@ package fr.ird.observe.client.main.focus; |
| 22 | 22 | * #L%
|
| 23 | 23 | */
|
| 24 | 24 | |
| 25 | -import fr.ird.observe.client.util.busy.BusyModel;
|
|
| 25 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 26 | 26 | import org.apache.logging.log4j.LogManager;
|
| 27 | 27 | import org.apache.logging.log4j.Logger;
|
| 28 | 28 |
| ... | ... | @@ -44,7 +44,7 @@ import fr.ird.observe.client.main.ObserveMainUI; |
| 44 | 44 | import fr.ird.observe.client.main.body.MainUIBodyContent;
|
| 45 | 45 | import fr.ird.observe.client.main.focus.MainUIFocusModel;
|
| 46 | 46 | import fr.ird.observe.client.util.UIHelper;
|
| 47 | -import fr.ird.observe.client.util.busy.BusyModel;
|
|
| 47 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 48 | 48 | import fr.ird.observe.dto.ProgressionModel;
|
| 49 | 49 | import fr.ird.observe.dto.ProtectedIdsCommon;
|
| 50 | 50 | import fr.ird.observe.dto.db.BabModelVersionException;
|
| ... | ... | @@ -78,4 +78,13 @@ public class DataSourceEditorModel extends AbstractJavaBean { |
| 78 | 78 | return messageTableModel;
|
| 79 | 79 | }
|
| 80 | 80 | |
| 81 | + /**
|
|
| 82 | + * apply extra actions from previous opened content (go back to correct tab if any, ...)
|
|
| 83 | + *
|
|
| 84 | + * @param previousUi previous ui with ui states to apply
|
|
| 85 | + */
|
|
| 86 | + public void resetFromPreviousUi(ContentUI previousUi) {
|
|
| 87 | + ContentUI newUi = getTypedContent();
|
|
| 88 | + newUi.resetFromPreviousUi(previousUi);
|
|
| 89 | + }
|
|
| 81 | 90 | } |
| ... | ... | @@ -25,7 +25,7 @@ package fr.ird.observe.client.datasource.editor.api.avdth; |
| 25 | 25 | import fr.ird.observe.client.WithClientUIContextApi;
|
| 26 | 26 | import fr.ird.observe.client.util.ObserveBlockingLayerUI;
|
| 27 | 27 | import fr.ird.observe.client.util.UIHelper;
|
| 28 | -import fr.ird.observe.client.util.busy.BusyLayerUI;
|
|
| 28 | +import fr.ird.observe.spi.ui.BusyLayerUI;
|
|
| 29 | 29 | import fr.ird.observe.client.util.init.UIInitHelper;
|
| 30 | 30 | import fr.ird.observe.dto.referential.common.OceanReference;
|
| 31 | 31 | import fr.ird.observe.dto.referential.ps.common.ProgramReference;
|
| ... | ... | @@ -27,7 +27,7 @@ import fr.ird.observe.client.configuration.ClientConfig; |
| 27 | 27 | import fr.ird.observe.client.datasource.api.ObserveSwingDataSource;
|
| 28 | 28 | import fr.ird.observe.client.datasource.validation.ContentMessageTableModel;
|
| 29 | 29 | import fr.ird.observe.client.main.focus.FocusDispatcher;
|
| 30 | -import fr.ird.observe.client.util.busy.BusyModel;
|
|
| 30 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 31 | 31 | import fr.ird.observe.dto.ProgressionModel;
|
| 32 | 32 | import fr.ird.observe.services.service.data.ps.AvdthDataImportConfiguration;
|
| 33 | 33 | import fr.ird.observe.services.service.data.ps.AvdthDataImportResult;
|
| ... | ... | @@ -94,15 +94,10 @@ public class ChangeModeExecutor<U extends ContentUI> { |
| 94 | 94 | node.nodeChangedDeep();
|
| 95 | 95 | |
| 96 | 96 | log.info(String.format("Will reselect node: %s", node));
|
| 97 | - tree.reSelectSafeNode(node);
|
|
| 98 | - // apply extra actions from previous opened content (go back to correct tab if any, ...)
|
|
| 99 | - U newUi = dataSourceEditor.getModel().getTypedContent();
|
|
| 100 | - newUi.resetFromPreviousUi(ui);
|
|
| 97 | + tree.reSelectSafeNodeThen(node, () -> dataSourceEditor.getModel().resetFromPreviousUi(ui));
|
|
| 101 | 98 | }
|
| 102 | 99 | |
| 103 | 100 | protected void afterOpen(U ui, DataSourceEditor dataSourceEditor, NavigationNode previousOpenedNode, String id) {
|
| 104 | - |
|
| 105 | - // on repaint le parent (le program devient alors ouvert)
|
|
| 106 | 101 | NavigationTree tree = dataSourceEditor.getNavigationUI().getTree();
|
| 107 | 102 | |
| 108 | 103 | if (previousOpenedNode != null) {
|
| ... | ... | @@ -117,14 +112,12 @@ public class ChangeModeExecutor<U extends ContentUI> { |
| 117 | 112 | selectedNode.nodeChangedDeep();
|
| 118 | 113 | afterOpenReselectNode(ui, dataSourceEditor, tree, selectedNode, id);
|
| 119 | 114 | SwingUtilities.invokeLater(tree::invalidateCellSizeCache);
|
| 115 | +// SwingUtilities.invokeLater(tree::repaint);
|
|
| 120 | 116 | }
|
| 121 | 117 | |
| 122 | 118 | protected void afterOpenReselectNode(U ui, DataSourceEditor dataSourceEditor, NavigationTree tree, NavigationNode selectedNode, String id) {
|
| 123 | 119 | log.info(String.format("Will reselect node: %s", selectedNode));
|
| 124 | - tree.reSelectSafeNode(selectedNode);
|
|
| 125 | - // apply extra actions from previous opened content (go back to correct tab if any, ...)
|
|
| 126 | - U newUi = dataSourceEditor.getModel().getTypedContent();
|
|
| 127 | - newUi.resetFromPreviousUi(ui);
|
|
| 120 | + tree.reSelectSafeNodeThen(selectedNode, () -> dataSourceEditor.getModel().resetFromPreviousUi(ui));
|
|
| 128 | 121 | }
|
| 129 | 122 | |
| 130 | 123 | } |
| ... | ... | @@ -29,7 +29,7 @@ import fr.ird.observe.client.datasource.editor.api.content.ContentUIHandler; |
| 29 | 29 | import fr.ird.observe.client.datasource.editor.api.content.data.edit.ContentEditUI;
|
| 30 | 30 | import fr.ird.observe.client.datasource.editor.api.navigation.NavigationTree;
|
| 31 | 31 | import fr.ird.observe.client.datasource.editor.api.navigation.tree.NavigationNode;
|
| 32 | -import fr.ird.observe.client.util.busy.BusyModel;
|
|
| 32 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 33 | 33 | import fr.ird.observe.dto.IdDto;
|
| 34 | 34 | import fr.ird.observe.dto.data.EditableDto;
|
| 35 | 35 | import fr.ird.observe.spi.decoration.DecoratorService;
|
| ... | ... | @@ -48,14 +48,12 @@ public class SaveContentEditUIAdapter<D extends EditableDto, U extends ContentEd |
| 48 | 48 | node.updateReference(savedBean.getId());
|
| 49 | 49 | |
| 50 | 50 | //FIXME A startEdit should do the math?
|
| 51 | - dataSourceEditor.getNavigationUI().getTree().reSelectSafeNode(node);
|
|
| 51 | + dataSourceEditor.getNavigationUI().getTree().reSelectSafeNodeThen(node, () -> {
|
|
| 52 | + dataSourceEditor.getModel().resetFromPreviousUi(ui);
|
|
| 53 | + if (notPersisted) {
|
|
| 54 | + dataSourceEditor.getNavigationUI().getTree().expandPath(dataSourceEditor.getNavigationUI().getTree().getSelectionPath());
|
|
| 55 | + }
|
|
| 56 | + });
|
|
| 52 | 57 | |
| 53 | - // apply extra actions from previous opened content (go back to correct tab if any, ...)
|
|
| 54 | - U newUi = dataSourceEditor.getModel().getTypedContent();
|
|
| 55 | - newUi.resetFromPreviousUi(ui);
|
|
| 56 | - |
|
| 57 | - if (notPersisted) {
|
|
| 58 | - dataSourceEditor.getNavigationUI().getTree().expandPath(dataSourceEditor.getNavigationUI().getTree().getSelectionPath());
|
|
| 59 | - }
|
|
| 60 | 58 | }
|
| 61 | 59 | } |
| ... | ... | @@ -76,21 +76,19 @@ public class SaveContentOpenableUIAdapter<D extends OpenableDto, U extends Conte |
| 76 | 76 | protected void afterNodeUpdated(DataSourceEditor dataSourceEditor, U ui, NavigationTree tree, ContentOpenableUINavigationNode node, boolean notPersisted, D bean) {
|
| 77 | 77 | |
| 78 | 78 | //FIXME A startEdit should do the math?
|
| 79 | - tree.reSelectSafeNode(node);
|
|
| 80 | - |
|
| 81 | - U newUi = dataSourceEditor.getModel().getTypedContent();
|
|
| 82 | - |
|
| 83 | - if (notPersisted && predicate.test(bean)) {
|
|
| 84 | - // reload ui and do click
|
|
| 85 | - SwingUtilities.invokeLater(() -> Objects.requireNonNull(buttonGetter).apply(newUi).doClick());
|
|
| 86 | - return;
|
|
| 87 | - } else {
|
|
| 88 | - // apply extra actions from previous opened content (go back to correct tab if any, ...)
|
|
| 89 | - newUi.resetFromPreviousUi(ui);
|
|
| 90 | - }
|
|
| 91 | - |
|
| 92 | - if (notPersisted) {
|
|
| 93 | - tree.expandPath(tree.getSelectionPath());
|
|
| 94 | - }
|
|
| 79 | + tree.reSelectSafeNodeThen(node, () -> {
|
|
| 80 | + if (notPersisted && predicate.test(bean)) {
|
|
| 81 | + // reload ui and do click
|
|
| 82 | + U newUi = dataSourceEditor.getModel().getTypedContent();
|
|
| 83 | + SwingUtilities.invokeLater(() -> Objects.requireNonNull(buttonGetter).apply(newUi).doClick());
|
|
| 84 | + return;
|
|
| 85 | + } else {
|
|
| 86 | + dataSourceEditor.getModel().resetFromPreviousUi(ui);
|
|
| 87 | + }
|
|
| 88 | + |
|
| 89 | + if (notPersisted) {
|
|
| 90 | + tree.expandPath(tree.getSelectionPath());
|
|
| 91 | + }
|
|
| 92 | + });
|
|
| 95 | 93 | }
|
| 96 | 94 | } |
| ... | ... | @@ -58,21 +58,17 @@ public class SaveContentRootOpenableUIAdapter<D extends RootOpenableDto, U exten |
| 58 | 58 | updateReference(node, bean.getId());
|
| 59 | 59 | |
| 60 | 60 | NavigationTree tree = dataSourceEditor.getNavigationUI().getTree();
|
| 61 | - tree.reSelectSafeNode(node);
|
|
| 62 | - |
|
| 63 | - U newUi = dataSourceEditor.getModel().getTypedContent();
|
|
| 64 | - |
|
| 65 | - // apply extra actions from previous opened content (go back to correct tab if any, ...)
|
|
| 66 | - newUi.resetFromPreviousUi(ui);
|
|
| 67 | - |
|
| 68 | - if (notPersisted) {
|
|
| 69 | - tree.expandPath(tree.getSelectionPath());
|
|
| 70 | - }
|
|
| 71 | - NavigationUIHandler.updateStatistics(dataSourceEditor.getNavigationUI(), 0, 1);
|
|
| 61 | + tree.reSelectSafeNodeThen(node, () -> {
|
|
| 62 | + dataSourceEditor.getModel().resetFromPreviousUi(ui);
|
|
| 63 | + if (notPersisted) {
|
|
| 64 | + tree.expandPath(tree.getSelectionPath());
|
|
| 65 | + }
|
|
| 66 | + NavigationUIHandler.updateStatistics(dataSourceEditor.getNavigationUI(), 0, 1);
|
|
| 67 | + });
|
|
| 72 | 68 | }
|
| 73 | 69 | |
| 74 | 70 | |
| 75 | - public void updateReference(ContentRootOpenableUINavigationNode node , String id) {
|
|
| 71 | + public void updateReference(ContentRootOpenableUINavigationNode node, String id) {
|
|
| 76 | 72 | boolean notPersisted = node.getInitializer().isNotPersisted();
|
| 77 | 73 | NavigationNode parent = node.getParent();
|
| 78 | 74 | int oldPosition = parent.getIndex(node);
|
| ... | ... | @@ -18,20 +18,7 @@ |
| 18 | 18 | #L%
|
| 19 | 19 | -->
|
| 20 | 20 | <JMenu id='menuStorage'>
|
| 21 | - |
|
| 22 | - <!-- <import>-->
|
|
| 23 | - <!-- fr.ird.observe.client.main.MainUIModel-->
|
|
| 24 | - <!-- fr.ird.observe.client.util.busy.BusyModel-->
|
|
| 25 | - <!-- fr.ird.observe.client.util.UIHelper-->
|
|
| 26 | - <!-- java.util.Locale-->
|
|
| 27 | - <!-- java.awt.Dimension-->
|
|
| 28 | - <!-- javax.swing.BoxLayout-->
|
|
| 29 | - <!-- javax.swing.JComponent-->
|
|
| 30 | - <!-- </import>-->
|
|
| 31 | - |
|
| 32 | 21 | <DataSourceEditorMenuModel id="uiModel" initializer="getContextValue(DataSourceEditorMenuModel.class)"/>
|
| 33 | - <!-- <BusyModel id='busyModel' initializer='uiModel.getBusyModel()'/>-->
|
|
| 34 | - <!-- <MainUIModel id="mainUiModel" initializer="uiModel.getMainUIModel()"/>-->
|
|
| 35 | 22 | <JMenuItem id='changeStorage'/>
|
| 36 | 23 | <JMenuItem id='reloadStorage' styleClass="optional"/>
|
| 37 | 24 | <JMenuItem id='closeStorage' styleClass="optional"/>
|
| ... | ... | @@ -30,7 +30,7 @@ import fr.ird.observe.client.main.MainUIModel; |
| 30 | 30 | import fr.ird.observe.client.main.body.MainUIBodyContentManager;
|
| 31 | 31 | import fr.ird.observe.client.main.body.NoBodyContentComponent;
|
| 32 | 32 | import fr.ird.observe.client.util.UIHelper;
|
| 33 | -import fr.ird.observe.client.util.busy.BusyModel;
|
|
| 33 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 34 | 34 | import io.ultreia.java4all.bean.AbstractJavaBean;
|
| 35 | 35 | import io.ultreia.java4all.bean.spi.GenerateJavaBeanDefinition;
|
| 36 | 36 | import org.apache.logging.log4j.LogManager;
|
| ... | ... | @@ -93,7 +93,7 @@ public class NavigationTree extends JXTree implements WithClientUIContextApi { |
| 93 | 93 | |
| 94 | 94 | @Override
|
| 95 | 95 | public void updateUI() {
|
| 96 | - setSelectionModel(new NavigationTreeSelectionModel());
|
|
| 96 | + setSelectionModel(new NavigationTreeSelectionModel(getBusyModel()));
|
|
| 97 | 97 | super.updateUI();
|
| 98 | 98 | }
|
| 99 | 99 | |
| ... | ... | @@ -142,25 +142,39 @@ public class NavigationTree extends JXTree implements WithClientUIContextApi { |
| 142 | 142 | log.info(String.format("try to select safe node [%s]", node));
|
| 143 | 143 | TreePath path = new TreePath(getModel().getPathToRoot(node));
|
| 144 | 144 | getSelectionModel().setSkipCheckPreviousContent(true);
|
| 145 | + getSelectionModel().setSkipBusyModel(true);
|
|
| 145 | 146 | try {
|
| 146 | 147 | setSelectionPath(path);
|
| 147 | 148 | } finally {
|
| 148 | 149 | getSelectionModel().setSkipCheckPreviousContent(false);
|
| 150 | + getSelectionModel().setSkipBusyModel(false);
|
|
| 149 | 151 | }
|
| 150 | 152 | SwingUtilities.invokeLater(() -> scrollPathToVisible(path));
|
| 151 | 153 | }
|
| 152 | 154 | |
| 153 | - public void reSelectSafeNode(TreeNode node) {
|
|
| 155 | + public void reSelectSafeNodeThen(TreeNode node, Runnable then) {
|
|
| 154 | 156 | log.info(String.format("try to reselect safe node [%s]", node));
|
| 155 | 157 | TreePath path = new TreePath(getModel().getPathToRoot(node));
|
| 156 | - getSelectionModel().clearSelection();
|
|
| 157 | - getSelectionModel().setSkipCheckPreviousContent(true);
|
|
| 158 | + getSelectionModel().setSkipBusyModel(true);
|
|
| 158 | 159 | try {
|
| 159 | - setSelectionPath(path);
|
|
| 160 | + getSelectionModel().clearSelection();
|
|
| 161 | + getSelectionModel().setSkipCheckPreviousContent(true);
|
|
| 162 | + try {
|
|
| 163 | + setSelectionPath(path);
|
|
| 164 | + } finally {
|
|
| 165 | + getSelectionModel().setSkipCheckPreviousContent(false);
|
|
| 166 | + }
|
|
| 160 | 167 | } finally {
|
| 161 | - getSelectionModel().setSkipCheckPreviousContent(false);
|
|
| 168 | + getSelectionModel().setSkipBusyModel(false);
|
|
| 162 | 169 | }
|
| 163 | 170 | SwingUtilities.invokeLater(() -> scrollPathToVisible(path));
|
| 171 | + if (then != null) {
|
|
| 172 | + then.run();
|
|
| 173 | + }
|
|
| 174 | + }
|
|
| 175 | + |
|
| 176 | + public void reSelectSafeNode(TreeNode node) {
|
|
| 177 | + reSelectSafeNodeThen(node, null);
|
|
| 164 | 178 | }
|
| 165 | 179 | |
| 166 | 180 | public boolean isRowSelected(int requiredRow) {
|
| ... | ... | @@ -76,6 +76,10 @@ observe.services.topia.error.h2.database.locked |
| 76 | 76 | observe.services.topia.error.h2.database.notFound
|
| 77 | 77 | observe.services.topia.error.id.not.found
|
| 78 | 78 | observe.services.topia.error.incompatible.data.source.create.configuration
|
| 79 | +observe.ui.busy.end.block
|
|
| 80 | +observe.ui.busy.end.task
|
|
| 81 | +observe.ui.busy.start.block
|
|
| 82 | +observe.ui.busy.start.task
|
|
| 79 | 83 | observe.ui.datasource.storage.error.rest.adminApiKey.invalid
|
| 80 | 84 | observe.ui.datasource.storage.error.rest.adminApiKey.required
|
| 81 | 85 | observe.ui.datasource.storage.error.rest.apiAccess.invalid
|
| ... | ... | @@ -87,3 +91,4 @@ observe.ui.datasource.storage.error.rest.password.required |
| 87 | 91 | observe.ui.datasource.storage.error.rest.user.required
|
| 88 | 92 | observe.ui.datasource.storage.error.rest.user.unknown
|
| 89 | 93 | observe.ui.message.warning.will.be.delete
|
| 94 | +observe.ui.tree.loading.node |
| ... | ... | @@ -144,6 +144,10 @@ observe.services.topia.error.h2.database.locked=The H2 database is locked |
| 144 | 144 | observe.services.topia.error.h2.database.notFound=The H2 database was not found.
|
| 145 | 145 | observe.services.topia.error.id.not.found=Data [%s] not found.
|
| 146 | 146 | observe.services.topia.error.incompatible.data.source.create.configuration=Can not create database, import of data and referential in same time.
|
| 147 | +observe.ui.busy.end.block=End main task [%10s] « %s »
|
|
| 148 | +observe.ui.busy.end.task=End task (%d) [%10s] « %s »
|
|
| 149 | +observe.ui.busy.start.block=Start main task « %s »
|
|
| 150 | +observe.ui.busy.start.task=Start task (%d) « %s »
|
|
| 147 | 151 | observe.ui.datasource.storage.error.rest.adminApiKey.invalid=Admin key not valid
|
| 148 | 152 | observe.ui.datasource.storage.error.rest.adminApiKey.required=Admin key not found
|
| 149 | 153 | 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 |
| 155 | 159 | observe.ui.datasource.storage.error.rest.user.required=User login is mandatory
|
| 156 | 160 | observe.ui.datasource.storage.error.rest.user.unknown=User "%s" is not defined on server
|
| 157 | 161 | observe.ui.message.warning.will.be.delete=%1$s\n\nBe ware, export will replace existing data.
|
| 162 | +observe.ui.tree.loading.node=Loading selected node |
| ... | ... | @@ -144,6 +144,10 @@ observe.services.topia.error.h2.database.locked=La base de datos H2 ya está sie |
| 144 | 144 | observe.services.topia.error.h2.database.notFound=No se pudó encontrar La base de datos H2.
|
| 145 | 145 | observe.services.topia.error.id.not.found=Data [%s] not found.
|
| 146 | 146 | observe.services.topia.error.incompatible.data.source.create.configuration=Can not create database, import of data and referential in same time.
|
| 147 | +observe.ui.busy.end.block=End main task [%10s] « %s »
|
|
| 148 | +observe.ui.busy.end.task=End task (%d) [%10s] « %s »
|
|
| 149 | +observe.ui.busy.start.block=Start main task « %s »
|
|
| 150 | +observe.ui.busy.start.task=Start task (%d) « %s »
|
|
| 147 | 151 | observe.ui.datasource.storage.error.rest.adminApiKey.invalid=Admin key not valid \#TODO
|
| 148 | 152 | observe.ui.datasource.storage.error.rest.adminApiKey.required=Admin key not found \#TODO
|
| 149 | 153 | 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 |
| 155 | 159 | observe.ui.datasource.storage.error.rest.user.required=El usuario es obligatorio
|
| 156 | 160 | observe.ui.datasource.storage.error.rest.user.unknown=El usuario "%s" no es conocido del servidor
|
| 157 | 161 | observe.ui.message.warning.will.be.delete=%1$s\n\nAtención, la exportación reemplazará la marea existente.
|
| 162 | +observe.ui.tree.loading.node=Loading selected node |
| ... | ... | @@ -144,6 +144,10 @@ observe.services.topia.error.h2.database.locked=La base H2 est déjà utilisé p |
| 144 | 144 | observe.services.topia.error.h2.database.notFound=La base H2 n'a pas été trouvée.
|
| 145 | 145 | observe.services.topia.error.id.not.found=Donnée [%s] non trouvée.
|
| 146 | 146 | 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)
|
| 147 | +observe.ui.busy.end.block=Action terminée [%10s] « %s »
|
|
| 148 | +observe.ui.busy.end.task=Tâche terminée (%d) [%10s] « %s »
|
|
| 149 | +observe.ui.busy.start.block=Action en cours « %s »
|
|
| 150 | +observe.ui.busy.start.task=Tâche en cours (%d) « %s »
|
|
| 147 | 151 | observe.ui.datasource.storage.error.rest.adminApiKey.invalid=Pas de clef admin trouvée
|
| 148 | 152 | observe.ui.datasource.storage.error.rest.adminApiKey.required=Clef admin non valide
|
| 149 | 153 | 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 |
| 155 | 159 | observe.ui.datasource.storage.error.rest.user.required=L'utilisateur est obligatoire
|
| 156 | 160 | observe.ui.datasource.storage.error.rest.user.unknown=L'utilisateur "%s" est inconnu sur le serveur
|
| 157 | 161 | observe.ui.message.warning.will.be.delete=%1$s\n\nAttention, l'export remplacera la marée existante.
|
| 162 | +observe.ui.tree.loading.node=Chargement du nœud sélectionné |
| ... | ... | @@ -25,9 +25,12 @@ package fr.ird.observe.navigation.tree.navigation; |
| 25 | 25 | import fr.ird.observe.navigation.tree.navigation.event.NavigationTreeSelectionEvent;
|
| 26 | 26 | import fr.ird.observe.navigation.tree.navigation.event.NavigationTreeSelectionListener;
|
| 27 | 27 | import fr.ird.observe.navigation.tree.navigation.event.NavigationTreeSelectionVetoException;
|
| 28 | +import fr.ird.observe.spi.ui.BusyModel;
|
|
| 29 | +import io.ultreia.java4all.i18n.I18n;
|
|
| 28 | 30 | import org.apache.logging.log4j.LogManager;
|
| 29 | 31 | import org.apache.logging.log4j.Logger;
|
| 30 | 32 | |
| 33 | +import javax.swing.SwingUtilities;
|
|
| 31 | 34 | import javax.swing.event.TreeExpansionEvent;
|
| 32 | 35 | import javax.swing.tree.DefaultTreeSelectionModel;
|
| 33 | 36 | import javax.swing.tree.ExpandVetoException;
|
| ... | ... | @@ -46,9 +49,12 @@ public class NavigationTreeSelectionModel extends DefaultTreeSelectionModel { |
| 46 | 49 | |
| 47 | 50 | private static final Logger log = LogManager.getLogger(NavigationTreeSelectionModel.class);
|
| 48 | 51 | |
| 52 | + private final BusyModel busyModel;
|
|
| 49 | 53 | private boolean skipCheckPreviousContent;
|
| 54 | + private boolean skipBusyModel;
|
|
| 50 | 55 | |
| 51 | - public NavigationTreeSelectionModel() {
|
|
| 56 | + public NavigationTreeSelectionModel(BusyModel busyModel) {
|
|
| 57 | + this.busyModel = busyModel;
|
|
| 52 | 58 | setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
| 53 | 59 | }
|
| 54 | 60 | |
| ... | ... | @@ -84,29 +90,35 @@ public class NavigationTreeSelectionModel extends DefaultTreeSelectionModel { |
| 84 | 90 | return;
|
| 85 | 91 | }
|
| 86 | 92 | TreePath path = pPaths[0];
|
| 87 | - boolean[] newness = new boolean[pPaths.length];
|
|
| 88 | - Arrays.fill(newness, true);
|
|
| 89 | - NavigationTreeSelectionEvent event = new NavigationTreeSelectionEvent(this, pPaths, newness, getLeadSelectionPath(), path, skipCheckPreviousContent);
|
|
| 90 | 93 | boolean canChange = !Objects.equals(path, getSelectionPath());
|
| 91 | 94 | if (canChange) {
|
| 95 | + boolean[] newness = new boolean[pPaths.length];
|
|
| 96 | + Arrays.fill(newness, true);
|
|
| 97 | + NavigationTreeSelectionEvent event = new NavigationTreeSelectionEvent(this, pPaths, newness, getLeadSelectionPath(), path, skipCheckPreviousContent);
|
|
| 92 | 98 | try {
|
| 93 | 99 | fireVetoValueChanged(event);
|
| 94 | 100 | } catch (NavigationTreeSelectionVetoException e) {
|
| 95 | 101 | canChange = false;
|
| 96 | 102 | }
|
| 97 | 103 | }
|
| 98 | - |
|
| 99 | -// boolean canChange = skipCheckPreviousContent || (!Objects.equals(path, getSelectionPath()) && contentUIManager.closeSelectedContentUI());
|
|
| 100 | 104 | if (!canChange) {
|
| 101 | 105 | // cancel the change of node
|
| 102 | 106 | log.warn(String.format("Do not change selection path: %s against: %s", path, getSelectionPath()));
|
| 103 | 107 | return;
|
| 104 | 108 | }
|
| 105 | -// FIXME Move this in a listener
|
|
| 106 | -// if (skipCheckPreviousContent) {
|
|
| 107 | -// contentUIManager.closeSafeSelectedContentUI();
|
|
| 108 | -// }
|
|
| 109 | - super.setSelectionPaths(pPaths);
|
|
| 109 | + // can now safely select new path
|
|
| 110 | + if (busyModel == null || skipBusyModel) {
|
|
| 111 | + super.setSelectionPaths(pPaths);
|
|
| 112 | + } else {
|
|
| 113 | + busyModel.addTask(I18n.t("observe.ui.tree.loading.node"));
|
|
| 114 | + SwingUtilities.invokeLater(() -> {
|
|
| 115 | + try {
|
|
| 116 | + super.setSelectionPaths(pPaths);
|
|
| 117 | + } finally {
|
|
| 118 | + busyModel.popTask();
|
|
| 119 | + }
|
|
| 120 | + });
|
|
| 121 | + }
|
|
| 110 | 122 | }
|
| 111 | 123 | |
| 112 | 124 | @Override
|
| ... | ... | @@ -135,4 +147,12 @@ public class NavigationTreeSelectionModel extends DefaultTreeSelectionModel { |
| 135 | 147 | public void setSkipCheckPreviousContent(boolean skipCheckPreviousContent) {
|
| 136 | 148 | this.skipCheckPreviousContent = skipCheckPreviousContent;
|
| 137 | 149 | }
|
| 150 | + |
|
| 151 | + public boolean isSkipBusyModel() {
|
|
| 152 | + return skipBusyModel;
|
|
| 153 | + }
|
|
| 154 | + |
|
| 155 | + public void setSkipBusyModel(boolean skipBusyModel) {
|
|
| 156 | + this.skipBusyModel = skipBusyModel;
|
|
| 157 | + }
|
|
| 138 | 158 | } |
| ... | ... | @@ -54,7 +54,7 @@ public class NavigationTreeSupport<R extends NavigationTreeNode, M extends Navig |
| 54 | 54 | |
| 55 | 55 | @Override
|
| 56 | 56 | public void updateUI() {
|
| 57 | - setSelectionModel(new NavigationTreeSelectionModel());
|
|
| 57 | + setSelectionModel(new NavigationTreeSelectionModel(null));
|
|
| 58 | 58 | super.updateUI();
|
| 59 | 59 | }
|
| 60 | 60 |
| 1 | -package fr.ird.observe.client.util.busy;
|
|
| 1 | +package fr.ird.observe.spi.ui;
|
|
| 2 | 2 | |
| 3 | 3 | /*-
|
| 4 | 4 | * #%L
|
| 5 | - * ObServe Client :: Core
|
|
| 5 | + * ObServe Toolkit :: API
|
|
| 6 | 6 | * %%
|
| 7 | 7 | * Copyright (C) 2008 - 2022 IRD, Ultreia.io
|
| 8 | 8 | * %%
|
| ... | ... | @@ -22,10 +22,6 @@ package fr.ird.observe.client.util.busy; |
| 22 | 22 | * #L%
|
| 23 | 23 | */
|
| 24 | 24 | |
| 25 | -import org.apache.logging.log4j.LogManager;
|
|
| 26 | -import org.apache.logging.log4j.Logger;
|
|
| 27 | -import io.ultreia.java4all.util.TimeLog;
|
|
| 28 | - |
|
| 29 | 25 | import javax.swing.JComponent;
|
| 30 | 26 | import javax.swing.JLayer;
|
| 31 | 27 | import javax.swing.RootPaneContainer;
|
| ... | ... | @@ -40,6 +36,7 @@ import java.awt.Cursor; |
| 40 | 36 | import java.awt.Graphics;
|
| 41 | 37 | import java.awt.Graphics2D;
|
| 42 | 38 | import java.awt.event.InputEvent;
|
| 39 | +import java.beans.PropertyChangeEvent;
|
|
| 43 | 40 | import java.beans.PropertyChangeListener;
|
| 44 | 41 | import java.io.Closeable;
|
| 45 | 42 | import java.util.Objects;
|
| ... | ... | @@ -48,18 +45,13 @@ import java.util.Objects; |
| 48 | 45 | * @author Tony Chemit - dev@tchemit.fr
|
| 49 | 46 | * @since 8.0.0
|
| 50 | 47 | */
|
| 51 | -public class BusyLayerUI<U extends Component> extends LayerUI<U> implements Closeable {
|
|
| 52 | - |
|
| 53 | - private static final Logger log = LogManager.getLogger(BusyLayerUI.class);
|
|
| 54 | - private static final TimeLog timeLog = new TimeLog(BusyLayerUI.class, 0, 1000);
|
|
| 48 | +public class BusyLayerUI<U extends Component> extends LayerUI<U> implements Closeable, PropertyChangeListener {
|
|
| 55 | 49 | |
| 56 | 50 | private final RootPaneContainer rootPanecontainer;
|
| 57 | 51 | private final Container container;
|
| 58 | 52 | private final BusyModel model;
|
| 59 | 53 | private final Color busyColor;
|
| 60 | - private final PropertyChangeListener listener;
|
|
| 61 | 54 | private transient Color color;
|
| 62 | - private long blockingTime;
|
|
| 63 | 55 | |
| 64 | 56 | public static void create(RootPaneContainer container, BusyModel busyModel) {
|
| 65 | 57 | Container contentPane = container.getRootPane().getContentPane();
|
| ... | ... | @@ -81,8 +73,7 @@ public class BusyLayerUI<U extends Component> extends LayerUI<U> implements Clos |
| 81 | 73 | this.container = Objects.requireNonNull(rootPanecontainer.getRootPane());
|
| 82 | 74 | this.model = Objects.requireNonNull(model);
|
| 83 | 75 | this.busyColor = UIManager.getColor("BlockingLayerUI.busyColor");
|
| 84 | - this.listener = evt -> onBusyStateChanged((boolean) evt.getOldValue(), (boolean) evt.getNewValue());
|
|
| 85 | - this.model.addPropertyChangeListener(BusyModel.BUSY_PROPERTY_NAME, listener);
|
|
| 76 | + this.model.addPropertyChangeListener(BusyModel.BUSY_PROPERTY_NAME, this);
|
|
| 86 | 77 | }
|
| 87 | 78 | |
| 88 | 79 | @Override
|
| ... | ... | @@ -125,32 +116,32 @@ public class BusyLayerUI<U extends Component> extends LayerUI<U> implements Clos |
| 125 | 116 | |
| 126 | 117 | @Override
|
| 127 | 118 | public void close() {
|
| 128 | - this.model.removePropertyChangeListener(BusyModel.BUSY_PROPERTY_NAME, listener);
|
|
| 119 | + model.removePropertyChangeListener(BusyModel.BUSY_PROPERTY_NAME, this);
|
|
| 129 | 120 | }
|
| 130 | 121 | |
| 131 | 122 | public Container getContainer() {
|
| 132 | 123 | return container;
|
| 133 | 124 | }
|
| 134 | 125 | |
| 135 | - public void onBusyStateChanged(boolean wasBusy, boolean isBusy) {
|
|
| 136 | - if (wasBusy == isBusy) {
|
|
| 137 | - return;
|
|
| 138 | - }
|
|
| 139 | - |
|
| 140 | - color = isBusy ? busyColor : null;
|
|
| 141 | - if (isBusy) {
|
|
| 142 | - blockingTime = TimeLog.getTime();
|
|
| 143 | - log.debug("Blocking ui at " + blockingTime);
|
|
| 144 | - container.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
|
| 145 | - } else {
|
|
| 146 | - timeLog.log(blockingTime, "unblock");
|
|
| 147 | - container.setCursor(Cursor.getDefaultCursor());
|
|
| 148 | - }
|
|
| 149 | - rootPanecontainer.getRootPane().repaint();
|
|
| 150 | - }
|
|
| 151 | - |
|
| 152 | 126 | public boolean isBusy() {
|
| 153 | 127 | return color != null;
|
| 154 | 128 | }
|
| 155 | 129 | |
| 130 | + @Override
|
|
| 131 | + public void propertyChange(PropertyChangeEvent evt) {
|
|
| 132 | + if (BusyModel.BUSY_PROPERTY_NAME.equals(evt.getPropertyName())) {
|
|
| 133 | + boolean wasBusy = (boolean) evt.getOldValue();
|
|
| 134 | + boolean isBusy = (boolean) evt.getNewValue();
|
|
| 135 | + if (wasBusy == isBusy) {
|
|
| 136 | + return;
|
|
| 137 | + }
|
|
| 138 | + color = isBusy ? busyColor : null;
|
|
| 139 | + if (isBusy) {
|
|
| 140 | + container.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
|
| 141 | + } else {
|
|
| 142 | + container.setCursor(Cursor.getDefaultCursor());
|
|
| 143 | + }
|
|
| 144 | + rootPanecontainer.getRootPane().repaint();
|
|
| 145 | + }
|
|
| 146 | + }
|
|
| 156 | 147 | } |
| 1 | -package fr.ird.observe.client.util.busy;
|
|
| 1 | +package fr.ird.observe.spi.ui;
|
|
| 2 | 2 | |
| 3 | 3 | /*-
|
| 4 | 4 | * #%L
|
| 5 | - * ObServe Client :: Core
|
|
| 5 | + * ObServe Toolkit :: API
|
|
| 6 | 6 | * %%
|
| 7 | 7 | * Copyright (C) 2008 - 2022 IRD, Ultreia.io
|
| 8 | 8 | * %%
|
| ... | ... | @@ -24,6 +24,9 @@ package fr.ird.observe.client.util.busy; |
| 24 | 24 | |
| 25 | 25 | import io.ultreia.java4all.bean.AbstractJavaBean;
|
| 26 | 26 | import io.ultreia.java4all.bean.spi.GenerateJavaBeanDefinition;
|
| 27 | +import io.ultreia.java4all.i18n.I18n;
|
|
| 28 | +import io.ultreia.java4all.lang.Strings;
|
|
| 29 | +import io.ultreia.java4all.util.TimeLog;
|
|
| 27 | 30 | import org.apache.logging.log4j.LogManager;
|
| 28 | 31 | import org.apache.logging.log4j.Logger;
|
| 29 | 32 | |
| ... | ... | @@ -36,36 +39,76 @@ import java.util.Deque; |
| 36 | 39 | */
|
| 37 | 40 | @GenerateJavaBeanDefinition
|
| 38 | 41 | public class BusyModel extends AbstractJavaBean {
|
| 39 | - |
|
| 42 | + private static final TimeLog timeLog = new TimeLog(BusyModel.class, 500, 1000);
|
|
| 40 | 43 | private static final Logger log = LogManager.getLogger(BusyModel.class);
|
| 41 | 44 | |
| 45 | + static class BusyTask {
|
|
| 46 | + private final String taskName;
|
|
| 47 | + private final int rank;
|
|
| 48 | + private final long startTime;
|
|
| 49 | + |
|
| 50 | + BusyTask(String taskName, int rank) {
|
|
| 51 | + this.taskName = taskName;
|
|
| 52 | + this.rank = rank;
|
|
| 53 | + this.startTime = TimeLog.getTime();
|
|
| 54 | + }
|
|
| 55 | + |
|
| 56 | + public int getRank() {
|
|
| 57 | + return rank;
|
|
| 58 | + }
|
|
| 59 | + |
|
| 60 | + public String getTaskName() {
|
|
| 61 | + return taskName;
|
|
| 62 | + }
|
|
| 63 | + |
|
| 64 | + public long getStartTime() {
|
|
| 65 | + return startTime;
|
|
| 66 | + }
|
|
| 67 | + |
|
| 68 | + }
|
|
| 69 | + |
|
| 42 | 70 | public static final String BUSY_PROPERTY_NAME = "busy";
|
| 43 | - private final Deque<String> tasks;
|
|
| 71 | + private final Deque<BusyTask> tasks;
|
|
| 44 | 72 | |
| 45 | 73 | public BusyModel() {
|
| 46 | 74 | tasks = new ArrayDeque<>();
|
| 47 | 75 | }
|
| 48 | 76 | |
| 49 | - public synchronized void addTask(String task) {
|
|
| 50 | - log.debug("Add task: " + task);
|
|
| 77 | + public synchronized void addTask(String taskName) {
|
|
| 51 | 78 | boolean oldValue = isBusy();
|
| 79 | + BusyTask task = new BusyTask(taskName, tasks.size() + 1);
|
|
| 80 | + log.info(I18n.t("observe.ui.busy.start.task", task.getRank(), taskName));
|
|
| 52 | 81 | tasks.add(task);
|
| 53 | - fireBusyStateChanged(oldValue);
|
|
| 82 | + fireBusyStateChanged(oldValue, task, null);
|
|
| 54 | 83 | }
|
| 55 | 84 | |
| 56 | 85 | public synchronized void popTask() {
|
| 57 | 86 | boolean oldValue = isBusy();
|
| 58 | - String task = tasks.removeLast();
|
|
| 59 | - log.debug("Remove task: " + task);
|
|
| 60 | - fireBusyStateChanged(oldValue);
|
|
| 87 | + BusyTask task = tasks.removeLast();
|
|
| 88 | + String taskName = task.getTaskName();
|
|
| 89 | + long startTime = task.getStartTime();
|
|
| 90 | + String delay = Strings.convertTime(TimeLog.getTime() - startTime);
|
|
| 91 | + log.info(I18n.t("observe.ui.busy.end.task", task.getRank(), delay, taskName));
|
|
| 92 | + timeLog.log(startTime, "task done", taskName);
|
|
| 93 | + fireBusyStateChanged(oldValue, task, delay);
|
|
| 61 | 94 | }
|
| 62 | 95 | |
| 63 | 96 | public boolean isBusy() {
|
| 64 | 97 | return !tasks.isEmpty();
|
| 65 | 98 | }
|
| 66 | 99 | |
| 67 | - void fireBusyStateChanged(boolean oldValue) {
|
|
| 100 | + void fireBusyStateChanged(boolean oldValue, BusyTask task, String delay) {
|
|
| 68 | 101 | boolean busy = isBusy();
|
| 69 | - firePropertyChange(BUSY_PROPERTY_NAME, oldValue, busy);
|
|
| 102 | + if (oldValue != busy) {
|
|
| 103 | + String taskName = task.getTaskName();
|
|
| 104 | + if (busy) {
|
|
| 105 | + log.info(I18n.t("observe.ui.busy.start.block", taskName));
|
|
| 106 | + } else {
|
|
| 107 | + long startTime = task.getStartTime();
|
|
| 108 | + log.info(I18n.t("observe.ui.busy.end.block", delay, taskName));
|
|
| 109 | + timeLog.log(startTime, "unblock", taskName);
|
|
| 110 | + }
|
|
| 111 | + firePropertyChange(BUSY_PROPERTY_NAME, oldValue, busy);
|
|
| 112 | + }
|
|
| 70 | 113 | }
|
| 71 | 114 | } |