MoneyWiseStaticPanel.java
/*
* MoneyWise: Finance Application
* Copyright 2012-2026. Tony Washer
*
* Licensed 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 io.github.tonywasher.joceanus.moneywise.ui.panel;
import io.github.tonywasher.joceanus.oceanus.base.OceanusException;
import io.github.tonywasher.joceanus.oceanus.event.OceanusEvent;
import io.github.tonywasher.joceanus.oceanus.event.OceanusEventManager;
import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar;
import io.github.tonywasher.joceanus.oceanus.event.OceanusEventRegistrar.OceanusEventProvider;
import io.github.tonywasher.joceanus.oceanus.profile.OceanusProfile;
import io.github.tonywasher.joceanus.metis.ui.MetisErrorPanel;
import io.github.tonywasher.joceanus.metis.viewer.MetisViewerEntry;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseAccountInfoType.MoneyWiseAccountInfoTypeList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCashCategoryType.MoneyWiseCashCategoryTypeList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseCurrency.MoneyWiseCurrencyList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseDepositCategoryType.MoneyWiseDepositCategoryTypeList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseLoanCategoryType.MoneyWiseLoanCategoryTypeList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWisePayeeType.MoneyWisePayeeTypeList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWisePortfolioType.MoneyWisePortfolioTypeList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseSecurityType.MoneyWiseSecurityTypeList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseStaticDataType;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTaxBasis.MoneyWiseTaxBasisList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTransCategoryType.MoneyWiseTransCategoryTypeList;
import io.github.tonywasher.joceanus.moneywise.data.statics.MoneyWiseTransInfoType.MoneyWiseTransInfoTypeList;
import io.github.tonywasher.joceanus.moneywise.ui.MoneyWiseUIResource;
import io.github.tonywasher.joceanus.moneywise.views.MoneyWiseView;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusStaticDataItem;
import io.github.tonywasher.joceanus.prometheus.data.PrometheusStaticDataItem.PrometheusStaticList;
import io.github.tonywasher.joceanus.prometheus.ui.PrometheusActionButtons;
import io.github.tonywasher.joceanus.prometheus.views.PrometheusDataEvent;
import io.github.tonywasher.joceanus.prometheus.views.PrometheusEditSet;
import io.github.tonywasher.joceanus.prometheus.views.PrometheusUIEvent;
import io.github.tonywasher.joceanus.prometheus.views.PrometheusViewerEntryId;
import io.github.tonywasher.joceanus.tethys.api.base.TethysUIComponent;
import io.github.tonywasher.joceanus.tethys.api.base.TethysUIEvent;
import io.github.tonywasher.joceanus.tethys.api.base.TethysUIGenericWrapper;
import io.github.tonywasher.joceanus.tethys.api.button.TethysUIScrollButtonManager;
import io.github.tonywasher.joceanus.tethys.api.control.TethysUICheckBox;
import io.github.tonywasher.joceanus.tethys.api.control.TethysUIControlFactory;
import io.github.tonywasher.joceanus.tethys.api.control.TethysUILabel;
import io.github.tonywasher.joceanus.tethys.api.factory.TethysUIFactory;
import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollItem;
import io.github.tonywasher.joceanus.tethys.api.menu.TethysUIScrollMenu;
import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIBorderPaneManager;
import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIBoxPaneManager;
import io.github.tonywasher.joceanus.tethys.api.pane.TethysUICardPaneManager;
import io.github.tonywasher.joceanus.tethys.api.pane.TethysUIPaneFactory;
import java.util.ArrayList;
import java.util.List;
/**
* MoneyWise Static Panel.
*/
public class MoneyWiseStaticPanel
implements OceanusEventProvider<PrometheusDataEvent>, TethysUIComponent {
/**
* The view.
*/
private final MoneyWiseView theView;
/**
* The Event Manager.
*/
private final OceanusEventManager<PrometheusDataEvent> theEventManager;
/**
* The UpdateSet associated with the panel.
*/
private final PrometheusEditSet theEditSet;
/**
* The ViewerEntry.
*/
private final MetisViewerEntry theViewerEntry;
/**
* The Panel.
*/
private final TethysUIBorderPaneManager thePanel;
/**
* The error panel.
*/
private final MetisErrorPanel theError;
/**
* The action buttons panel.
*/
private final PrometheusActionButtons theActionButtons;
/**
* The disabled check box.
*/
private final TethysUICheckBox theDisabledCheckBox;
/**
* The Selection Panel.
*/
private final TethysUIBorderPaneManager theSelectionPanel;
/**
* The select button.
*/
private final TethysUIScrollButtonManager<TethysUIGenericWrapper> theSelectButton;
/**
* Data menu builder.
*/
private final TethysUIScrollMenu<TethysUIGenericWrapper> theDataMenu;
/**
* The table card panel.
*/
private final TethysUICardPaneManager<MoneyWiseStaticTable<?, ?>> theTableCard;
/**
* The new card panel.
*/
private final TethysUICardPaneManager<TethysUIScrollButtonManager<?>> theNewCard;
/**
* The list of panels.
*/
private final List<MoneyWiseStaticTable<?, ?>> thePanels;
/**
* Constructor.
*
* @param pView the view
*/
MoneyWiseStaticPanel(final MoneyWiseView pView) {
/* Store parameters */
theView = pView;
/* Create the event manager */
theEventManager = new OceanusEventManager<>();
/* Build the Update set */
theEditSet = new PrometheusEditSet(theView);
/* Create the top level viewer entry for this view */
theViewerEntry = pView.getViewerEntry(PrometheusViewerEntryId.STATIC);
theViewerEntry.setTreeObject(theEditSet);
/* Create the error panel */
theError = pView.getToolkit().getToolkit().newErrorPanel(theViewerEntry);
theError.getEventRegistrar().addEventListener(e -> handleErrorPanel());
/* Create the list of panels */
thePanels = new ArrayList<>();
/* Access the Gui Factory */
final TethysUIFactory<?> myGuiFactory = pView.getGuiFactory();
/* Create the action buttons panel */
theActionButtons = new PrometheusActionButtons(myGuiFactory, theEditSet);
theActionButtons.getEventRegistrar().addEventListener(this::handleActionButtons);
/* Create the CheckBox */
final TethysUIControlFactory myControls = myGuiFactory.controlFactory();
theDisabledCheckBox = myControls.newCheckBox(MoneyWiseUIResource.STATICDATA_DISABLED.getValue());
theDisabledCheckBox.getEventRegistrar().addEventListener(e -> showDisabled(theDisabledCheckBox.isSelected()));
/* Create the select button */
final TethysUILabel myLabel = myControls.newLabel(MoneyWiseUIResource.STATICDATA_SELECT.getValue());
theSelectButton = myGuiFactory.buttonFactory().newScrollButton(TethysUIGenericWrapper.class);
theDataMenu = theSelectButton.getMenu();
theSelectButton.setMenuConfigurator(e -> buildDataMenu());
final OceanusEventRegistrar<TethysUIEvent> myRegistrar = theSelectButton.getEventRegistrar();
myRegistrar.addEventListener(TethysUIEvent.NEWVALUE, e -> handlePanelSelection());
/* Create the selection panel */
final TethysUIPaneFactory myPanes = myGuiFactory.paneFactory();
theSelectionPanel = myPanes.newBorderPane();
theSelectionPanel.setBorderTitle(MoneyWiseUIResource.STATICDATA_SELECTION.getValue());
/* Create the new card panel */
theNewCard = myPanes.newCardPane();
theNewCard.setVisible(false);
/* Create the layout for the selection panel */
final TethysUIBoxPaneManager mySubPanel = myPanes.newHBoxPane();
mySubPanel.addNode(myLabel);
mySubPanel.addNode(theSelectButton);
mySubPanel.addSpacer();
mySubPanel.addNode(theDisabledCheckBox);
mySubPanel.addSpacer();
theSelectionPanel.setCentre(mySubPanel);
theSelectionPanel.setEast(theNewCard);
/* Create the header panel */
final TethysUIBorderPaneManager myHeader = myPanes.newBorderPane();
myHeader.setCentre(theSelectionPanel);
myHeader.setNorth(theError);
myHeader.setEast(theActionButtons);
/* Create the table card panel */
theTableCard = myPanes.newCardPane();
/* Create the Panel */
thePanel = myPanes.newBorderPane();
/* Now define the panel */
thePanel.setNorth(myHeader);
thePanel.setCentre(theTableCard);
/* Hide the action buttons initially */
theActionButtons.setVisible(false);
/* Add the static data */
addStatic(MoneyWiseStaticDataType.DEPOSITTYPE, MoneyWiseDepositCategoryTypeList.class);
addStatic(MoneyWiseStaticDataType.CASHTYPE, MoneyWiseCashCategoryTypeList.class);
addStatic(MoneyWiseStaticDataType.LOANTYPE, MoneyWiseLoanCategoryTypeList.class);
addStatic(MoneyWiseStaticDataType.PAYEETYPE, MoneyWisePayeeTypeList.class);
addStatic(MoneyWiseStaticDataType.PORTFOLIOTYPE, MoneyWisePortfolioTypeList.class);
addStatic(MoneyWiseStaticDataType.SECURITYTYPE, MoneyWiseSecurityTypeList.class);
addStatic(MoneyWiseStaticDataType.TRANSTYPE, MoneyWiseTransCategoryTypeList.class);
addStatic(MoneyWiseStaticDataType.CURRENCY, MoneyWiseCurrencyList.class);
addStatic(MoneyWiseStaticDataType.TAXBASIS, MoneyWiseTaxBasisList.class);
addStatic(MoneyWiseStaticDataType.ACCOUNTINFOTYPE, MoneyWiseAccountInfoTypeList.class);
addStatic(MoneyWiseStaticDataType.TRANSINFOTYPE, MoneyWiseTransInfoTypeList.class);
}
@Override
public TethysUIComponent getUnderlying() {
return thePanel;
}
@Override
public OceanusEventRegistrar<PrometheusDataEvent> getEventRegistrar() {
return theEventManager.getEventRegistrar();
}
/**
* Has this set of tables got updates?
*
* @return true/false
*/
public boolean hasUpdates() {
/* Return to caller */
return theEditSet.hasUpdates();
}
/**
* Has this set of panels got the session focus?
*
* @return true/false
*/
public boolean hasSession() {
/* Return to caller */
return hasUpdates() || isEditing();
}
/**
* Has this set of tables got errors?
*
* @return true/false
*/
public boolean hasErrors() {
/* Return to caller */
return theEditSet.hasErrors();
}
/**
* Refresh views/controls after a load/update of underlying data.
*
* @throws OceanusException on error
*/
public void refreshData() throws OceanusException {
/* Obtain the active profile */
OceanusProfile myTask = theView.getActiveTask();
myTask = myTask.startTask("StaticData");
theEditSet.setDataSet(theView.getData());
/* Loop through the panels */
for (MoneyWiseStaticTable<?, ?> myPanel : thePanels) {
/* Note the stage */
myTask.startTask(myPanel.getItemType().getItemName());
/* Refresh the panel */
myPanel.refreshData();
}
/* Touch the updateSet */
theViewerEntry.setTreeObject(theEditSet);
/* Complete the task */
myTask.end();
}
/**
* Build StaticData menu.
*/
private void buildDataMenu() {
/* Cancel any editing */
cancelEditing();
/* Reset the popUp menu */
theDataMenu.removeAllItems();
/* Record active item */
TethysUIScrollItem<TethysUIGenericWrapper> myActive = null;
final String myActiveName = theTableCard.getActiveName();
/* Loop through the panels */
for (MoneyWiseStaticTable<?, ?> myTable : thePanels) {
/* Create a new MenuItem and add it to the popUp */
final String myName = myTable.getItemType().getItemName();
final TethysUIScrollItem<TethysUIGenericWrapper> myItem = theDataMenu.addItem(new TethysUIGenericWrapper(myTable), myName);
/* If this is the active panel */
if (myName.equals(myActiveName)) {
/* Record it */
myActive = myItem;
}
}
/* Ensure active item is visible */
if (myActive != null) {
myActive.scrollToItem();
}
}
/**
* Add static panel.
*
* @param pItemType the type of the list
* @param pListClass the class of the list
* @param <L> the list type
* @param <T> the data type
*/
private <L extends PrometheusStaticList<T>, T extends PrometheusStaticDataItem> void addStatic(final MoneyWiseStaticDataType pItemType,
final Class<L> pListClass) {
/* Create the new panel */
final MoneyWiseStaticTable<L, T> myPanel = new MoneyWiseStaticTable<>(theView, theEditSet, theError, pItemType, pListClass);
/* Add the listener for the panel */
myPanel.getEventRegistrar().addEventListener(e -> setVisibility());
/* Access list name */
final String myName = pItemType.getListName();
/* Add to the card panels */
theTableCard.addCard(myName, myPanel);
theNewCard.addCard(myName, myPanel.getNewButton());
/* Make sure that the active set is displayed */
theSelectButton.setValue(new TethysUIGenericWrapper(theTableCard.getActiveCard()), theTableCard.getActiveName());
/* Add to the List */
thePanels.add(myPanel);
}
/**
* Select static data.
*
* @param pStatic the static data to select
*/
public void selectStatic(final PrometheusStaticDataItem pStatic) {
/* Access the item type */
final MoneyWiseStaticDataType myType = (MoneyWiseStaticDataType) pStatic.getItemType();
final String myName = myType.getFieldName();
/* Access the panel */
if (theTableCard.selectCard(myName)) {
/* Update selection */
final MoneyWiseStaticTable<?, ?> myPanel = theTableCard.getActiveCard();
theSelectButton.setValue(new TethysUIGenericWrapper(myPanel), myName);
myPanel.selectStatic(pStatic);
setSelection(myName);
}
}
/**
* Set Selection.
*
* @param pName the name that is selected
*/
private void setSelection(final String pName) {
/* Select the correct static */
theTableCard.selectCard(pName);
theNewCard.selectCard(pName);
determineFocus();
}
/**
* Determine Focus.
*/
public void determineFocus() {
/* Request the focus */
final MoneyWiseStaticTable<?, ?> myPanel = theTableCard.getActiveCard();
if (myPanel != null) {
myPanel.determineFocus(theViewerEntry);
}
}
/**
* Show New button.
*/
private void showNewButton() {
/* Set visibility of New Button */
final MoneyWiseStaticTable<?, ?> myPanel = (MoneyWiseStaticTable<?, ?>) theSelectButton.getValue().getData();
final boolean showNew = myPanel != null
&& !myPanel.isFull();
theNewCard.setVisible(showNew);
}
/**
* Set Visibility.
*/
protected void setVisibility() {
/* Determine whether we have updates */
final boolean hasUpdates = hasUpdates();
/* Update the action buttons */
theActionButtons.setEnabled(true);
theActionButtons.setVisible(hasUpdates);
/* Set visibility of New Button */
showNewButton();
/* Alert listeners that there has been a change */
theEventManager.fireEvent(PrometheusDataEvent.ADJUSTVISIBILITY);
}
/**
* Handle error panel.
*/
private void handleErrorPanel() {
/* Determine whether we have an error */
final boolean isError = theError.hasError();
/* Hide selection panel on error */
theSelectionPanel.setVisible(!isError);
/* Lock scroll-able area */
theTableCard.setEnabled(!isError);
/* Lock Action Buttons */
theActionButtons.setEnabled(!isError);
}
/**
* Handle action buttons.
*
* @param pEvent the event
*/
private void handleActionButtons(final OceanusEvent<PrometheusUIEvent> pEvent) {
/* Cancel Editing */
cancelEditing();
/* Process the command */
theEditSet.processCommand(pEvent.getEventId(), theError);
/* Adjust visibility */
setVisibility();
}
/**
* Handle panel selection.
*/
private void handlePanelSelection() {
final MoneyWiseStaticTable<?, ?> myPanel = (MoneyWiseStaticTable<?, ?>) theSelectButton.getValue().getData();
final String myName = myPanel.getItemType().getListName();
theTableCard.selectCard(myName);
theNewCard.selectCard(myName);
myPanel.determineFocus(theViewerEntry);
showNewButton();
}
/**
* Show disabled.
*
* @param pShow true/false
*/
public void showDisabled(final boolean pShow) {
/* Loop through the panels */
for (MoneyWiseStaticTable<?, ?> myPanel : thePanels) {
myPanel.setShowAll(pShow);
}
}
/**
* Cancel Editing of underlying tables.
*/
private void cancelEditing() {
/* Loop through the panels */
for (MoneyWiseStaticTable<?, ?> myPanel : thePanels) {
myPanel.cancelEditing();
}
}
/**
* is the current table editing?
*
* @return true/false
*/
private boolean isEditing() {
final MoneyWiseStaticTable<?, ?> myPanel = (MoneyWiseStaticTable<?, ?>) theSelectButton.getValue().getData();
return myPanel.isEditing();
}
}