From e82819ffff58c06bd7a664ac3014025747801577 Mon Sep 17 00:00:00 2001 From: mpyat2 Date: Sat, 18 Nov 2023 18:30:13 +0200 Subject: [PATCH 1/4] This branch addresses Issues #381, #382. --- .../period/PeriodAnalysis2DChartPane.java | 24 ++++++++++++++--- .../period/PeriodAnalysis2DResultDialog.java | 7 +++++ .../period/PeriodAnalysisDataTablePane.java | 17 +++++++++++- .../PeriodAnalysisTopHitsTablePane.java | 19 +++++++++++-- .../dialog/period/wwz/WWZDataTablePane.java | 3 +++ .../ui/dialog/period/wwz/WWZPlotPane.java | 3 +++ ...WeightedWaveletZTransformResultDialog.java | 4 +++ .../tools/vstar/ui/mediator/Mediator.java | 27 +++++++++++++++++++ .../ui/mediator/message/MessageBase.java | 10 +++++++ 9 files changed, 108 insertions(+), 6 deletions(-) diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java index 76647be61..8d4cfc819 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java @@ -38,8 +38,6 @@ import org.aavso.tools.vstar.util.IStartAndCleanup; import org.aavso.tools.vstar.util.locale.LocaleProps; import org.aavso.tools.vstar.util.notification.Listener; -import org.aavso.tools.vstar.util.period.IPeriodAnalysisDatum; -import org.aavso.tools.vstar.util.period.PeriodAnalysisCoordinateType; import org.aavso.tools.vstar.util.period.dcdft.PeriodAnalysisDataPoint; import org.jfree.chart.ChartMouseEvent; import org.jfree.chart.ChartMouseListener; @@ -74,6 +72,8 @@ public class PeriodAnalysis2DChartPane extends JPanel implements private Listener periodAnalysisSelectionListener; private Listener periodAnalysisRefinementListener; private Listener harmonicSearchListener; + + private String chartPaneID = null; /** * Constructor @@ -113,6 +113,14 @@ public Dimension getPreferredSize() { return new Dimension(DEFAULT_CHART_PANEL_WIDTH, DEFAULT_CHART_PANEL_HEIGHT); } + public void setChartPaneID(String chartPaneID) { + this.chartPaneID = chartPaneID; + } + + public String getChartPaneID() { + return chartPaneID; + } + /** * @return the chart */ @@ -204,6 +212,7 @@ public void chartMouseClicked(ChartMouseEvent event) { PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage( this, dataPoint, item); if (message != null) { + message.setName(Mediator.getParentDialogName(this)); Mediator.getInstance().getPeriodAnalysisSelectionNotifier() .notifyListeners(message); } @@ -252,6 +261,8 @@ protected Listener createPeriodAnalysisListener( return new Listener() { @Override public void update(PeriodAnalysisSelectionMessage info) { + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(PeriodAnalysis2DChartPane.this), info)) + return; if (info.getSource() != parent) { double x = info.getDataPoint().getValue(model.getDomainType()); double y = info.getDataPoint().getValue(model.getRangeType()); @@ -276,6 +287,8 @@ private Listener createRefinementListener() { return new Listener() { @Override public void update(PeriodAnalysisRefinementMessage info) { + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(PeriodAnalysis2DChartPane.this), info)) + return; chart.getXYPlot().clearAnnotations(); for (PeriodAnalysisDataPoint dataPoint : info.getNewTopHits()) { // if (model.getRangeType() == @@ -302,7 +315,12 @@ private Listener createHarmonicSearchListener() { return new Listener() { @Override public void update(HarmonicSearchResultMessage info) { - new HarmonicInfoDialog(info, pane); + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(PeriodAnalysis2DChartPane.this), info)) + return; + String id = PeriodAnalysis2DChartPane.this.getChartPaneID(); + if (id != null && id.equals("PlotPane0")) { + new HarmonicInfoDialog(info, pane); + } } @Override diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java index 239a870bb..54757bb54 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java @@ -159,6 +159,7 @@ private JTabbedPane createTabs() { plotPanes = new ArrayList(); // Add plots. + int n = 0; for (PeriodAnalysis2DPlotModel model : plotModels) { boolean permitlogarithmic = model.getRangeType() == PeriodAnalysisCoordinateType.POWER; @@ -193,7 +194,9 @@ private JTabbedPane createTabs() { + model.getDomainType(); namedComponents.add(new NamedComponent(tabName, plot)); + plot.setChartPaneID("PlotPane" + Integer.toString(n)); plotPanes.add(plot); + n += 1; } // Add data table view. @@ -219,6 +222,7 @@ private JTabbedPane createTabs() { protected void newPhasePlotButtonAction() { PeriodChangeMessage message = new PeriodChangeMessage(this, selectedDataPoint.getPeriod()); + message.setName(this.getName()); Mediator.getInstance().getPeriodChangeNotifier() .notifyListeners(message); } @@ -231,6 +235,7 @@ protected void findHarmonicsButtonAction() { selectedDataPoint.getFrequency(), data); HarmonicSearchResultMessage msg = new HarmonicSearchResultMessage(this, harmonics, selectedDataPoint); + msg.setName(this.getName()); Mediator.getInstance().getHarmonicSearchNotifier().notifyListeners(msg); } @@ -239,6 +244,8 @@ protected void findHarmonicsButtonAction() { private Listener createPeriodAnalysisListener() { return new Listener() { public void update(PeriodAnalysisSelectionMessage info) { + if (!Mediator.isMsgForDialog(PeriodAnalysis2DResultDialog.this, info)) + return; setNewPhasePlotButtonState(true); setFindHarmonicsButtonState(true); selectedDataPoint = info.getDataPoint(); diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java index e86bbcc21..5e6689395 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java @@ -73,6 +73,8 @@ public class PeriodAnalysisDataTablePane extends JPanel implements ListSelection protected Listener harmonicSearchResultListener; protected Listener periodAnalysisSelectionListener; + private boolean valueChangedDisabled = false; + /** * Constructor * @@ -143,6 +145,9 @@ protected JPanel createButtonPanel() { * has "settled". This event could be consumed by other views such as plots. */ public void valueChanged(ListSelectionEvent e) { + if (valueChangedDisabled) + return; + if (e.getSource() == table.getSelectionModel() && table.getRowSelectionAllowed() && !e.getValueIsAdjusting()) { int row = table.getSelectedRow(); @@ -151,6 +156,7 @@ public void valueChanged(ListSelectionEvent e) { PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage(this, model.getDataPointFromRow(row), row); + message.setName(Mediator.getParentDialogName(this)); Mediator.getInstance().getPeriodAnalysisSelectionNotifier().notifyListeners(message); } } @@ -202,6 +208,8 @@ protected Listener createHarmonicSearchResultListen return new Listener() { @Override public void update(HarmonicSearchResultMessage info) { + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(PeriodAnalysisDataTablePane.this), info)) + return; freqToHarmonicsMap.put(info.getDataPoint().getFrequency(), info.getHarmonics()); } @@ -222,6 +230,8 @@ protected Listener createPeriodAnalysisListener( return new Listener() { @Override public void update(PeriodAnalysisSelectionMessage info) { + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(PeriodAnalysisDataTablePane.this), info)) + return; if (info.getSource() != parent) { // Find data point in table. int row = -1; @@ -251,7 +261,12 @@ public void update(PeriodAnalysisSelectionMessage info) { int rowHeight = table.getRowHeight(row); table.scrollRectToVisible(new Rectangle(colWidth, rowHeight * row, colWidth, rowHeight)); - table.setRowSelectionInterval(row, row); + valueChangedDisabled = true; + try { + table.setRowSelectionInterval(row, row); + } finally { + valueChangedDisabled = false; + } enableButtons(); } } else { diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java index a6ad3f3d5..f1d844c31 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java @@ -58,6 +58,8 @@ public class PeriodAnalysisTopHitsTablePane extends PeriodAnalysisDataTablePane private JButton refineButton; private Listener periodAnalysisRefinementListener; + + private boolean valueChangedDisabled = false; /** * Constructor. @@ -170,7 +172,7 @@ public void actionPerformed(ActionEvent e) { PeriodAnalysisRefinementMessage msg = new PeriodAnalysisRefinementMessage( this, data, topHits, newTopHits); - + msg.setName(Mediator.getParentDialogName(PeriodAnalysisTopHitsTablePane.this)); Mediator.getInstance() .getPeriodAnalysisRefinementNotifier() .notifyListeners(msg); @@ -197,6 +199,8 @@ protected Listener createPeriodAnalysisListener( return new Listener() { @Override public void update(PeriodAnalysisSelectionMessage info) { + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(PeriodAnalysisTopHitsTablePane.this), info)) + return; if (info.getSource() != parent) { // Find data point in top hits table. int row = -1; @@ -229,7 +233,12 @@ public void update(PeriodAnalysisSelectionMessage info) { table.scrollRectToVisible(new Rectangle(colWidth, rowHeight * row, colWidth, rowHeight)); - table.setRowSelectionInterval(row, row); + valueChangedDisabled = true; + try { + table.setRowSelectionInterval(row, row); + } finally { + valueChangedDisabled = false; + } enableButtons(); } } else { @@ -260,6 +269,9 @@ protected void enableButtons() { */ @Override public void valueChanged(ListSelectionEvent e) { + if (valueChangedDisabled) + return; + if (e.getSource() == table.getSelectionModel() && table.getRowSelectionAllowed() && !e.getValueIsAdjusting()) { // Which row in the top hits table was selected? @@ -269,6 +281,7 @@ public void valueChanged(ListSelectionEvent e) { row = table.convertRowIndexToModel(row); PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage( this, model.getDataPointFromRow(row), row); + message.setName(Mediator.getParentDialogName(this)); Mediator.getInstance().getPeriodAnalysisSelectionNotifier() .notifyListeners(message); } @@ -282,6 +295,8 @@ private Listener createRefinementListener() { return new Listener() { @Override public void update(PeriodAnalysisRefinementMessage info) { + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(PeriodAnalysisTopHitsTablePane.this), info)) + return; resultantDataPoints.addAll(info.getNewTopHits()); } diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZDataTablePane.java b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZDataTablePane.java index 16dbc96a7..2c1d43622 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZDataTablePane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZDataTablePane.java @@ -128,6 +128,7 @@ public void valueChanged(ListSelectionEvent e) { PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage( this, model.getDataPointFromRow(row), row); + message.setName(Mediator.getParentDialogName(this)); Mediator.getInstance().getPeriodAnalysisSelectionNotifier() .notifyListeners(message); } @@ -173,6 +174,8 @@ protected Listener createPeriodAnalysisListener( return new Listener() { @Override public void update(PeriodAnalysisSelectionMessage info) { + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(WWZDataTablePane.this), info)) + return; if (info.getSource() != parent) { // Find data point in table. int row = -1; diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZPlotPane.java b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZPlotPane.java index 918c13785..6c89cf2e1 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZPlotPane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZPlotPane.java @@ -139,6 +139,7 @@ public void chartMouseClicked(ChartMouseEvent event) { int item = entity.getItem(); PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage( this, model.getStats().get(item), item); + message.setName(Mediator.getParentDialogName(this)); Mediator.getInstance().getPeriodAnalysisSelectionNotifier() .notifyListeners(message); } @@ -163,6 +164,8 @@ protected Listener createPeriodAnalysisListener( return new Listener() { @Override public void update(PeriodAnalysisSelectionMessage info) { + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(WWZPlotPane.this), info)) + return; if (info.getSource() != parent) { // Find the datapoint in the model (could be minimal or full // stats). diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java index 00b46c731..b3fff7c3c 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java @@ -182,6 +182,7 @@ protected JPanel createButtonPanel() { protected void newPhasePlotButtonAction() { PeriodChangeMessage message = new PeriodChangeMessage(this, selectedDataPoint.getPeriod()); + message.setName(this.getName()); Mediator.getInstance().getPeriodChangeNotifier().notifyListeners( message); } @@ -196,6 +197,7 @@ protected void findHarmonicsButtonAction() { .getFrequency()); HarmonicSearchResultMessage msg = new HarmonicSearchResultMessage(this, harmonics, selectedDataPoint); + msg.setName(this.getName()); Mediator.getInstance().getHarmonicSearchNotifier().notifyListeners(msg); } @@ -227,6 +229,8 @@ protected List findHarmonicsFromWWZStats(double freq) { private Listener createPeriodAnalysisListener() { return new Listener() { public void update(PeriodAnalysisSelectionMessage info) { + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(WeightedWaveletZTransformResultDialog.this), info)) + return; setNewPhasePlotButtonState(true); selectedDataPoint = info.getDataPoint(); } diff --git a/src/org/aavso/tools/vstar/ui/mediator/Mediator.java b/src/org/aavso/tools/vstar/ui/mediator/Mediator.java index ac0b65317..39c096b2c 100644 --- a/src/org/aavso/tools/vstar/ui/mediator/Mediator.java +++ b/src/org/aavso/tools/vstar/ui/mediator/Mediator.java @@ -86,6 +86,7 @@ import org.aavso.tools.vstar.ui.mediator.message.FilteredObservationMessage; import org.aavso.tools.vstar.ui.mediator.message.HarmonicSearchResultMessage; import org.aavso.tools.vstar.ui.mediator.message.MeanSourceSeriesChangeMessage; +import org.aavso.tools.vstar.ui.mediator.message.MessageBase; import org.aavso.tools.vstar.ui.mediator.message.ModelCreationMessage; import org.aavso.tools.vstar.ui.mediator.message.ModelSelectionMessage; import org.aavso.tools.vstar.ui.mediator.message.MultipleObservationSelectionMessage; @@ -2350,5 +2351,31 @@ public void quit() { // defer to Mediator. System.exit(0); } + + public static JDialog getParentDialog(Component c) { + while (c != null) { + if (c instanceof JDialog) { + return (JDialog)c; + } + c = c.getParent(); + } + return null; + } + + public static String getParentDialogName(Component c) { + while (c != null) { + if (c instanceof JDialog) { + return c.getName(); + } + c = c.getParent(); + } + return null; + } + + public static boolean isMsgForDialog(JDialog dlg, MessageBase msg) { + if (dlg == null || msg == null || msg.getName() == null) + return false; + return msg.getName().equals(dlg.getName()); + } } diff --git a/src/org/aavso/tools/vstar/ui/mediator/message/MessageBase.java b/src/org/aavso/tools/vstar/ui/mediator/message/MessageBase.java index 2a7040370..4aaef3e08 100644 --- a/src/org/aavso/tools/vstar/ui/mediator/message/MessageBase.java +++ b/src/org/aavso/tools/vstar/ui/mediator/message/MessageBase.java @@ -22,6 +22,8 @@ */ public class MessageBase { + private String name; + protected Object source; public MessageBase(Object source) { @@ -34,4 +36,12 @@ public MessageBase(Object source) { public Object getSource() { return source; } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } } \ No newline at end of file From 4a2b5076c767539724b6d9c727d63cfad139551f Mon Sep 17 00:00:00 2001 From: mpyat2 Date: Sat, 18 Nov 2023 23:50:17 +0200 Subject: [PATCH 2/4] Trying to partially fix #61. See https://github.com/AAVSO/VStar/issues/61#issuecomment-717564049 --- .../ui/dialog/model/HarmonicInfoDialog.java | 80 +++++++++++++++---- .../period/PeriodAnalysis2DChartPane.java | 3 +- .../period/PeriodAnalysis2DResultDialog.java | 26 +++++- .../tools/vstar/ui/mediator/Mediator.java | 11 ++- .../message/HarmonicSearchResultMessage.java | 9 +++ 5 files changed, 106 insertions(+), 23 deletions(-) diff --git a/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java b/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java index d8c43e8cb..4dbad35ea 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java +++ b/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java @@ -18,8 +18,13 @@ package org.aavso.tools.vstar.ui.dialog.model; import java.awt.FlowLayout; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -62,8 +67,6 @@ public class HarmonicInfoDialog extends JDialog implements private Map harmonicMap; - private JButton dismissButton; - /** * Constructor. * @@ -96,6 +99,13 @@ public HarmonicInfoDialog(HarmonicSearchResultMessage msg, getContentPane().add(topPane); pack(); + + this.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent we) { + dismiss(); + } + }); + setLocationRelativeTo(Mediator.getUI().getContentPane()); setVisible(true); } @@ -128,11 +138,16 @@ private JPanel createListPane() { private JPanel createButtonPane() { JPanel panel = new JPanel(new FlowLayout()); - dismissButton = new JButton("Dismiss"); + JButton dismissButton = new JButton("Dismiss"); dismissButton.addActionListener(createDismissButtonListener()); dismissButton.setEnabled(true); panel.add(dismissButton); + JButton copyButton = new JButton("Copy"); + copyButton.addActionListener(createCopyButtonListener()); + copyButton.setEnabled(true); + panel.add(copyButton); + this.getRootPane().setDefaultButton(dismissButton); return panel; @@ -147,30 +162,46 @@ public void valueChanged(ListSelectionEvent e) { String desc = (String) harmonicListModel .get(selectedModelIndex); Harmonic harmonic = harmonicMap.get(desc); - plotPane - .setCrossHair(harmonic.getFrequency(), - findNthRangeValueFromFrequency(harmonic - .getFrequency())); + double x = harmonic.getFrequency(); + double y = findNthChartRangeValueFromFrequency(x); + // 'y' is not the exact value because the chart resolution is limited. + plotPane.setCrossHair(x, y); } } } // Return the range value corresponding to the specified frequency. - private Double findNthRangeValueFromFrequency(double frequency) { + private Double findNthChartRangeValueFromFrequency(double frequency) { Double value = null; List freqVals = plotPane.getModel().getDomainValues(); List rangeVals = plotPane.getModel().getRangeValues(); + // We take points from the chart; the number of chart points (typically, 100) + // is less than the number of calculated frequencies among which + // the harmonic had been searched (see PeriodAnalysisDialogBase.findHarmonics()). + // So we cannot directly compare 'frequency' with chart values, and even + // Tolerance() will not help much. + // We assume, however, that the point of interest exists on the chart. + // So, we simply try to find the closest chart point. + int i = 0; + Double minDif = null; while (i < freqVals.size()) { - if (freqVals.get(i) == frequency) { + double f = freqVals.get(i); // we assume get() returns non-null + double dif = Math.abs(f - frequency); + if (minDif != null) { + if (dif < minDif) { + minDif = dif; + value = rangeVals.get(i); + } + } else { + minDif = dif; value = rangeVals.get(i); - break; } i++; } - + if (value == null) { throw new IllegalArgumentException("Unknown frequency"); } @@ -178,15 +209,34 @@ private Double findNthRangeValueFromFrequency(double frequency) { return value; } + private void dismiss() { + setVisible(false); + dispose(); + // Restore the plot's cross hair. + plotPane.setCrossHair(startX, startY); + } + // Return a listener for the "Dismiss" button. private ActionListener createDismissButtonListener() { return new ActionListener() { public void actionPerformed(ActionEvent e) { - setVisible(false); - dispose(); - // Restore the plot's cross hair. - plotPane.setCrossHair(startX, startY); + dismiss(); } }; } + + // Return a listener for the "Dismiss" button. + private ActionListener createCopyButtonListener() { + return new ActionListener() { + public void actionPerformed(ActionEvent e) { + String s = ""; + for (int i = 0; i < harmonicListModel.size(); i++) { + s += harmonicListModel.get(i).toString() + "\n"; + } + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(new StringSelection(s) , null); + } + }; + } + } diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java index 8d4cfc819..34568af40 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java @@ -318,7 +318,8 @@ public void update(HarmonicSearchResultMessage info) { if (!Mediator.isMsgForDialog(Mediator.getParentDialog(PeriodAnalysis2DChartPane.this), info)) return; String id = PeriodAnalysis2DChartPane.this.getChartPaneID(); - if (id != null && id.equals("PlotPane0")) { + String currentID = info.getIDstring(); + if (currentID != null && currentID.equals(id)) { new HarmonicInfoDialog(info, pane); } } diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java index 54757bb54..dc6aff912 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java @@ -30,6 +30,7 @@ import org.aavso.tools.vstar.plugin.period.PeriodAnalysisComponentFactory; import org.aavso.tools.vstar.plugin.period.PeriodAnalysisDialogBase; import org.aavso.tools.vstar.ui.NamedComponent; +import org.aavso.tools.vstar.ui.dialog.MessageBox; import org.aavso.tools.vstar.ui.mediator.Mediator; import org.aavso.tools.vstar.ui.mediator.message.HarmonicSearchResultMessage; import org.aavso.tools.vstar.ui.mediator.message.PeriodAnalysisSelectionMessage; @@ -42,6 +43,7 @@ import org.aavso.tools.vstar.util.period.IPeriodAnalysisAlgorithm; import org.aavso.tools.vstar.util.period.IPeriodAnalysisDatum; import org.aavso.tools.vstar.util.period.PeriodAnalysisCoordinateType; +import org.aavso.tools.vstar.util.prefs.NumericPrecisionPrefs; import org.jfree.chart.JFreeChart; import org.jfree.chart.plot.DatasetRenderingOrder; @@ -69,6 +71,10 @@ public class PeriodAnalysis2DResultDialog extends PeriodAnalysisDialogBase { private IPeriodAnalysisDatum selectedDataPoint; private Listener periodAnalysisListener; + + private JTabbedPane tabbedPane; + + private String findHarmonicsButtonText; /** * Constructor @@ -95,6 +101,8 @@ public PeriodAnalysis2DResultDialog(String title, String seriesTitle, assert searchType == PeriodAnalysisCoordinateType.PERIOD || searchType == PeriodAnalysisCoordinateType.FREQUENCY; + findHarmonicsButtonText = LocaleProps.get("FIND_HARMONICS_BUTTON"); + selectedDataPoint = null; resultDataMap = algorithm.getResultSeries(); @@ -147,7 +155,8 @@ public void windowClosing(WindowEvent we) { } protected Component createContent() { - return createTabs(); + tabbedPane = createTabs(); + return tabbedPane; } // Return the tabs containing table and plots of frequency vs one of the @@ -229,6 +238,17 @@ protected void newPhasePlotButtonAction() { @Override protected void findHarmonicsButtonAction() { + String chartID = null; + Component c = tabbedPane.getSelectedComponent(); + if (c instanceof PeriodAnalysis2DChartPane) { + chartID = ((PeriodAnalysis2DChartPane)c).getChartPaneID(); + } + + if (chartID == null) { + MessageBox.showMessageDialog("Find Harmonic", "Please select a tab with a chart"); + return; + } + List data = algorithm.getResultSeries().get( PeriodAnalysisCoordinateType.FREQUENCY); List harmonics = findHarmonics( @@ -236,6 +256,7 @@ protected void findHarmonicsButtonAction() { HarmonicSearchResultMessage msg = new HarmonicSearchResultMessage(this, harmonics, selectedDataPoint); msg.setName(this.getName()); + msg.setIDstring(chartID); Mediator.getInstance().getHarmonicSearchNotifier().notifyListeners(msg); } @@ -249,6 +270,9 @@ public void update(PeriodAnalysisSelectionMessage info) { setNewPhasePlotButtonState(true); setFindHarmonicsButtonState(true); selectedDataPoint = info.getDataPoint(); + // Sometimes the cross-hair does not coincide with the real selection. + // Let's indicate the selected frequency on the button... + findHarmonicsButton.setText(findHarmonicsButtonText + " [" + NumericPrecisionPrefs.formatOther(selectedDataPoint.getFrequency()) + "]"); } public boolean canBeRemoved() { diff --git a/src/org/aavso/tools/vstar/ui/mediator/Mediator.java b/src/org/aavso/tools/vstar/ui/mediator/Mediator.java index 39c096b2c..60f1295b7 100644 --- a/src/org/aavso/tools/vstar/ui/mediator/Mediator.java +++ b/src/org/aavso/tools/vstar/ui/mediator/Mediator.java @@ -2363,13 +2363,12 @@ public static JDialog getParentDialog(Component c) { } public static String getParentDialogName(Component c) { - while (c != null) { - if (c instanceof JDialog) { - return c.getName(); - } - c = c.getParent(); + JDialog dlg = getParentDialog(c); + if (dlg != null) { + return dlg.getName(); + } else { + return null; } - return null; } public static boolean isMsgForDialog(JDialog dlg, MessageBase msg) { diff --git a/src/org/aavso/tools/vstar/ui/mediator/message/HarmonicSearchResultMessage.java b/src/org/aavso/tools/vstar/ui/mediator/message/HarmonicSearchResultMessage.java index a26ded930..de47b1d52 100644 --- a/src/org/aavso/tools/vstar/ui/mediator/message/HarmonicSearchResultMessage.java +++ b/src/org/aavso/tools/vstar/ui/mediator/message/HarmonicSearchResultMessage.java @@ -30,6 +30,7 @@ public class HarmonicSearchResultMessage extends MessageBase { private List harmonics; private IPeriodAnalysisDatum dataPoint; + private String iDstring = null; /** * Constructor @@ -60,4 +61,12 @@ public List getHarmonics() { public IPeriodAnalysisDatum getDataPoint() { return dataPoint; } + + public void setIDstring(String s) { + iDstring = s; + } + + public String getIDstring() { + return iDstring; + } } From 3982b8e22b99cb0751068da52c60c3443dd15ee7 Mon Sep 17 00:00:00 2001 From: mpyat2 Date: Mon, 20 Nov 2023 22:16:37 +0200 Subject: [PATCH 3/4] 1) findHarmonics() tolerance can be tuned by the user. 2) Harmonics are searched within top-hits only, which makes more sense (IMHO - Max) 3) HarmonicInfoDialog: a procedure that shows a selected harmonic was unreasonably complicated. Why should we seek for the y coordinate? Let's display the x-position only. 4) The domain type was ignored in the HarmonicInfoDialog, which made displaying the selected harmonic not work if x of PERIOD type. 5) An algorithm of the hair-cross positioning/showing was changed to make it more intuitive (IMHO - Max) --- .../period/PeriodAnalysisDialogBase.java | 8 +-- .../ui/dialog/model/HarmonicInfoDialog.java | 54 ++++--------------- .../period/PeriodAnalysis2DChartPane.java | 22 +++++++- .../period/PeriodAnalysis2DResultDialog.java | 24 +++++++-- .../period/PeriodAnalysisDataTablePane.java | 4 ++ .../PeriodAnalysisTopHitsTablePane.java | 2 + ...WeightedWaveletZTransformResultDialog.java | 16 +++--- 7 files changed, 68 insertions(+), 62 deletions(-) diff --git a/src/org/aavso/tools/vstar/plugin/period/PeriodAnalysisDialogBase.java b/src/org/aavso/tools/vstar/plugin/period/PeriodAnalysisDialogBase.java index e491e2039..025e3700c 100644 --- a/src/org/aavso/tools/vstar/plugin/period/PeriodAnalysisDialogBase.java +++ b/src/org/aavso/tools/vstar/plugin/period/PeriodAnalysisDialogBase.java @@ -177,7 +177,7 @@ protected void addDismissButton(JPanel buttonPane) { * The data in which to search; assumed to be frequencies. * @return A list of harmonic objects. */ - protected List findHarmonics(double freq, List data) { + protected List findHarmonics(double freq, List data, double tolerance) { List harmonics = new ArrayList(); harmonics.add(new Harmonic(freq, Harmonic.FUNDAMENTAL)); int n = Harmonic.FUNDAMENTAL + 1; @@ -185,13 +185,13 @@ protected List findHarmonics(double freq, List data) { for (int i = 0; i < data.size(); i++) { double potentialHarmonic = data.get(i) / n; - + // Check if the data is a harmonic of the frequency within // a relative tolerance range - if(Tolerance.areClose(potentialHarmonic, freq, 1e-3, false)){ + if (Tolerance.areClose(potentialHarmonic, freq, tolerance, false)) { harmonics.add(new Harmonic(freq * n, n)); n++; - } + } } return harmonics; diff --git a/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java b/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java index 4dbad35ea..5748fc264 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java +++ b/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java @@ -25,7 +25,6 @@ import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.util.List; import java.util.Map; import java.util.TreeMap; @@ -46,6 +45,7 @@ import org.aavso.tools.vstar.ui.mediator.Mediator; import org.aavso.tools.vstar.ui.mediator.message.HarmonicSearchResultMessage; import org.aavso.tools.vstar.util.model.Harmonic; +import org.aavso.tools.vstar.util.period.PeriodAnalysisCoordinateType; import org.aavso.tools.vstar.util.prefs.NumericPrecisionPrefs; /** @@ -99,7 +99,7 @@ public HarmonicInfoDialog(HarmonicSearchResultMessage msg, getContentPane().add(topPane); pack(); - + this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { dismiss(); @@ -162,51 +162,17 @@ public void valueChanged(ListSelectionEvent e) { String desc = (String) harmonicListModel .get(selectedModelIndex); Harmonic harmonic = harmonicMap.get(desc); - double x = harmonic.getFrequency(); - double y = findNthChartRangeValueFromFrequency(x); - // 'y' is not the exact value because the chart resolution is limited. - plotPane.setCrossHair(x, y); - } - } - } - - // Return the range value corresponding to the specified frequency. - private Double findNthChartRangeValueFromFrequency(double frequency) { - Double value = null; - - List freqVals = plotPane.getModel().getDomainValues(); - List rangeVals = plotPane.getModel().getRangeValues(); - - // We take points from the chart; the number of chart points (typically, 100) - // is less than the number of calculated frequencies among which - // the harmonic had been searched (see PeriodAnalysisDialogBase.findHarmonics()). - // So we cannot directly compare 'frequency' with chart values, and even - // Tolerance() will not help much. - // We assume, however, that the point of interest exists on the chart. - // So, we simply try to find the closest chart point. - - int i = 0; - Double minDif = null; - while (i < freqVals.size()) { - double f = freqVals.get(i); // we assume get() returns non-null - double dif = Math.abs(f - frequency); - if (minDif != null) { - if (dif < minDif) { - minDif = dif; - value = rangeVals.get(i); + double x; + if (plotPane.getModel().getDomainType() == PeriodAnalysisCoordinateType.FREQUENCY) { + x = harmonic.getFrequency(); + } else if (plotPane.getModel().getDomainType() == PeriodAnalysisCoordinateType.PERIOD) { + x = harmonic.getPeriod(); + } else { + return; } - } else { - minDif = dif; - value = rangeVals.get(i); + plotPane.setCrossHair(x, 0); } - i++; } - - if (value == null) { - throw new IllegalArgumentException("Unknown frequency"); - } - - return value; } private void dismiss() { diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java index 34568af40..3e54c9c6e 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java @@ -45,6 +45,7 @@ import org.jfree.chart.JFreeChart; import org.jfree.chart.annotations.XYLineAnnotation; import org.jfree.chart.entity.XYItemEntity; +import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.data.general.DatasetChangeEvent; import org.jfree.data.general.DatasetChangeListener; @@ -195,6 +196,15 @@ private void configureChart() { } public void chartMouseClicked(ChartMouseEvent event) { + // The cross-hair appears if the user clicks the chart even if there is no + // 'entity' under the mouse. This means that the cross-hair selection + // does not always coincide with the selected data point. + // Let's show the cross-hair only if an 'entity' is behind it. + + XYPlot plot = event.getChart().getXYPlot(); + plot.setDomainCrosshairVisible(false); + plot.setRangeCrosshairVisible(false); + if (event.getEntity() instanceof XYItemEntity) { XYItemEntity entity = (XYItemEntity) event.getEntity(); int item = entity.getItem(); @@ -208,6 +218,9 @@ public void chartMouseClicked(ChartMouseEvent event) { dataPoint = plotModel.getDataPointFromItem(item); } } + + plot.setDomainCrosshairVisible(true); + plot.setRangeCrosshairVisible(true); PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage( this, dataPoint, item); @@ -230,6 +243,8 @@ public void chartMouseClicked(ChartMouseEvent event) { public void setCrossHair(double x, double y) { chart.getXYPlot().setDomainCrosshairValue(x); chart.getXYPlot().setRangeCrosshairValue(y); + chart.getXYPlot().setDomainCrosshairVisible(true); + chart.getXYPlot().setRangeCrosshairVisible(true); } public void chartMouseMoved(ChartMouseEvent event) { @@ -268,8 +283,11 @@ public void update(PeriodAnalysisSelectionMessage info) { double y = info.getDataPoint().getValue(model.getRangeType()); if (x != Double.NaN && y != Double.NaN) { - chart.getXYPlot().setDomainCrosshairValue(x); - chart.getXYPlot().setRangeCrosshairValue(y); + XYPlot plot = chart.getXYPlot(); + plot.setDomainCrosshairValue(x); + plot.setRangeCrosshairValue(y); + plot.setDomainCrosshairVisible(true); + plot.setRangeCrosshairVisible(true); } } } diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java index dc6aff912..41805b471 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java @@ -30,7 +30,9 @@ import org.aavso.tools.vstar.plugin.period.PeriodAnalysisComponentFactory; import org.aavso.tools.vstar.plugin.period.PeriodAnalysisDialogBase; import org.aavso.tools.vstar.ui.NamedComponent; +import org.aavso.tools.vstar.ui.dialog.DoubleField; import org.aavso.tools.vstar.ui.dialog.MessageBox; +import org.aavso.tools.vstar.ui.dialog.MultiEntryComponentDialog; import org.aavso.tools.vstar.ui.mediator.Mediator; import org.aavso.tools.vstar.ui.mediator.message.HarmonicSearchResultMessage; import org.aavso.tools.vstar.ui.mediator.message.PeriodAnalysisSelectionMessage; @@ -76,6 +78,11 @@ public class PeriodAnalysis2DResultDialog extends PeriodAnalysisDialogBase { private String findHarmonicsButtonText; + private static final double FREQUENCY_RELATIVE_TOLERANCE = 1e-3; + + private double currentTolerance = FREQUENCY_RELATIVE_TOLERANCE; + DoubleField toleranceField; + /** * Constructor * @@ -249,16 +256,25 @@ protected void findHarmonicsButtonAction() { return; } - List data = algorithm.getResultSeries().get( - PeriodAnalysisCoordinateType.FREQUENCY); - List harmonics = findHarmonics( - selectedDataPoint.getFrequency(), data); + MultiEntryComponentDialog paramDialog = createParamDialog(); + if (paramDialog.isCancelled()) { + return; + } + currentTolerance = toleranceField.getValue(); + //List data = algorithm.getResultSeries().get(PeriodAnalysisCoordinateType.FREQUENCY); + List data = algorithm.getTopHits().get(PeriodAnalysisCoordinateType.FREQUENCY); + List harmonics = findHarmonics(selectedDataPoint.getFrequency(), data, currentTolerance); HarmonicSearchResultMessage msg = new HarmonicSearchResultMessage(this, harmonics, selectedDataPoint); msg.setName(this.getName()); msg.setIDstring(chartID); Mediator.getInstance().getHarmonicSearchNotifier().notifyListeners(msg); } + + private MultiEntryComponentDialog createParamDialog() { + toleranceField = new DoubleField("Relative Frequency Tolerance", 0.0, 1.0, currentTolerance); + return new MultiEntryComponentDialog("Find Harmonics", toleranceField); + } // Enable the new phase plot button and store the selected // period analysis data point. diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java index 5e6689395..8648d3911 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java @@ -171,6 +171,10 @@ public void actionPerformed(ActionEvent e) { List dataPoints = new ArrayList(); List userSelectedFreqs = new ArrayList(); int[] selectedTableRowIndices = table.getSelectedRows(); + if (selectedTableRowIndices.length < 1) { + MessageBox.showMessageDialog(LocaleProps.get("CREATE_MODEL_BUTTON"), "Please select a row"); + return; + } for (int row : selectedTableRowIndices) { int modelRow = table.convertRowIndexToModel(row); diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java index f1d844c31..eb4700724 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java @@ -240,6 +240,8 @@ public void update(PeriodAnalysisSelectionMessage info) { valueChangedDisabled = false; } enableButtons(); + } else { + table.clearSelection(); } } else { enableButtons(); diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java index b3fff7c3c..8e8768ab8 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java @@ -31,7 +31,6 @@ import org.aavso.tools.vstar.plugin.period.PeriodAnalysisDialogBase; import org.aavso.tools.vstar.ui.NamedComponent; import org.aavso.tools.vstar.ui.mediator.Mediator; -import org.aavso.tools.vstar.ui.mediator.message.HarmonicSearchResultMessage; import org.aavso.tools.vstar.ui.mediator.message.PeriodAnalysisSelectionMessage; import org.aavso.tools.vstar.ui.mediator.message.PeriodChangeMessage; import org.aavso.tools.vstar.ui.model.list.WWZDataTableModel; @@ -39,7 +38,6 @@ import org.aavso.tools.vstar.ui.model.plot.WWZ3DPlotModel; import org.aavso.tools.vstar.util.IStartAndCleanup; import org.aavso.tools.vstar.util.locale.LocaleProps; -import org.aavso.tools.vstar.util.model.Harmonic; import org.aavso.tools.vstar.util.notification.Listener; import org.aavso.tools.vstar.util.period.IPeriodAnalysisDatum; import org.aavso.tools.vstar.util.period.wwz.WWZCoordinateType; @@ -193,14 +191,15 @@ protected void newPhasePlotButtonAction() { @Override protected void findHarmonicsButtonAction() { - List harmonics = findHarmonicsFromWWZStats(selectedDataPoint - .getFrequency()); - HarmonicSearchResultMessage msg = new HarmonicSearchResultMessage(this, - harmonics, selectedDataPoint); - msg.setName(this.getName()); - Mediator.getInstance().getHarmonicSearchNotifier().notifyListeners(msg); +// List harmonics = findHarmonicsFromWWZStats(selectedDataPoint +// .getFrequency()); +// HarmonicSearchResultMessage msg = new HarmonicSearchResultMessage(this, +// harmonics, selectedDataPoint); +// msg.setName(this.getName()); +// Mediator.getInstance().getHarmonicSearchNotifier().notifyListeners(msg); } +/* // TODO: Refactor so that the base class method takes an interface // with a method that returns a frequency from a sequence. Then // List or List can be wrapped in an object @@ -223,6 +222,7 @@ protected List findHarmonicsFromWWZStats(double freq) { return harmonics; } +*/ // Enable the new phase plot button and store the selected // period analysis data point. From 6ff82cb433ca778efc4d0b2292b4648ba6414f07 Mon Sep 17 00:00:00 2001 From: mpyat2 Date: Fri, 24 Nov 2023 19:04:29 +0200 Subject: [PATCH 4/4] find harmonics improvement --- .../period/PeriodAnalysisDialogBase.java | 38 ++++-- .../ui/dialog/model/HarmonicInfoDialog.java | 123 +++++++++++++++--- .../period/PeriodAnalysis2DChartPane.java | 13 +- .../period/PeriodAnalysis2DResultDialog.java | 20 +-- .../period/PeriodAnalysisDataTablePane.java | 56 +++++++- .../PeriodAnalysisTopHitsTablePane.java | 19 +-- .../dialog/period/wwz/WWZDataTablePane.java | 2 +- .../ui/dialog/period/wwz/WWZPlotPane.java | 2 +- ...WeightedWaveletZTransformResultDialog.java | 2 +- .../tools/vstar/ui/mediator/Mediator.java | 4 +- .../message/HarmonicSearchResultMessage.java | 9 +- .../ui/mediator/message/MessageBase.java | 10 +- 12 files changed, 231 insertions(+), 67 deletions(-) diff --git a/src/org/aavso/tools/vstar/plugin/period/PeriodAnalysisDialogBase.java b/src/org/aavso/tools/vstar/plugin/period/PeriodAnalysisDialogBase.java index 025e3700c..6e1441252 100644 --- a/src/org/aavso/tools/vstar/plugin/period/PeriodAnalysisDialogBase.java +++ b/src/org/aavso/tools/vstar/plugin/period/PeriodAnalysisDialogBase.java @@ -24,6 +24,7 @@ import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import javax.swing.BorderFactory; @@ -179,19 +180,32 @@ protected void addDismissButton(JPanel buttonPane) { */ protected List findHarmonics(double freq, List data, double tolerance) { List harmonics = new ArrayList(); - harmonics.add(new Harmonic(freq, Harmonic.FUNDAMENTAL)); - int n = Harmonic.FUNDAMENTAL + 1; - - for (int i = 0; i < data.size(); i++) { - - double potentialHarmonic = data.get(i) / n; - - // Check if the data is a harmonic of the frequency within - // a relative tolerance range - if (Tolerance.areClose(potentialHarmonic, freq, tolerance, false)) { - harmonics.add(new Harmonic(freq * n, n)); - n++; + + //Do not assume that the fundamental frequency exists in the data. + //harmonics.add(new Harmonic(freq, Harmonic.FUNDAMENTAL)); + //int n = Harmonic.FUNDAMENTAL + 1; + + double minData = Collections.min(data); + double maxData = Collections.max(data); + + assert(freq > 0 || minData > 0); + + int n = Harmonic.FUNDAMENTAL; + + // Do not assume that data are sorted. + while (freq * n <= maxData) { + for (int i = 0; i < data.size(); i++) { + double potentialHarmonic = data.get(i) / n; + // Check if the data is a harmonic of the frequency within + // a relative tolerance range + if (Tolerance.areClose(potentialHarmonic, freq, tolerance, false)) { + if (freq * n >= minData || freq * n <= maxData) { + harmonics.add(new Harmonic(freq * n, n)); + break; + } + } } + n++; } return harmonics; diff --git a/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java b/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java index 5748fc264..5ee6f21d0 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java +++ b/src/org/aavso/tools/vstar/ui/dialog/model/HarmonicInfoDialog.java @@ -17,7 +17,9 @@ */ package org.aavso.tools.vstar.ui.dialog.model; +import java.awt.Component; import java.awt.FlowLayout; +import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; @@ -25,6 +27,7 @@ import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.util.ArrayList; import java.util.Map; import java.util.TreeMap; @@ -36,17 +39,23 @@ import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.aavso.tools.vstar.ui.dialog.period.PeriodAnalysis2DChartPane; +import org.aavso.tools.vstar.ui.dialog.period.PeriodAnalysisDataTablePane; import org.aavso.tools.vstar.ui.mediator.DocumentManager; import org.aavso.tools.vstar.ui.mediator.Mediator; import org.aavso.tools.vstar.ui.mediator.message.HarmonicSearchResultMessage; +import org.aavso.tools.vstar.ui.model.list.PeriodAnalysisDataTableModel; +import org.aavso.tools.vstar.util.Tolerance; import org.aavso.tools.vstar.util.model.Harmonic; import org.aavso.tools.vstar.util.period.PeriodAnalysisCoordinateType; +import org.aavso.tools.vstar.util.period.dcdft.PeriodAnalysisDataPoint; import org.aavso.tools.vstar.util.prefs.NumericPrecisionPrefs; +import org.jfree.chart.plot.XYPlot; /** * This dialog shows harmonics found from a search for harmonics of some @@ -58,9 +67,12 @@ public class HarmonicInfoDialog extends JDialog implements ListSelectionListener { private HarmonicSearchResultMessage msg; - private PeriodAnalysis2DChartPane plotPane; + //private PeriodAnalysis2DChartPane plotPane; + private Component interfaceComponent; private double startX, startY; + + private ArrayList startIndices; private JList harmonicList; private DefaultListModel harmonicListModel; @@ -72,22 +84,32 @@ public class HarmonicInfoDialog extends JDialog implements * * @param msg * The harmonic search result message. - * @param plotPane - * The corresponding plot pane to set the cross-hair on. + * @param interfaceComponent + * plot pane or data table. */ public HarmonicInfoDialog(HarmonicSearchResultMessage msg, - PeriodAnalysis2DChartPane plotPane) { + Component interfaceComponent) { super(DocumentManager.findActiveWindow()); this.setTitle("Harmonics"); this.setModal(true); this.msg = msg; - this.plotPane = plotPane; - - startX = plotPane.getChart().getXYPlot().getDomainCrosshairValue(); - startY = plotPane.getChart().getXYPlot().getRangeCrosshairValue(); - + + this.interfaceComponent = interfaceComponent; + if (interfaceComponent instanceof PeriodAnalysis2DChartPane) { + XYPlot plot = ((PeriodAnalysis2DChartPane)interfaceComponent).getChart().getXYPlot(); + startX = plot.getDomainCrosshairValue(); + startY = plot.getRangeCrosshairValue(); + } else if (interfaceComponent instanceof PeriodAnalysisDataTablePane) { + JTable table = ((PeriodAnalysisDataTablePane)interfaceComponent).getTable(); + int[] indices = table.getSelectedRows(); + startIndices = new ArrayList(); + for (int row : indices) { + startIndices.add(row); + } + } + this.harmonicMap = new TreeMap(); JPanel topPane = new JPanel(); @@ -163,14 +185,55 @@ public void valueChanged(ListSelectionEvent e) { .get(selectedModelIndex); Harmonic harmonic = harmonicMap.get(desc); double x; - if (plotPane.getModel().getDomainType() == PeriodAnalysisCoordinateType.FREQUENCY) { - x = harmonic.getFrequency(); - } else if (plotPane.getModel().getDomainType() == PeriodAnalysisCoordinateType.PERIOD) { - x = harmonic.getPeriod(); - } else { - return; + + if (interfaceComponent instanceof PeriodAnalysis2DChartPane) { + PeriodAnalysis2DChartPane plotPane = (PeriodAnalysis2DChartPane)interfaceComponent; + if (plotPane.getModel().getDomainType() == PeriodAnalysisCoordinateType.FREQUENCY) { + x = harmonic.getFrequency(); + } else if (plotPane.getModel().getDomainType() == PeriodAnalysisCoordinateType.PERIOD) { + x = harmonic.getPeriod(); + } else { + return; + } + plotPane.setCrossHair(x, 0); + } else if (interfaceComponent instanceof PeriodAnalysisDataTablePane) { + selectHarmonic(((PeriodAnalysisDataTablePane)interfaceComponent).getTable(), harmonic, msg.getTolerance()); } - plotPane.setCrossHair(x, 0); + } + } + } + + private void selectHarmonic(JTable table, Harmonic harmonic, double tolerance) { + if (table.getModel() instanceof PeriodAnalysisDataTableModel) { + PeriodAnalysisDataTableModel model = (PeriodAnalysisDataTableModel)(table.getModel()); + Integer closestRow = null; + Double minDiff = null; + int n = harmonic.getHarmonicNumber(); + //System.out.println("\nselectHarmonic"); + for (int row = 0; row < model.getRowCount(); row++) { + PeriodAnalysisDataPoint dataPoint = model.getDataPointFromRow(row); + double f = dataPoint.getFrequency(); + // use tolerance but also look for the closest point inside the tolerance! + if (Tolerance.areClose(f / n, harmonic.getFrequency() / n, tolerance, false)) { + double dif = Math.abs(f - harmonic.getFrequency()); + if (minDiff == null || dif < minDiff) { + minDiff = dif; + closestRow = row; + //System.out.println("minDif = " + minDiff); + } + } + } + if (closestRow != null) { + closestRow = table.convertRowIndexToView(closestRow); + ensureVisible(table, closestRow); + boolean state = ((PeriodAnalysisDataTablePane)interfaceComponent).disableValueChangeEvent(); + try { + table.setRowSelectionInterval(closestRow, closestRow); + } finally { + ((PeriodAnalysisDataTablePane)interfaceComponent).setValueChangedDisabledState(state); + } + } else { + throw new IllegalArgumentException("Harmonic not found"); } } } @@ -178,8 +241,32 @@ public void valueChanged(ListSelectionEvent e) { private void dismiss() { setVisible(false); dispose(); - // Restore the plot's cross hair. - plotPane.setCrossHair(startX, startY); + // Restore the plot's cross hair or table's selection(s). + if (interfaceComponent instanceof PeriodAnalysis2DChartPane) { + ((PeriodAnalysis2DChartPane)interfaceComponent).setCrossHair(startX, startY); + } else if (interfaceComponent instanceof PeriodAnalysisDataTablePane) { + JTable table = ((PeriodAnalysisDataTablePane)interfaceComponent).getTable(); + if (startIndices != null) { + if (startIndices.size() > 0) { + ensureVisible(table, startIndices.get(0)); + } + boolean state = ((PeriodAnalysisDataTablePane)interfaceComponent).disableValueChangeEvent(); + try { + table.clearSelection(); + for (int row : startIndices) { + table.addRowSelectionInterval(row, row); + } + } finally { + ((PeriodAnalysisDataTablePane)interfaceComponent).setValueChangedDisabledState(state); + } + } + } + } + + private void ensureVisible(JTable table, int row) { + int colWidth = (int) table.getCellRect(row, 0, true).getWidth(); + int rowHeight = table.getRowHeight(row); + table.scrollRectToVisible(new Rectangle(colWidth, rowHeight * row, colWidth, rowHeight)); } // Return a listener for the "Dismiss" button. diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java index 3e54c9c6e..8ebd61508 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DChartPane.java @@ -29,6 +29,7 @@ import javax.swing.JCheckBox; import javax.swing.JPanel; +import org.aavso.tools.vstar.ui.dialog.MessageBox; import org.aavso.tools.vstar.ui.dialog.model.HarmonicInfoDialog; import org.aavso.tools.vstar.ui.mediator.Mediator; import org.aavso.tools.vstar.ui.mediator.message.HarmonicSearchResultMessage; @@ -225,7 +226,7 @@ public void chartMouseClicked(ChartMouseEvent event) { PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage( this, dataPoint, item); if (message != null) { - message.setName(Mediator.getParentDialogName(this)); + message.setTag(Mediator.getParentDialogName(this)); Mediator.getInstance().getPeriodAnalysisSelectionNotifier() .notifyListeners(message); } @@ -333,12 +334,16 @@ private Listener createHarmonicSearchListener() { return new Listener() { @Override public void update(HarmonicSearchResultMessage info) { - if (!Mediator.isMsgForDialog(Mediator.getParentDialog(PeriodAnalysis2DChartPane.this), info)) + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(pane), info)) return; - String id = PeriodAnalysis2DChartPane.this.getChartPaneID(); + String id = pane.getChartPaneID(); String currentID = info.getIDstring(); if (currentID != null && currentID.equals(id)) { - new HarmonicInfoDialog(info, pane); + if (info.getHarmonics().size() > 0) { + new HarmonicInfoDialog(info, pane); + } else { + MessageBox.showMessageDialog("Harmonics", "No top hit for this frequency"); + } } } diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java index 41805b471..f4ac84115 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysis2DResultDialog.java @@ -218,12 +218,14 @@ private JTabbedPane createTabs() { // Add data table view. dataTablePane = new PeriodAnalysisDataTablePane(dataTableModel, algorithm, false); + dataTablePane.setTablePaneID("DataTable"); namedComponents.add(new NamedComponent(LocaleProps.get("DATA_TAB"), dataTablePane)); // Add top-hits table view. topHitsTablePane = new PeriodAnalysisTopHitsTablePane( topHitsTableModel, dataTableModel, algorithm); + topHitsTablePane.setTablePaneID("TopHitsTable"); namedComponents.add(new NamedComponent(LocaleProps.get("TOP_HITS_TAB"), topHitsTablePane)); @@ -238,21 +240,23 @@ private JTabbedPane createTabs() { protected void newPhasePlotButtonAction() { PeriodChangeMessage message = new PeriodChangeMessage(this, selectedDataPoint.getPeriod()); - message.setName(this.getName()); + message.setTag(this.getName()); Mediator.getInstance().getPeriodChangeNotifier() .notifyListeners(message); } @Override protected void findHarmonicsButtonAction() { - String chartID = null; + String componentID = null; Component c = tabbedPane.getSelectedComponent(); if (c instanceof PeriodAnalysis2DChartPane) { - chartID = ((PeriodAnalysis2DChartPane)c).getChartPaneID(); + componentID = ((PeriodAnalysis2DChartPane)c).getChartPaneID(); + } else if (c instanceof PeriodAnalysisDataTablePane) { + componentID = ((PeriodAnalysisDataTablePane)c).getTablePaneID(); } - if (chartID == null) { - MessageBox.showMessageDialog("Find Harmonic", "Please select a tab with a chart"); + if (componentID == null) { + MessageBox.showMessageDialog("Find Harmonic", "Not implemented for this view"); return; } @@ -265,9 +269,9 @@ protected void findHarmonicsButtonAction() { List data = algorithm.getTopHits().get(PeriodAnalysisCoordinateType.FREQUENCY); List harmonics = findHarmonics(selectedDataPoint.getFrequency(), data, currentTolerance); HarmonicSearchResultMessage msg = new HarmonicSearchResultMessage(this, - harmonics, selectedDataPoint); - msg.setName(this.getName()); - msg.setIDstring(chartID); + harmonics, selectedDataPoint, currentTolerance); + msg.setTag(this.getName()); + msg.setIDstring(componentID); Mediator.getInstance().getHarmonicSearchNotifier().notifyListeners(msg); } diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java index 8648d3911..19718e147 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisDataTablePane.java @@ -38,6 +38,7 @@ import javax.swing.table.TableRowSorter; import org.aavso.tools.vstar.ui.dialog.MessageBox; +import org.aavso.tools.vstar.ui.dialog.model.HarmonicInfoDialog; import org.aavso.tools.vstar.ui.dialog.model.HarmonicInputDialog; import org.aavso.tools.vstar.ui.mediator.Mediator; import org.aavso.tools.vstar.ui.mediator.message.HarmonicSearchResultMessage; @@ -73,7 +74,9 @@ public class PeriodAnalysisDataTablePane extends JPanel implements ListSelection protected Listener harmonicSearchResultListener; protected Listener periodAnalysisSelectionListener; - private boolean valueChangedDisabled = false; + private String tablePaneID = null; + + private boolean valueChangedDisabledState = false; /** * Constructor @@ -145,7 +148,7 @@ protected JPanel createButtonPanel() { * has "settled". This event could be consumed by other views such as plots. */ public void valueChanged(ListSelectionEvent e) { - if (valueChangedDisabled) + if (isValueChangeDisabled()) return; if (e.getSource() == table.getSelectionModel() && table.getRowSelectionAllowed() && !e.getValueIsAdjusting()) { @@ -156,7 +159,7 @@ public void valueChanged(ListSelectionEvent e) { PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage(this, model.getDataPointFromRow(row), row); - message.setName(Mediator.getParentDialogName(this)); + message.setTag(Mediator.getParentDialogName(this)); Mediator.getInstance().getPeriodAnalysisSelectionNotifier().notifyListeners(message); } } @@ -209,12 +212,23 @@ public void actionPerformed(ActionEvent e) { * (fundamental) frequency to harmonics. */ protected Listener createHarmonicSearchResultListener() { + final PeriodAnalysisDataTablePane tablePane = this; return new Listener() { @Override public void update(HarmonicSearchResultMessage info) { - if (!Mediator.isMsgForDialog(Mediator.getParentDialog(PeriodAnalysisDataTablePane.this), info)) + if (!Mediator.isMsgForDialog(Mediator.getParentDialog(tablePane), info)) return; freqToHarmonicsMap.put(info.getDataPoint().getFrequency(), info.getHarmonics()); + + String id = tablePane.getTablePaneID(); + String currentID = info.getIDstring(); + if (currentID != null && currentID.equals(id)) { + if (info.getHarmonics().size() > 0) { + new HarmonicInfoDialog(info, tablePane); + } else { + MessageBox.showMessageDialog("Harmonics", "No top hit for this frequency"); + } + } } @Override @@ -265,11 +279,11 @@ public void update(PeriodAnalysisSelectionMessage info) { int rowHeight = table.getRowHeight(row); table.scrollRectToVisible(new Rectangle(colWidth, rowHeight * row, colWidth, rowHeight)); - valueChangedDisabled = true; + boolean state = disableValueChangeEvent(); try { table.setRowSelectionInterval(row, row); } finally { - valueChangedDisabled = false; + setValueChangedDisabledState(state); } enableButtons(); } @@ -307,4 +321,34 @@ public void cleanup() { Mediator.getInstance().getPeriodAnalysisSelectionNotifier() .removeListenerIfWilling(periodAnalysisSelectionListener); } + + public void setTablePaneID(String tablePaneID) { + this.tablePaneID = tablePaneID; + } + + public String getTablePaneID() { + return tablePaneID; + } + + /** + * @return the table + */ + public JTable getTable() { + return table; + } + + public boolean disableValueChangeEvent() { + boolean state = valueChangedDisabledState; + valueChangedDisabledState = true; + return state; + } + + public void setValueChangedDisabledState(boolean state) { + valueChangedDisabledState = state; + } + + public boolean isValueChangeDisabled() { + return valueChangedDisabledState; + } + } diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java index eb4700724..88c21e828 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/PeriodAnalysisTopHitsTablePane.java @@ -59,8 +59,6 @@ public class PeriodAnalysisTopHitsTablePane extends PeriodAnalysisDataTablePane private Listener periodAnalysisRefinementListener; - private boolean valueChangedDisabled = false; - /** * Constructor. * @@ -172,7 +170,7 @@ public void actionPerformed(ActionEvent e) { PeriodAnalysisRefinementMessage msg = new PeriodAnalysisRefinementMessage( this, data, topHits, newTopHits); - msg.setName(Mediator.getParentDialogName(PeriodAnalysisTopHitsTablePane.this)); + msg.setTag(Mediator.getParentDialogName(PeriodAnalysisTopHitsTablePane.this)); Mediator.getInstance() .getPeriodAnalysisRefinementNotifier() .notifyListeners(msg); @@ -233,15 +231,20 @@ public void update(PeriodAnalysisSelectionMessage info) { table.scrollRectToVisible(new Rectangle(colWidth, rowHeight * row, colWidth, rowHeight)); - valueChangedDisabled = true; + boolean state = disableValueChangeEvent(); try { table.setRowSelectionInterval(row, row); } finally { - valueChangedDisabled = false; + setValueChangedDisabledState(state); } enableButtons(); } else { - table.clearSelection(); + boolean state = disableValueChangeEvent(); + try { + table.clearSelection(); + } finally { + setValueChangedDisabledState(state); + } } } else { enableButtons(); @@ -271,7 +274,7 @@ protected void enableButtons() { */ @Override public void valueChanged(ListSelectionEvent e) { - if (valueChangedDisabled) + if (isValueChangeDisabled()) return; if (e.getSource() == table.getSelectionModel() @@ -283,7 +286,7 @@ public void valueChanged(ListSelectionEvent e) { row = table.convertRowIndexToModel(row); PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage( this, model.getDataPointFromRow(row), row); - message.setName(Mediator.getParentDialogName(this)); + message.setTag(Mediator.getParentDialogName(this)); Mediator.getInstance().getPeriodAnalysisSelectionNotifier() .notifyListeners(message); } diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZDataTablePane.java b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZDataTablePane.java index 2c1d43622..c6c10a8eb 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZDataTablePane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZDataTablePane.java @@ -128,7 +128,7 @@ public void valueChanged(ListSelectionEvent e) { PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage( this, model.getDataPointFromRow(row), row); - message.setName(Mediator.getParentDialogName(this)); + message.setTag(Mediator.getParentDialogName(this)); Mediator.getInstance().getPeriodAnalysisSelectionNotifier() .notifyListeners(message); } diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZPlotPane.java b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZPlotPane.java index 6c89cf2e1..c10014b3b 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZPlotPane.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WWZPlotPane.java @@ -139,7 +139,7 @@ public void chartMouseClicked(ChartMouseEvent event) { int item = entity.getItem(); PeriodAnalysisSelectionMessage message = new PeriodAnalysisSelectionMessage( this, model.getStats().get(item), item); - message.setName(Mediator.getParentDialogName(this)); + message.setTag(Mediator.getParentDialogName(this)); Mediator.getInstance().getPeriodAnalysisSelectionNotifier() .notifyListeners(message); } diff --git a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java index 8e8768ab8..4c90ea19f 100644 --- a/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java +++ b/src/org/aavso/tools/vstar/ui/dialog/period/wwz/WeightedWaveletZTransformResultDialog.java @@ -180,7 +180,7 @@ protected JPanel createButtonPanel() { protected void newPhasePlotButtonAction() { PeriodChangeMessage message = new PeriodChangeMessage(this, selectedDataPoint.getPeriod()); - message.setName(this.getName()); + message.setTag(this.getName()); Mediator.getInstance().getPeriodChangeNotifier().notifyListeners( message); } diff --git a/src/org/aavso/tools/vstar/ui/mediator/Mediator.java b/src/org/aavso/tools/vstar/ui/mediator/Mediator.java index 60f1295b7..1a735e89f 100644 --- a/src/org/aavso/tools/vstar/ui/mediator/Mediator.java +++ b/src/org/aavso/tools/vstar/ui/mediator/Mediator.java @@ -2372,9 +2372,9 @@ public static String getParentDialogName(Component c) { } public static boolean isMsgForDialog(JDialog dlg, MessageBase msg) { - if (dlg == null || msg == null || msg.getName() == null) + if (dlg == null || msg == null || msg.getTag() == null) return false; - return msg.getName().equals(dlg.getName()); + return msg.getTag().equals(dlg.getName()); } } diff --git a/src/org/aavso/tools/vstar/ui/mediator/message/HarmonicSearchResultMessage.java b/src/org/aavso/tools/vstar/ui/mediator/message/HarmonicSearchResultMessage.java index de47b1d52..dbd17d933 100644 --- a/src/org/aavso/tools/vstar/ui/mediator/message/HarmonicSearchResultMessage.java +++ b/src/org/aavso/tools/vstar/ui/mediator/message/HarmonicSearchResultMessage.java @@ -30,6 +30,7 @@ public class HarmonicSearchResultMessage extends MessageBase { private List harmonics; private IPeriodAnalysisDatum dataPoint; + private double tolerance; private String iDstring = null; /** @@ -41,11 +42,12 @@ public class HarmonicSearchResultMessage extends MessageBase { * @param dataPoint The datapoint associated with the first harmonic. */ public HarmonicSearchResultMessage(Object source, List harmonics, - IPeriodAnalysisDatum dataPoint) { + IPeriodAnalysisDatum dataPoint, double tolerance) { super(source); this.harmonics = harmonics; this.dataPoint = dataPoint; + this.tolerance = tolerance; } /** @@ -69,4 +71,9 @@ public void setIDstring(String s) { public String getIDstring() { return iDstring; } + + public double getTolerance() { + return tolerance; + } + } diff --git a/src/org/aavso/tools/vstar/ui/mediator/message/MessageBase.java b/src/org/aavso/tools/vstar/ui/mediator/message/MessageBase.java index 4aaef3e08..6fd98e5f3 100644 --- a/src/org/aavso/tools/vstar/ui/mediator/message/MessageBase.java +++ b/src/org/aavso/tools/vstar/ui/mediator/message/MessageBase.java @@ -22,7 +22,7 @@ */ public class MessageBase { - private String name; + private String tag; protected Object source; @@ -37,11 +37,11 @@ public Object getSource() { return source; } - public void setName(String name) { - this.name = name; + public void setTag(String name) { + this.tag = name; } - public String getName() { - return name; + public String getTag() { + return tag; } } \ No newline at end of file