From 4624fa090361b9233d32ebaaedbde3fab8b93bb7 Mon Sep 17 00:00:00 2001 From: Harald Wolff Date: Mon, 21 Nov 2016 16:08:15 +0100 Subject: [PATCH] WIP161121 --- .../pulscounter/PulsCounterApplication.java | 10 ++ src/org/hwo/pulscounter/SnapShot.java | 5 + .../pulscounter/db/PulsCounterDatabase.java | 6 + src/org/hwo/pulscounter/ui/BatchRunner.java | 37 +++- src/org/hwo/pulscounter/ui/NewMainWindow.java | 27 +-- .../hwo/pulscounter/ui/SnapshotManager.java | 169 ++++++++++++++---- 6 files changed, 187 insertions(+), 67 deletions(-) diff --git a/src/org/hwo/pulscounter/PulsCounterApplication.java b/src/org/hwo/pulscounter/PulsCounterApplication.java index d5212f5..34dacc7 100644 --- a/src/org/hwo/pulscounter/PulsCounterApplication.java +++ b/src/org/hwo/pulscounter/PulsCounterApplication.java @@ -71,6 +71,8 @@ public class PulsCounterApplication implements ServiceLinkListener{ private PulsCounterDatabase database; + private List batchCommands; + @@ -109,6 +111,8 @@ public class PulsCounterApplication implements ServiceLinkListener{ interfaceClasses = new ArrayList<>(); interfaces = new ArrayList<>(); + batchCommands = new ArrayList<>(); + /* Prepare for Startup */ loadApplicationConfiguration(); @@ -134,6 +138,8 @@ public class PulsCounterApplication implements ServiceLinkListener{ case "-G": applicationConfiguration.setProperty("ui.class", NewMainWindow.class.getCanonicalName()); break; + case "--batch-execute": + batchCommands.add( options.next() ); default: log(WARN,"Unknown command line parameter: %s", option); } @@ -208,6 +214,10 @@ public class PulsCounterApplication implements ServiceLinkListener{ log("OS Search Path: %s", System.getenv("PATH")); } + public String[] getBatchCommands(){ + return batchCommands.toArray(new String[0]); + } + public void start(){ diff --git a/src/org/hwo/pulscounter/SnapShot.java b/src/org/hwo/pulscounter/SnapShot.java index b380372..6a10793 100644 --- a/src/org/hwo/pulscounter/SnapShot.java +++ b/src/org/hwo/pulscounter/SnapShot.java @@ -7,13 +7,17 @@ import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; +import java.util.UUID; import org.hwo.csv.CSVRecord; import org.hwo.models.TableMapper.TableColumn; import org.hwo.servicelink.ServiceLink; import org.hwo.servicelink.ServiceLinkException; +import org.hwo.ui.diagram.annotation.Plot; public class SnapShot { + UUID uuid; + Integer deviceSerial; Integer index; @@ -145,6 +149,7 @@ public class SnapShot { this.values[ch] = value; } } + @Plot(label="Zähler %d",instances=32) public Integer getValue(Integer ch){ if ((ch >= 0) && (ch<32)){ return this.values[ch]; diff --git a/src/org/hwo/pulscounter/db/PulsCounterDatabase.java b/src/org/hwo/pulscounter/db/PulsCounterDatabase.java index 41fd336..577163d 100644 --- a/src/org/hwo/pulscounter/db/PulsCounterDatabase.java +++ b/src/org/hwo/pulscounter/db/PulsCounterDatabase.java @@ -192,6 +192,12 @@ public class PulsCounterDatabase { ); } + public void deleteSnapshot(SnapShot snapShot){ + log(INFO,"db delete snapshot [%d]",snapShot.getIndex()); + executeVerySimpleQuery("DELETE FROM snapshots WHERE device=? AND snap_id=?", snapShot.getDeviceSerial(),snapShot.getIndex()); + } + + public int highestSnapShot(int deviceSerial){ Integer ind = (Integer)executeSimpleQueryObject("SELECT max(snap_id) FROM snapshots WHERE device=? GROUP BY device", deviceSerial); if (ind == null){ diff --git a/src/org/hwo/pulscounter/ui/BatchRunner.java b/src/org/hwo/pulscounter/ui/BatchRunner.java index 4b188d2..a3b2f09 100644 --- a/src/org/hwo/pulscounter/ui/BatchRunner.java +++ b/src/org/hwo/pulscounter/ui/BatchRunner.java @@ -26,15 +26,42 @@ public class BatchRunner implements PulsCounterApplicationListener{ } public void run(){ - - PulsCounterApplication.getApplication().checkForSnapShots(); - for (ExportSetting es: PulsCounterApplication.getApplication().getExportSettings()){ - if (es.getAutostart()){ - es.export(); + for (String cmd: pulsCounterApplication.getBatchCommands()){ + String[] tokens = cmd.split(":"); + switch (tokens[0]){ + case "output": + + String[] s = tokens[1].split("="); + int outputno = Integer.decode(s[0]); + int state = Integer.decode(s[1]); + + int outputs = pulsCounterApplication.getInterfaces().get(0).getOutputs(); + if (state != 0){ + outputs |= (1<\nAbgleich der Zeitmessung
\n
\nDiese Funktion gleicht die Geschwindigkeit der Echtzeituhr des
\nSynololog mit der des Rechners ab und korrigiert diese Laufzeitdifferenz.
\n
\nHierdurch kann der Synololog auch ohne angeschlossenen Rechner über
\nmehrere Tage hinweg eine genaue Systemzeit vorhalten.
\n
\nDie Trimmung sollte vor allem dann ausgeführt werden, wenn die durchschnittliche
\nUmgebungstemperatur am Einsatzort des Synololog sich stark verändert.\n"); - cbTrimDevice.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - trimTicksOnConnect = null; - if (cbTrimDevice.isSelected()){ - // trimDevice(); - } - } - }); - panel_4 = new JPanel(); panel_4.setBorder(new TitledBorder(null, "Anschlusseinstellungen", TitledBorder.LEADING, TitledBorder.TOP, null, null)); GridBagConstraints gbc_panel_4 = new GridBagConstraints(); gbc_panel_4.gridwidth = 2; - gbc_panel_4.insets = new Insets(0, 0, 5, 0); gbc_panel_4.fill = GridBagConstraints.BOTH; gbc_panel_4.gridx = 0; gbc_panel_4.gridy = 2; @@ -454,13 +440,6 @@ public class NewMainWindow implements PulsCounterApplicationListener, TaskletLis gbc_tfConnectionSettings.gridy = 0; panel_4.add(tfConnectionSettings, gbc_tfConnectionSettings); tfConnectionSettings.setColumns(10); - - GridBagConstraints gbc_cbTrimDevice = new GridBagConstraints(); - gbc_cbTrimDevice.gridwidth = 2; - gbc_cbTrimDevice.anchor = GridBagConstraints.WEST; - gbc_cbTrimDevice.gridx = 0; - gbc_cbTrimDevice.gridy = 3; - panel_1.add(cbTrimDevice, gbc_cbTrimDevice); JPanel panel_2 = new JPanel(); panel_2.setBackground(Color.WHITE); diff --git a/src/org/hwo/pulscounter/ui/SnapshotManager.java b/src/org/hwo/pulscounter/ui/SnapshotManager.java index d7f94de..d4f17e6 100644 --- a/src/org/hwo/pulscounter/ui/SnapshotManager.java +++ b/src/org/hwo/pulscounter/ui/SnapshotManager.java @@ -23,7 +23,9 @@ import org.hwo.pulscounter.PulsCounterApplication; import org.hwo.pulscounter.SnapShot; import org.hwo.ui.JMappedTable; import org.hwo.ui.MousePopupListener; +import org.hwo.ui.diagram.AnnotatedPlotProvider; import org.hwo.ui.diagram.LinePlotPainter; +import org.hwo.ui.diagram.PlotLabeler; import org.hwo.ui.diagram.SimplePlotProvider; import javax.swing.JScrollPane; @@ -33,10 +35,14 @@ import javax.swing.JOptionPane; import javax.swing.event.ListSelectionListener; import javax.swing.event.ListSelectionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.lang.management.GarbageCollectorMXBean; import java.awt.event.ActionEvent; import javax.swing.ScrollPaneConstants; import javax.swing.ListSelectionModel; import java.awt.Insets; +import java.awt.MenuItem; + import javax.swing.JTabbedPane; import javax.swing.BoxLayout; import org.hwo.ui.JDiagram; @@ -66,10 +72,15 @@ public class SnapshotManager extends JDialog { private JCheckBox cbDifferenzen; private JPanel paIndex; + private JLabel[] graphLabels; + private AnnotatedPlotProvider + annotatedPlotProvider; + /** * Create the dialog. */ public SnapshotManager() { + setTitle("Aufgezeichnete Werte verwalten"); setModal(true); setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); setModalityType(ModalityType.APPLICATION_MODAL); @@ -176,10 +187,13 @@ public class SnapshotManager extends JDialog { gbl_panel_2.rowWeights = new double[]{0.0, Double.MIN_VALUE}; panel_2.setLayout(gbl_panel_2); { - cbDifferenzen = new JCheckBox("Differenzen"); + cbDifferenzen = new JCheckBox("Differenzieren"); cbDifferenzen.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { - updateDiagram(); + for (int i=0;i<32;i++){ + annotatedPlotProvider.setPlotDifferentiated(i, cbDifferenzen.isSelected()); + } + diaSnapshots.repaint(); } }); GridBagConstraints gbc_cbDifferenzen = new GridBagConstraints(); @@ -218,7 +232,10 @@ public class SnapshotManager extends JDialog { initialize(); } - private void initialize(){ + private void initializeDeviceList(){ + initializeDeviceList(null); + } + private void initializeDeviceList(Integer preSelected){ Integer[] deviceSerials = PulsCounterApplication.getApplication().getDatabase().getKnownDevices(); DefaultListModel lm = new DefaultListModel<>(); @@ -227,6 +244,13 @@ public class SnapshotManager extends JDialog { } lDevices.setModel(lm); + lDevices.setSelectedValue(preSelected, true); + } + + private void initialize(){ + graphLabels = new JLabel[32]; + + initializeDeviceList(); mtSnapshots.getTableMapper().setReadOnly(true); mtSnapshots.getTableMapper().addListSelectionListener(new ListSelectionListener() { @@ -238,10 +262,66 @@ public class SnapshotManager extends JDialog { }); for (int i=0;i<32;i++){ + final int ii = i; + JLabel l = new JLabel(String.format("#%02d", i)); l.setForeground(plotColors[i]); + l.addMouseListener(new MouseAdapter() { + public void mouseClicked(java.awt.event.MouseEvent e) { + if (l.isEnabled()){ + l.setEnabled(false); + annotatedPlotProvider.setPlotEnabled(ii, false); + } else { + l.setEnabled(true); + annotatedPlotProvider.setPlotEnabled(ii, true); + } + diaSnapshots.repaint(); + }; + }); + l.addMouseListener(new MousePopupListener() { + + @Override + public void popupTriggered(int x, int y) { + JPopupMenu popup = new JPopupMenu(); + + JMenuItem mi = new JMenuItem("Nur diesen Graph zeigen"); + mi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + for (int g=0;g<32;g++){ + graphLabels[g].setEnabled(false); + annotatedPlotProvider.setPlotEnabled(g, false); + } + graphLabels[ii].setEnabled(true); + annotatedPlotProvider.setPlotEnabled(ii,true); + diaSnapshots.repaint(); + } + }); + popup.add(mi); + + mi = new JMenuItem("Alle ausser diesem Graph zeigen"); + mi.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + for (int g=0;g<32;g++){ + graphLabels[g].setEnabled(true); + annotatedPlotProvider.setPlotEnabled(g, true); + } + graphLabels[ii].setEnabled(false); + annotatedPlotProvider.setPlotEnabled(ii, false); + diaSnapshots.repaint(); + } + }); + popup.add(mi); + + popup.show(l, x, y); + } + }); paIndex.add(l); + graphLabels[i] = l; } mtSnapshots.addMouseListener(new MousePopupListener() { @@ -257,16 +337,37 @@ public class SnapshotManager extends JDialog { @Override public void actionPerformed(ActionEvent e) { - if (JOptionPane.showConfirmDialog(mtSnapshots, "Sollen die markierten Snapshots wirklich gelöscht werden?","Aufzeichnungen entfernen",JOptionPane.YES_NO_OPTION)==JOptionPane.YES_OPTION){ + if (JOptionPane.showConfirmDialog(SnapshotManager.this, "Sollen die markierten Snapshots wirklich gelöscht werden?","Aufzeichnungen entfernen",JOptionPane.YES_NO_OPTION)==JOptionPane.YES_OPTION){ for (SnapShot ss: selRows){ mtSnapshots.getTableMapper().removeRow(ss); + PulsCounterApplication.getApplication().getDatabase().deleteSnapshot(ss); } + + if (mtSnapshots.getTableMapper().getRows().size()==0){ + initializeDeviceList(); + } + mtSnapshots.repaint(); } } }); popupMenu.add(mi); + mi = new JMenuItem("(Ent-)Parken"); + mi.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + for (SnapShot ss: selRows){ + mtSnapshots.getTableMapper().removeRow(ss); + PulsCounterApplication.getApplication().getDatabase().deleteSnapshot(ss); + ss.setDeviceSerial(-ss.getDeviceSerial()); + PulsCounterApplication.getApplication().getDatabase().storeSnapshots(new SnapShot[]{ss}); + } + initializeDeviceList((Integer)lDevices.getSelectedValue()); + } + }); + popupMenu.add(mi); + popupMenu.show(mtSnapshots, x, y); } @@ -274,6 +375,29 @@ public class SnapshotManager extends JDialog { } }); + + annotatedPlotProvider = new AnnotatedPlotProvider(SnapShot.class); + + for (int i=0;i<32;i++){ + annotatedPlotProvider.setColors(i, plotColors[i]); + } + + diaSnapshots.setPlotProvider(annotatedPlotProvider); + diaSnapshots.setAbszissLabeler(new PlotLabeler() { + + @Override + public String getOrdinateLabel(JDiagram diagram, int ordinate, Double value) { + return null; + } + + @Override + public String getAbzisseLabel(JDiagram diagram, Double pos) { + return ((SnapShot)annotatedPlotProvider.getValues().get(pos.intValue())).getTimeStampFormated(); + } + }); + + if (lDevices.getModel().getSize()>0) + lDevices.setSelectedIndex(0); } private void showSnapshots(){ @@ -288,45 +412,14 @@ public class SnapshotManager extends JDialog { updateDiagram(); } - private void updateDiagram(){ - System.gc(); - + private void updateDiagram(){ SnapShot[] rows = mtSnapshots.getTableMapper().getSelectedRows(new SnapShot[0]); if ((rows == null)||(rows.length==0)){ rows = mtSnapshots.getTableMapper().getRows(SnapShot.class).toArray(new SnapShot[0]); } - - int plotLength = rows.length; - - if (cbDifferenzen.isSelected()){ - plotLength--; - } - - if (plotLength > 1024) - plotLength = 1024; - - SimplePlotProvider pp = new SimplePlotProvider(32, plotLength); - diaSnapshots.setPlotProvider(pp); - - for (int p=0;p<32;p++){ - Float[] v = new Float[ plotLength ]; - - for (int i=0;i