/*********************************************************************** * Copyright - Secretariat of the Pacific Community * * Droit de copie - Secrétariat Général de la Communauté du Pacifique * * http://www.spc.int/ * ***********************************************************************/ package org.spc.ofp.project.mfcl.viewer; import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.builders.ProgressIndicatorBuilder; import javafx.builders.ScrollPaneBuilder; import javafx.builders.TabBuilder; import javafx.builders.TabPaneBuilder; import javafx.builders.VBoxBuilder; import javafx.scene.chart.Chart; import javafx.scene.control.ProgressIndicator; import javafx.scene.control.ScrollPane; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.layout.BorderPane; import javafx.scene.layout.VBox; import org.spc.ofp.java.i18n.I18NBase; import org.spc.ofp.java.lang.__DIR__; import org.spc.ofp.project.mfcl.io.rep.Rep; import org.spc.ofp.project.mfcl.chart.helper.AgeSelectivityHelper; import org.spc.ofp.project.mfcl.chart.helper.CatchHelper; import org.spc.ofp.project.mfcl.chart.helper.ChartIterator; import org.spc.ofp.project.mfcl.chart.helper.GrowthHelper; import org.spc.ofp.project.mfcl.chart.helper.MSYHelper; import org.spc.ofp.project.mfcl.chart.helper.MovementInformationHelper; import org.spc.ofp.project.mfcl.chart.helper.NaturalMortalityHelper; import org.spc.ofp.project.mfcl.chart.helper.PlotRepHelperBase; import org.spc.ofp.project.mfcl.chart.helper.StockRecruitmentHelper; import org.spc.ofp.project.mfcl.chart.helper.TagReportingHelper; import org.spc.ofp.project.mfcl.chart.helper.TagReturnsHelper; import org.spc.ofp.project.mfcl.chart.helper.YieldHelper; /** * This class display the content of a plot.rep file. * @author Fabrice Bouyé (fabriceb@spc.int) */ class PlotRepPane extends BorderPane { private static final __DIR__ __DIR__ = new __DIR__(PlotRepPane.class); private static final I18NBase I18N = new I18NBase(PlotRepPane.class); private TabPane tabPane; /** * Map: fishery index -> fishery name. */ private Map fisheryMap = new HashMap<>(); private Map helperMap = new HashMap<>(); /** * Creates a new instance. * @param plotRep The plot.rep file. * @param fisheryNames The display fisheryName for each fishery. */ public PlotRepPane(Rep plotRep, String... fisheryNames) { int fisheryNumber = plotRep.getFisheryCount(); // Generate missing fishery names. for (int fisheryIndex = 0; fisheryIndex < fisheryNumber; fisheryIndex++) { String fisheryName = (fisheryIndex < fisheryNames.length) ? fisheryNames[fisheryIndex] : null; if (fisheryName == null || fisheryName.trim().isEmpty()) { fisheryName = MessageFormat.format(I18N.getString("FISHERY_NUMBER_LABEL"), fisheryIndex + 1); // NOI18N. fisheryMap.put(fisheryIndex, fisheryName); } } // Setup tabs. final Tab movementTab = TabBuilder.create().text(I18N.getString("MOVEMENT_TAB")).closable(false).build(); // NOI18N. helperMap.put(movementTab, new MovementInformationHelper(plotRep, fisheryMap)); Tab tagReturnsTab = TabBuilder.create().text(I18N.getString("TAG_RETURNS_TAB")).closable(false).build(); // NOI18N. helperMap.put(tagReturnsTab, new TagReturnsHelper(plotRep, fisheryMap)); Tab tagReportingTab = TabBuilder.create().text(I18N.getString("TAG_REPORTING_TAB")).closable(false).build(); // NOI18N. helperMap.put(tagReportingTab, new TagReportingHelper(plotRep, fisheryMap)); Tab catchTab = TabBuilder.create().text(I18N.getString("CATCH_TAB")).closable(false).build(); // NOI18N. helperMap.put(catchTab, new CatchHelper(plotRep, fisheryMap)); Tab biomassTab = TabBuilder.create().text(I18N.getString("BIOMASS_TAB")).closable(false).build(); // NOI18N. Tab exploitableBiomassTab = TabBuilder.create().text(I18N.getString("EXPLOITABLE_BIOMASS_TAB")).closable(false).build(); // NOI18N. Tab exploitablePopVSObservedCPUETab = TabBuilder.create().text(I18N.getString("EXPLOITABLE_POPULATION_VS_OBSERVED_CPUE_TAB")).closable(false).build(); // NOI18N. Tab initialPopulationTab = TabBuilder.create().text(I18N.getString("INITIAL_POPULATION_TAB")).closable(false).build(); // NOI18N. Tab recruitmentTab = TabBuilder.create().text(I18N.getString("RECRUITMENT_TAB")).closable(false).build(); // NOI18N. Tab fishingMortalityTab = TabBuilder.create().text(I18N.getString("FISHING_MORTALITY_TAB")).closable(false).build(); // NOI18N. Tab catchabilityTab = TabBuilder.create().text(I18N.getString("CATCHABILITY_TAB")).closable(false).build(); // NOI18N. Tab effortDevsTab = TabBuilder.create().text(I18N.getString("EFFORT_DEVS_TAB")).closable(false).build(); // NOI18N. Tab ageSelectivityTab = TabBuilder.create().text(I18N.getString("AGE_SELECTIVITY_TAB")).closable(false).build(); // NOI18N. helperMap.put(ageSelectivityTab, new AgeSelectivityHelper(plotRep, fisheryMap)); Tab lengthSelectivityTab = TabBuilder.create().text(I18N.getString("LENGTH_SELECTIVITY_TAB")).closable(false).build(); // NOI18N. Tab naturalMortalityTab = TabBuilder.create().text(I18N.getString("NATURAL_MORTALITY_TAB")).closable(false).build(); // NOI18N. helperMap.put(naturalMortalityTab, new NaturalMortalityHelper(plotRep, fisheryMap)); Tab growthTab = TabBuilder.create().text(I18N.getString("GROWTH_TAB")).closable(false).build(); // NOI18N. helperMap.put(growthTab, new GrowthHelper(plotRep, fisheryMap)); Tab stockRecruitmentTab = TabBuilder.create().text(I18N.getString("STOCK_RECRUITMENT_TAB")).closable(false).build(); // NOI18N. helperMap.put(stockRecruitmentTab, new StockRecruitmentHelper(plotRep, fisheryMap)); Tab yieldTab = TabBuilder.create().text(I18N.getString("YIELD_TAB")).closable(false).build(); // NOI18N. helperMap.put(yieldTab, new YieldHelper(plotRep, fisheryMap)); Tab msyTab = TabBuilder.create().text(I18N.getString("MSY_TAB")).closable(false).build(); // NOI18N. helperMap.put(msyTab, new MSYHelper(plotRep, fisheryMap)); tabPane = TabPaneBuilder.create().id("tabPane").build(); // NOI18N. tabPane.getTabs().addAll(movementTab, tagReturnsTab, tagReportingTab, catchTab, biomassTab, exploitableBiomassTab, exploitablePopVSObservedCPUETab, initialPopulationTab, recruitmentTab, fishingMortalityTab, catchabilityTab, effortDevsTab, ageSelectivityTab, lengthSelectivityTab, naturalMortalityTab, growthTab, stockRecruitmentTab, yieldTab, msyTab); // NOI18N. setCenter(tabPane); tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() { /** * {@inheritDoc} */ @Override public void changed(ObservableValue observable, Tab oldValue, Tab newValue) { setupTab(newValue); } }); System.out.println("FX app thread? "+Platform.isFxApplicationThread()); // If uncommented the TabView's arrow button fails to pop on screen. //setupTab(movementTab); // If you use this, the TabView's arrow button is correctly popped up. Platform.runLater(new Runnable() { /** * {@inheritDoc} */ @Override public void run() { setupTab(movementTab); } }); } private void setupTab(final Tab tab) { if (tab.getContent() != null) { return; } final PlotRepHelperBase helper = helperMap.remove(tab); if (helper == null) { return; } ProgressIndicator progressIndicator = ProgressIndicatorBuilder.create().id("progressIndicator").build(); tab.setContent(progressIndicator); Platform.runLater(new Runnable() { /** * {@inheritDoc} */ @Override public void run() { impl_setupTab(tab, helper); } }); } /** * Setup the content of a tab. * @param tab The target tab. * @param helper The helper which will generate this tab's charts. */ private void impl_setupTab(Tab tab, PlotRepHelperBase helper) { System.out.println(MessageFormat.format("impl_setupTab({0}, {1})", tab, helper)); VBox chartBox = VBoxBuilder.create().id("chartBox").build(); // NOI18N. int minHeight = 0; int chartIndex = 0; for (ChartIterator iterator = helper.getChartIterator(); iterator.hasNext();) { Chart chart = iterator.next(); if (chart == null) { continue; } impl_setupChart(chart); minHeight += chart.getMinHeight(); chartBox.getChildren().add(chart); chartIndex++; } System.out.println(MessageFormat.format("impl_setupTab() created {0} chart(s)", chartIndex)); //chartBox.setMinHeight(minHeight); ScrollPane chartScroll = ScrollPaneBuilder.create().id("chartScroll").build(); // NOI18N. chartScroll.setNode(chartBox); //chartScroll.setFitToHeight(true); tab.setContent(chartScroll); } /** * Prepare each chart before display. * @param chart The target chart. */ private void impl_setupChart(Chart chart) { chart.setMinHeight(300); chart.setMaxSize(Integer.MAX_VALUE, Integer.MAX_VALUE); } }