001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tc.admin.common;
005:
006: import org.dijon.Button;
007: import org.dijon.Container;
008: import org.dijon.ContainerResource;
009: import org.dijon.Spinner;
010: import org.dijon.SplitPane;
011: import org.jfree.chart.ChartPanel;
012: import org.jfree.chart.JFreeChart;
013: import org.jfree.chart.plot.XYPlot;
014: import org.jfree.data.time.Second;
015: import org.jfree.data.time.TimeSeries;
016:
017: import com.tc.admin.AdminClient;
018: import com.tc.admin.AdminClientContext;
019: import com.tc.admin.ConnectionContext;
020: import com.tc.stats.statistics.CountStatistic;
021: import com.tc.stats.statistics.Statistic;
022:
023: import java.awt.GridLayout;
024: import java.awt.event.ActionEvent;
025: import java.awt.event.ActionListener;
026: import java.util.Date;
027:
028: import javax.management.ObjectName;
029: import javax.swing.Icon;
030: import javax.swing.ImageIcon;
031: import javax.swing.SpinnerNumberModel;
032: import javax.swing.SwingConstants;
033: import javax.swing.Timer;
034: import javax.swing.event.ChangeEvent;
035: import javax.swing.event.ChangeListener;
036:
037: // TODO: This and StatisticPanel should be merged. Maybe StatisticPanel should be a
038: // special case of this guy.
039:
040: public class MultiStatisticPanel extends XContainer implements Poller {
041: protected ConnectionContext m_cc;
042: protected JFreeChart[] m_charts;
043: protected TimeSeries[] m_timeSeries;
044: protected SplitPane m_splitter;
045: protected Button m_controlsButton;
046: protected Icon m_showIcon;
047: protected Icon m_hideIcon;
048: protected Button m_startButton;
049: protected Button m_stopButton;
050: protected Button m_clearButton;
051: protected Spinner m_periodSpinner;
052: protected Spinner m_historySpinner;
053: protected Timer m_timer;
054: protected int m_pollPeriod;
055: protected ObjectName m_bean;
056: protected String[] m_statisticNames;
057: protected Statistic[] m_statistics;
058: protected boolean m_shouldAutoStart;
059:
060: private static final int DEFAULT_POLL_PERIOD = 1000;
061: private static final int DEFAULT_HISTORY_COUNT = 30;
062:
063: private static final String SHOW_ICON_URI = "/com/tc/admin/icons/view_menu.gif";
064: private static final String HIDE_ICON_URI = "/com/tc/admin/icons/hide_menu.gif";
065:
066: public MultiStatisticPanel(ConnectionContext cc, ObjectName bean,
067: String[] stats, String[] labels, String header,
068: String xAxis, String yAxis, int orientation) {
069: super ();
070:
071: m_shouldAutoStart = true;
072:
073: AdminClientContext cntx = AdminClient.getContext();
074:
075: load((ContainerResource) cntx.topRes
076: .getComponent("StatisticPanel"));
077:
078: Container chartHolder = (Container) findComponent("ChartHolder");
079: int rows = 1, cols = stats.length;
080: if (orientation == SwingConstants.VERTICAL) {
081: rows = stats.length;
082: cols = 1;
083: }
084: chartHolder.setLayout(new GridLayout(rows, cols));
085:
086: m_bean = bean;
087: m_statisticNames = stats;
088: m_timeSeries = new TimeSeries[stats.length];
089: m_charts = new JFreeChart[stats.length];
090:
091: for (int i = 0; i < stats.length; i++) {
092: m_timeSeries[i] = new TimeSeries(labels[i], Second.class);
093: m_timeSeries[i].setMaximumItemCount(DEFAULT_HISTORY_COUNT);
094: }
095:
096: m_startButton = (Button) findComponent("StartButton");
097: m_startButton.addActionListener(new ActionListener() {
098: public void actionPerformed(ActionEvent ae) {
099: start();
100: }
101: });
102:
103: m_stopButton = (Button) findComponent("StopButton");
104: m_stopButton.addActionListener(new ActionListener() {
105: public void actionPerformed(ActionEvent ae) {
106: stop();
107: }
108: });
109:
110: m_clearButton = (Button) findComponent("ClearButton");
111: m_clearButton.addActionListener(new ActionListener() {
112: public void actionPerformed(ActionEvent ae) {
113: clear();
114: }
115: });
116:
117: m_periodSpinner = (Spinner) findComponent("PeriodSpinner");
118: m_periodSpinner.setModel(new SpinnerNumberModel(new Integer(1),
119: new Integer(1), null, new Integer(1)));
120: m_periodSpinner.addChangeListener(new ChangeListener() {
121: public void stateChanged(ChangeEvent e) {
122: SpinnerNumberModel model = (SpinnerNumberModel) m_periodSpinner
123: .getModel();
124: Integer i = (Integer) model.getNumber();
125:
126: setPollPeriod(i.intValue() * 1000);
127: }
128: });
129:
130: m_historySpinner = (Spinner) findComponent("HistorySpinner");
131: m_historySpinner.setModel(new SpinnerNumberModel(new Integer(
132: DEFAULT_HISTORY_COUNT), new Integer(5), null,
133: new Integer(10)));
134: m_historySpinner.addChangeListener(new ChangeListener() {
135: public void stateChanged(ChangeEvent e) {
136: SpinnerNumberModel model = (SpinnerNumberModel) m_historySpinner
137: .getModel();
138: Integer i = (Integer) model.getNumber();
139:
140: for (int j = 0; j < m_timeSeries.length; j++) {
141: m_timeSeries[j].setMaximumItemCount(i.intValue());
142: ((XYPlot) m_charts[j].getPlot()).getDomainAxis()
143: .setFixedAutoRange(i.intValue() * 1000);
144: }
145: }
146: });
147:
148: for (int i = 0; i < m_charts.length; i++) {
149: m_charts[i] = getChart(m_timeSeries[i], labels[i], xAxis,
150: yAxis);
151: chartHolder.add(new ChartPanel(m_charts[i], false));
152: if (i == 0) {
153: if (orientation == SwingConstants.HORIZONTAL) {
154: yAxis = null;
155: } else {
156: xAxis = null;
157: }
158: }
159: }
160:
161: m_controlsButton = (Button) findComponent("ControlsButton");
162:
163: m_showIcon = new ImageIcon(getClass()
164: .getResource(SHOW_ICON_URI));
165: m_hideIcon = new ImageIcon(getClass()
166: .getResource(HIDE_ICON_URI));
167: m_controlsButton.setIcon(m_showIcon);
168: m_controlsButton.addActionListener(new ActionListener() {
169: public void actionPerformed(ActionEvent ae) {
170: if (m_splitter.isRightShowing()) {
171: m_splitter.hideRight();
172: m_controlsButton.setIcon(m_showIcon);
173: } else {
174: m_splitter.showRight();
175: m_controlsButton.setIcon(m_hideIcon);
176: }
177: }
178: });
179:
180: m_splitter = (SplitPane) findComponent("Splitter");
181: m_splitter.hideRight();
182:
183: m_cc = cc;
184: m_pollPeriod = DEFAULT_POLL_PERIOD;
185: m_timer = new Timer(m_pollPeriod, new TaskPerformer());
186: }
187:
188: public void setPollPeriod(int millis) {
189: m_timer.setDelay(m_pollPeriod = Math.abs(millis));
190: }
191:
192: public int getPollPeriod() {
193: return m_pollPeriod;
194: }
195:
196: private Date m_date = new Date();
197:
198: public void setStatistics(Statistic[] statistics) {
199: m_statistics = statistics;
200:
201: for (int i = 0; i < m_timeSeries.length; i++) {
202: CountStatistic countStat = (CountStatistic) statistics[i];
203: long ts = countStat.getLastSampleTime();
204: long count = countStat.getCount();
205:
206: m_date.setTime(ts);
207:
208: m_timeSeries[i].addOrUpdate(new Second(m_date), count);
209: }
210: }
211:
212: public Statistic[] getStatistics() {
213: return m_statistics;
214: }
215:
216: class TaskPerformer implements ActionListener {
217: public void actionPerformed(ActionEvent evt) {
218: if (m_cc.isConnected()) {
219: try {
220: String op = "getStatistics";
221: Object[] args = { m_statisticNames };
222: String[] types = { "[Ljava.lang.String;" };
223:
224: if (m_cc.isRegistered(m_bean)) {
225: setStatistics((Statistic[]) m_cc.invoke(m_bean,
226: op, args, types));
227: }
228: } catch (Exception e) {
229: stop();
230: }
231: } else {
232: stop();
233: }
234: }
235: }
236:
237: public JFreeChart createChart(TimeSeries series) {
238: return DemoChartFactory.getXYBarChart("", "", "", series);
239: }
240:
241: public JFreeChart getChart(TimeSeries series, String header,
242: String xAxis, String yAxis) {
243: JFreeChart chart = createChart(series);
244:
245: chart.setTitle(header);
246: chart.getXYPlot().getDomainAxis().setLabel(xAxis);
247: chart.getXYPlot().getRangeAxis().setLabel(yAxis);
248:
249: return chart;
250: }
251:
252: public boolean isRunning() {
253: return m_timer.isRunning();
254: }
255:
256: public void start() {
257: if (!isRunning()) {
258: m_timer.start();
259: m_startButton.setEnabled(false);
260: m_stopButton.setEnabled(true);
261: }
262: }
263:
264: public void stop() {
265: if (isRunning()) {
266: m_timer.stop();
267: m_startButton.setEnabled(true);
268: m_stopButton.setEnabled(false);
269: }
270: }
271:
272: public void clear() {
273: for (int i = 0; i < m_timeSeries.length; i++) {
274: m_timeSeries[i].clear();
275: }
276: }
277:
278: public void addNotify() {
279: super .addNotify();
280:
281: if (m_shouldAutoStart) {
282: start();
283: m_shouldAutoStart = false;
284: }
285: }
286:
287: public void tearDown() {
288: stop();
289:
290: super.tearDown();
291:
292: m_cc = null;
293: m_charts = null;
294: m_timeSeries = null;
295: m_startButton = null;
296: m_stopButton = null;
297: m_clearButton = null;
298: m_periodSpinner = null;
299: m_historySpinner = null;
300: m_timer = null;
301: m_bean = null;
302: m_statisticNames = null;
303: m_statistics = null;
304: }
305: }
|