Chart2D
that constantly adds new tracepoints to a
- * Trace2DLtd
. Mainly the runtime- scaling is interesting.
- *
- * Furthermore this is an example on how to connect other components to the
- * Chart2D
using an adaptor- class. If interested have a look on
- * {@link info.monitorenter.reflection.ObjRecorder2Trace2DAdapter}.
- *
- * - * @author Achim Westermann - * @version $Revision: 1.5 $ - */ -public class Chart extends JFrame { - /** - * Helper class that holds an internal number that is randomly modified by a - * Thread. - *
- * - * @author Achim Westermann - * @version $Revision: 1.5 $ - */ - static class RandomBumper extends Thread { - /** Streches or compresses the grade of jumping of the internal number. */ - protected double m_factor; - - /** The bumping number. */ - protected double m_number = 0; - - /** The propability of an increase versus a decrease of the bumped number. */ - protected double m_plusminus = 0.5; - - /** Needed for randomization of bumping the number. */ - protected java.util.Random m_randomizer = new java.util.Random(); - - /** - * Creates an instance. - *
- *
- * @param plusminus
- * probability to increase or decrease the number each step.
- * @param factor
- * affects the amplitude of the number (severity of jumps).
- */
- public RandomBumper(final double plusminus, final int factor) {
-
- if (plusminus < 0 || plusminus > 1) {
- System.out.println(this.getClass().getName()
- + " ignores constructor-passed value. Must be between 0.0 and 1.0!");
- } else {
- this.m_plusminus = plusminus;
- }
- this.m_factor = factor;
- this.setDaemon(true);
- this.start();
- }
-
- /**
- * @see java.lang.Runnable#run()
- */
- @Override
- public void run() {
-
- while (true) {
- double rand = this.m_randomizer.nextDouble();
- if (rand < this.m_plusminus) {
- this.m_number += this.m_randomizer.nextDouble() * this.m_factor;
- } else {
- this.m_number -= this.m_randomizer.nextDouble() * this.m_factor;
- }
-
- try {
- Thread.sleep(20);
- } catch (InterruptedException e) {
- // nop
- }
-
- }
- }
- }
-
- /**
- * Generated for serialVersionUID
.
- */
- private static final long serialVersionUID = 3545231432038627123L;
-
- /**
- * Main entry.
- *
- * - * @param args - * ignored. - */ - public static void main(final String[] args) { - - Chart2D chart = new Chart2D(); - chart.setUseAntialiasing(true); - chart.setMinPaintLatency(20); - ITrace2D data = new Trace2DLtd(300); - data.setStroke(new BasicStroke(3)); - data.setColor(new Color(255, 0, 0, 255)); - data.setName("random"); - data.setPhysicalUnits("hertz", "ms"); - - ITracePainter> dotPainter = new TracePainterPolyline(); - data.setTracePainter(dotPainter); - chart.addTrace(data); - - Chart wnd = new Chart(chart, "AntialiasingChart"); - chart.getAxisX().setPaintGrid(true); - chart.getAxisX().setStartMajorTick(false); - chart.getAxisY().setPaintGrid(true); - - chart.getAxisX().setPaintScale(true); - chart.getAxisX().setPaintScale(true); - - // force ranges: - chart.getAxisY().setRangePolicy(new RangePolicyMinimumViewport(new Range(0, 20))); - // chart.setFont(new Font(null,0,12)); - wnd.setLocation(200, 300); - wnd.setSize(700, 210); - wnd.setResizable(true); - wnd.setVisible(true); - new ObjRecorder2Trace2DAdapter(data, new RandomBumper(0.5, 1000), "m_number", 1000); - } - - /** The chart to use. */ - protected Chart2D m_chart = null; - - /** - * Creates an instance that will dynamically paint on the chart to a trace - * with the given label. - *
- *
- * @param chart
- * the chart to use.
- * @param label
- * the name of the trace too display.
- */
- public Chart(final Chart2D chart, final String label) {
-
- super(label);
- this.m_chart = chart;
- this.addWindowListener(new WindowAdapter() {
- /**
- * @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
- */
- @Override
- public void windowClosing(final WindowEvent e) {
-
- Chart.this.setVisible(false);
- Chart.this.dispose();
- System.exit(0);
-
- }
- });
- Container contentPane = this.getContentPane();
- contentPane.setLayout(new BorderLayout());
- contentPane.add(new ChartPanel(this.m_chart), BorderLayout.CENTER);
- }
-}
\ No newline at end of file
diff --git a/src/net/i2p/itoopie/gui/component/ParticipatingTunnelsChart.java b/src/net/i2p/itoopie/gui/component/ParticipatingTunnelsChart.java
new file mode 100644
index 000000000..578ab638f
--- /dev/null
+++ b/src/net/i2p/itoopie/gui/component/ParticipatingTunnelsChart.java
@@ -0,0 +1,83 @@
+package net.i2p.itoopie.gui.component;
+
+import info.monitorenter.gui.chart.Chart2D;
+import info.monitorenter.gui.chart.IAxis.AxisTitle;
+import info.monitorenter.gui.chart.ITrace2D;
+import info.monitorenter.gui.chart.ITracePainter;
+import info.monitorenter.gui.chart.labelformatters.LabelFormatterDate;
+import info.monitorenter.gui.chart.labelformatters.LabelFormatterNumber;
+import info.monitorenter.gui.chart.rangepolicies.RangePolicyMinimumViewport;
+import info.monitorenter.gui.chart.traces.Trace2DLtd;
+import info.monitorenter.gui.chart.traces.painters.TracePainterPolyline;
+import info.monitorenter.gui.chart.views.ChartPanel;
+import info.monitorenter.util.Range;
+
+import java.awt.BasicStroke;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Container;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+
+import javax.swing.JFrame;
+
+import net.i2p.itoopie.configuration.ConfigurationManager;
+import net.i2p.itoopie.gui.component.chart.DummyDataCollector;
+import net.i2p.itoopie.gui.component.chart.RateStatTracker;
+import net.i2p.itoopie.gui.component.chart.ObjRecorder2Trace2DAdapter;
+import net.i2p.itoopie.i18n.Transl;
+
+
+public class ParticipatingTunnelsChart {
+ private static ConfigurationManager _conf = ConfigurationManager.getInstance();
+ private final static int DEFAULT_UPDATE_INTERVAL = 1000; // Update every 1000th ms
+ private final static int DEFAULT_GRAPH_INTERVAL = 2*3600; // The graph will cover a maximum of 2hrs
+ private final static String DATE_FORMAT = "HH:mm:ss";
+
+ public static Chart2D getChart(){
+ int updateInterval = _conf.getConf("graph.updateinterval", DEFAULT_UPDATE_INTERVAL);
+ int graphInterval = _conf.getConf("graph.graphinterval", DEFAULT_GRAPH_INTERVAL);
+
+ Chart2D chart = new Chart2D();
+ chart.setUseAntialiasing(true);
+ chart.setMinPaintLatency(20);
+ ITrace2D dataPartTunnels = new Trace2DLtd( updateInterval*graphInterval );
+ dataPartTunnels.setStroke(new BasicStroke(1));
+ dataPartTunnels.setColor(new Color(255, 0, 0, 255));
+ dataPartTunnels.setName(Transl._("Number of tunnels we are participating in."));
+
+ ITracePainter> dotPainter = new TracePainterPolyline();
+ dataPartTunnels.setTracePainter(dotPainter);
+ chart.addTrace(dataPartTunnels);
+
+ final SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
+
+ chart.getAxisX().setFormatter(new LabelFormatterDate(sdf));
+ chart.getAxisX().setPaintGrid(true);
+ chart.getAxisX().setAxisTitle(new AxisTitle(Transl._("Time")));
+
+ DecimalFormat df = new DecimalFormat("0 ; 0");
+ chart.getAxisY().setFormatter(new LabelFormatterNumber(df));
+ chart.getAxisY().setPaintGrid(true);
+ chart.getAxisY().setAxisTitle(new AxisTitle(""));
+
+ // force ranges:
+ chart.getAxisY().setRangePolicy(new RangePolicyMinimumViewport(new Range(0, 20)));
+
+ //new ObjRecorder2Trace2DAdapter(dataPartTunnels, new RateStatTracker("tunnel.participatingTunnels", 3600000L), "m_value", updateInterval);
+ new ObjRecorder2Trace2DAdapter(dataPartTunnels, new DummyDataCollector(0.5, 1000), "m_number", updateInterval);
+ return chart;
+ }
+
+ public static void main(final String[] args) {
+ JFrame frame = new JFrame();
+ Container contentPane = frame.getContentPane();
+ contentPane.setLayout(new BorderLayout());
+ contentPane.add(new ChartPanel(getChart()), BorderLayout.CENTER);
+ //frame.add(new ChartPanel(getChart()));
+ frame.setLocation(200, 300);
+ frame.setSize(700, 210);
+ frame.setResizable(true);
+ frame.setVisible(true);
+ }
+}
diff --git a/src/net/i2p/itoopie/gui/component/ProgressiveDisclosurePanel.java b/src/net/i2p/itoopie/gui/component/ProgressiveDisclosurePanel.java
deleted file mode 100644
index 476dc0724..000000000
--- a/src/net/i2p/itoopie/gui/component/ProgressiveDisclosurePanel.java
+++ /dev/null
@@ -1,260 +0,0 @@
-package net.i2p.itoopie.gui.component;
-
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.HeadlessException;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-
-import javax.swing.Icon;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.RootPaneContainer;
-import javax.swing.UIManager;
-
-public final class ProgressiveDisclosurePanel extends JOptionPane {
- /** Label. */
- private final JLabel label;
-
- /** Wrapped container. */
- private final Container container;
-
- /** True if this disclosure triangle container is collapsed. */
- private boolean collapsed;
-
- /** Collapse icon. */
- private Icon collapseIcon;
-
- /** Expand icon. */
- private Icon expandIcon;
-
- /** Default label text, "Details"
. */
- public static final String DEFAULT_LABEL_TEXT = "Details";
-
- /**
- * Create a new disclosure triangle container wrapping the specified
- * container.
- *
- *
- * By default this disclosure triangle container will be collapsed, its label
- * text will be "Details"
, its collapse icon will be the icon
- * resource returned by UIManager.getIcon("Tree.expandedIcon")
,
- * and its expand icon will be the icon resource returned by
- * UIManager.getIcon("Tree.collapsedIcon")
.
- *
collapse()
or expand()
as appropriate.
- *
- * - * This is a bound property. - *
- * - * @param collapsed true to collapse this disclosure triangle container - */ - public void setCollapsed(final boolean collapsed) { - boolean oldCollapsed = this .collapsed; - if (collapsed && !oldCollapsed) { - doCollapse(); - } - if (!collapsed && oldCollapsed) { - doExpand(); - } - this .collapsed = collapsed; - firePropertyChange("collapsed", oldCollapsed, this .collapsed); - } - - /** - * Return the parent root pane container for this disclosure triangle - * container or null if one does not exist. - * - * @return the parent root pane container for this disclosure triangle - * container or null if one does not exist - */ - private Container getParentRootPaneContainer() { - Container c = this ; - while (!(c instanceof RootPaneContainer)) { - if (c.getParent() == null) { - return null; - } - c = c.getParent(); - } - return c; - } - - /** - * Return the label text for this disclosure triangle container. - * - * @return the label text for this disclosure triangle container - */ - public String getLabelText() { - return label.getText(); - } - - /** - * Set the label text for this disclosure triangle container to - *labelText
.
- *
- * - * This is a bound property. - *
- * - * @param labelText label text for this disclosure triangle container - */ - public void setLabelText(final String labelText) { - String oldLabelText = label.getText(); - label.setText(labelText); - firePropertyChange("labelText", oldLabelText, label.getText()); - } - - /** - * Return the collapse icon for this disclosure triangle container. - * - * @return the collapse icon for this disclosure triangle container - */ - public Icon getCollapseIcon() { - return collapseIcon; - } - - /** - * Set the collapse icon for this disclosure triangle container to - *collapseIcon
.
- *
- * - * This is a bound property. - *
- * - * @param collapseIcon - * collapse icon for this disclosure triangle container - */ - public void setCollapseIcon(final Icon collapseIcon) { - Icon oldCollapseIcon = this .collapseIcon; - this .collapseIcon = collapseIcon; - firePropertyChange("collapseIcon", oldCollapseIcon, - this .collapseIcon); - if (!collapsed) { - label.setIcon(this .collapseIcon); - } - } - - /** - * Return the expand icon for this disclosure triangle container. - * - * @return the expand icon for this disclosure triangle container - */ - public Icon getExpandIcon() { - return expandIcon; - } - - /** - * Set the expand icon for this disclosure triangle container to - *expandIcon
.
- *
- * - * This is a bound property. - *
- * - * @param expandIcon expand icon for this disclosure triangle container - */ - public void setExpandIcon(final Icon expandIcon) { - Icon oldExpandIcon = this .expandIcon; - this.expandIcon = expandIcon; - firePropertyChange("expandIcon", oldExpandIcon, this.expandIcon); - if (collapsed) { - label.setIcon(this.expandIcon); - } - } -} diff --git a/src/net/i2p/itoopie/gui/component/chart/DummyDataCollector.java b/src/net/i2p/itoopie/gui/component/chart/DummyDataCollector.java new file mode 100644 index 000000000..86b446ebc --- /dev/null +++ b/src/net/i2p/itoopie/gui/component/chart/DummyDataCollector.java @@ -0,0 +1,61 @@ +package net.i2p.itoopie.gui.component.chart; + +public class DummyDataCollector extends Thread { + /** Streches or compresses the grade of jumping of the internal number. */ + protected double m_factor; + + /** The bumping number. */ + protected double m_number = 0; + + /** The propability of an increase versus a decrease of the bumped number. */ + protected double m_plusminus = 0.5; + + /** Needed for randomization of bumping the number. */ + protected java.util.Random m_randomizer = new java.util.Random(); + + /** + * Creates an instance. + *
+ *
+ * @param plusminus
+ * probability to increase or decrease the number each step.
+ * @param factor
+ * affects the amplitude of the number (severity of jumps).
+ */
+ public DummyDataCollector(final double plusminus, final int factor) {
+
+ if (plusminus < 0 || plusminus > 1) {
+ System.out
+ .println(this.getClass().getName()
+ + " ignores constructor-passed value. Must be between 0.0 and 1.0!");
+ } else {
+ this.m_plusminus = plusminus;
+ }
+ this.m_factor = factor;
+ this.setDaemon(true);
+ this.start();
+ }
+
+ /**
+ * @see java.lang.Runnable#run()
+ */
+ @Override
+ public void run() {
+
+ while (true) {
+ double rand = this.m_randomizer.nextDouble();
+ if (rand < this.m_plusminus) {
+ this.m_number += this.m_randomizer.nextDouble() * this.m_factor;
+ } else {
+ this.m_number -= this.m_randomizer.nextDouble() * this.m_factor;
+ }
+
+ try {
+ Thread.sleep(20);
+ } catch (InterruptedException e) {
+ // nop
+ }
+
+ }
+ }
+}
diff --git a/src/net/i2p/itoopie/gui/component/chart/ObjRecorder2Trace2DAdapter.java b/src/net/i2p/itoopie/gui/component/chart/ObjRecorder2Trace2DAdapter.java
new file mode 100644
index 000000000..6977a422c
--- /dev/null
+++ b/src/net/i2p/itoopie/gui/component/chart/ObjRecorder2Trace2DAdapter.java
@@ -0,0 +1,162 @@
+/*
+ * ObjectRecorder2Trace2DAdpater, an adapter which enables drawing timestamped
+ * values inspected by the ObjectRecorder on a Chart2D.
+ * Copyright (c) 2004 - 2011 Achim Westermann, Achim.Westermann@gmx.de
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * If you modify or optimize the code in a useful way please let me know.
+ * Achim.Westermann@gmx.de
+ */
+
+package net.i2p.itoopie.gui.component.chart;
+
+import info.monitorenter.gui.chart.ITrace2D;
+import info.monitorenter.reflection.ObjectRecorder;
+import info.monitorenter.util.TimeStampedValue;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+/**
+ * A simple adapter that allows displaying of timestamped values from an
+ * inspection of the
+ * {@link info.monitorenter.reflection.ObjectRecorder}
on a
+ * Chart2D.
+ *
+ * + * @author Achim Westermann + * + * @version $Revision: 1.7 $ + */ +public class ObjRecorder2Trace2DAdapter implements ChangeListener { + + /** The field name to inspect. */ + private final String m_fieldname; + + /** The source inspector to connect to the trace. */ + private final ObjectRecorder m_inspector; + + /** The target trace to use. */ + private final ITrace2D m_view; + + /** + * Creates a bridge from the given field of the given instance to inspect to + * the trace. + *
+ * + * @param view + * the target trace that will show the inspected value. + * + * @param toinspect + * the instance to inpsect. + * + * @param fieldname + * the field on the instance to inspect. + * + * @param interval + * the interval of inspections in ms. + */ + public ObjRecorder2Trace2DAdapter(final ITrace2D view, final Object toinspect, + final String fieldname, final long interval) { + this.m_view = view; + this.m_fieldname = fieldname; + this.m_inspector = new ObjectRecorder(toinspect, interval); + this.m_inspector.addChangeListener(this); + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (this.getClass() != obj.getClass()) { + return false; + } + final ObjRecorder2Trace2DAdapter other = (ObjRecorder2Trace2DAdapter) obj; + if (this.m_fieldname == null) { + if (other.m_fieldname != null) { + return false; + } + } else if (!this.m_fieldname.equals(other.m_fieldname)) { + return false; + } + if (this.m_inspector == null) { + if (other.m_inspector != null) { + return false; + } + } else if (!this.m_inspector.equals(other.m_inspector)) { + return false; + } + if (this.m_view == null) { + if (other.m_view != null) { + return false; + } + } else if (!this.m_view.equals(other.m_view)) { + return false; + } + return true; + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.m_fieldname == null) ? 0 : this.m_fieldname.hashCode()); + result = prime * result + ((this.m_inspector == null) ? 0 : this.m_inspector.hashCode()); + result = prime * result + ((this.m_view == null) ? 0 : this.m_view.hashCode()); + return result; + } + + /** + * Sets the interval for inspections in ms. + *
+ * + * @param interval + * the interval for inspections in ms. + */ + public void setInterval(final long interval) { + this.m_inspector.setInterval(interval); + } + + /** + * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent) + */ + public void stateChanged(final ChangeEvent e) { + TimeStampedValue last; + try { + last = this.m_inspector.getLastValue(this.m_fieldname); + } catch (final Exception f) { + f.printStackTrace(); + return; + } + if (last != null) { + double tmpx; + double tmpy; + tmpx = last.getTime(); + tmpy = Double.parseDouble(last.getValue().toString()); + this.m_view.addPoint(tmpx, tmpy); + } + } +} diff --git a/src/net/i2p/itoopie/gui/component/chart/RateStatTracker.java b/src/net/i2p/itoopie/gui/component/chart/RateStatTracker.java new file mode 100644 index 000000000..60b5d1322 --- /dev/null +++ b/src/net/i2p/itoopie/gui/component/chart/RateStatTracker.java @@ -0,0 +1,59 @@ +package net.i2p.itoopie.gui.component.chart; + +import com.thetransactioncompany.jsonrpc2.client.JSONRPC2SessionException; + +import net.i2p.itoopie.configuration.ConfigurationManager; +import net.i2p.itoopie.i2pcontrol.InvalidParametersException; +import net.i2p.itoopie.i2pcontrol.InvalidPasswordException; +import net.i2p.itoopie.i2pcontrol.methods.GetRateStat; + +public class RateStatTracker extends Thread { + + private static ConfigurationManager _conf = ConfigurationManager.getInstance(); + /** Last read bw */ + private double m_value = 0; + + /** Poll router for current ratestat every updateInterval seconds */ + private final static int DEFAULT_UPDATE_INTERVAL = 100; // Update every 100th ms + + private int updateInterval = _conf.getConf("graph.updateinterval", DEFAULT_UPDATE_INTERVAL); + + /** Which RateStat to measure from the router */ + private String rateStat; + + /** Which period of a stat to measure */ + private long period; + + /** + * Start daemon that checks to current inbound bandwidth of the router. + */ + public RateStatTracker(String rateStat, long period) { + this.rateStat = rateStat; + this.period = period; + this.setDaemon(true); + this.start(); + } + + /** + * @see java.lang.Runnable#run() + */ + @Override + public void run() { + + while (true) { + try { + m_value = GetRateStat.execute(rateStat, period); + } catch (InvalidPasswordException e1) { + } catch (JSONRPC2SessionException e1) { + } catch (InvalidParametersException e1) { + } + + try { + Thread.sleep(updateInterval); + } catch (InterruptedException e) { + // nop + } + + } + } +} diff --git a/src/net/i2p/itoopie/i2pcontrol/JSONRPC2Interface.java b/src/net/i2p/itoopie/i2pcontrol/JSONRPC2Interface.java index 6dbde37f1..55a73b1bd 100644 --- a/src/net/i2p/itoopie/i2pcontrol/JSONRPC2Interface.java +++ b/src/net/i2p/itoopie/i2pcontrol/JSONRPC2Interface.java @@ -23,7 +23,6 @@ import com.thetransactioncompany.jsonrpc2.client.JSONRPC2SessionException; public class JSONRPC2Interface { private static Log _log; private static ConfigurationManager _conf; - private static String DEFAULT_PASSWORD = "itoopie"; private static int nonce; private static final int MAX_NBR_RETRIES = 2; private static JSONRPC2Session session;