-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.threadlog.ui;\r
-\r
-import gnu.trove.TLongObjectHashMap;\r
-import gnu.trove.TObjectProcedure;\r
-\r
-import java.awt.BorderLayout;\r
-import java.awt.event.ActionEvent;\r
-import java.awt.event.KeyEvent;\r
-import java.io.IOException;\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-\r
-import javax.swing.AbstractAction;\r
-import javax.swing.JButton;\r
-import javax.swing.JFileChooser;\r
-import javax.swing.JFrame;\r
-import javax.swing.JToolBar;\r
-import javax.swing.filechooser.FileNameExtensionFilter;\r
-\r
-import org.simantics.threadlog.Task;\r
-import org.simantics.threadlog.ThreadLog;\r
-\r
-public class ThreadLogVisualizer extends JFrame {\r
-\r
- private static final long serialVersionUID = 6250996509358338304L;\r
- \r
- TimeLineViewer viewer = new TimeLineViewer();\r
- JToolBar toolbar = new JToolBar("Thread Log Visualizer Tools");\r
- JButton saveButton = new JButton(new SaveAction());\r
-\r
- ThreadLog currentLog;\r
-\r
- public ThreadLogVisualizer() {\r
- super("Thread log visualizer");\r
- setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);\r
- setSize(800, 600);\r
-\r
- getContentPane().setLayout(new BorderLayout());\r
- getContentPane().add(toolbar, BorderLayout.NORTH);\r
- getContentPane().add(viewer, BorderLayout.CENTER);\r
-\r
- toolbar.add(saveButton);\r
- }\r
-\r
- class SaveAction extends AbstractAction {\r
- private static final long serialVersionUID = 1L;\r
-\r
- public SaveAction() {\r
- super("Save");\r
- putValue(SHORT_DESCRIPTION, "Save the Current Log");\r
- putValue(MNEMONIC_KEY, KeyEvent.VK_S);\r
- }\r
-\r
- @Override\r
- public void actionPerformed(ActionEvent e) {\r
- JFileChooser chooser = new JFileChooser();\r
- FileNameExtensionFilter filter = new FileNameExtensionFilter(\r
- "Thread Logs (*.tlog)", "tlog", "tlog");\r
- chooser.setFileFilter(filter);\r
- int returnVal = chooser.showSaveDialog(ThreadLogVisualizer.this);\r
- if (returnVal != JFileChooser.APPROVE_OPTION)\r
- return;\r
-\r
- try {\r
- currentLog.serialize(chooser.getSelectedFile());\r
- } catch (IOException ex) {\r
- ex.printStackTrace();\r
- }\r
- }\r
- }\r
-\r
- public void setLog(ThreadLog log) {\r
- this.currentLog = log;\r
-\r
- String[] tasks = log.getTasks();\r
- double[] times = log.getTimes();\r
-\r
- // Relativize to the first task\r
- double minTime = Double.POSITIVE_INFINITY;\r
- double maxTime = Double.NEGATIVE_INFINITY;\r
-\r
- for(int i=0;i<times.length;i+=2) {\r
- double temp = times[i];\r
- if(temp < minTime)\r
- minTime = temp;\r
-\r
- temp = times[i+1];\r
- if(temp > maxTime)\r
- maxTime = temp;\r
- }\r
- for(int i=0;i<times.length;++i)\r
- times[i] -= minTime;\r
- maxTime -= minTime;\r
-\r
- // Group intervals by thread\r
- TLongObjectHashMap<ArrayList<Interval>> intervals = new TLongObjectHashMap<ArrayList<Interval>>();\r
- long[] threads = log.getThreads();\r
- for(int i=0;i<tasks.length;++i) {\r
- long thread = threads[i];\r
- ArrayList<Interval> in = intervals.get(thread);\r
- if(in == null) {\r
- in = new ArrayList<Interval>();\r
- intervals.put(thread, in);\r
- }\r
- in.add(new Interval(tasks[i], times[i*2], times[i*2+1]));\r
- }\r
-\r
- // Create lanes\r
- viewer.clear();\r
- intervals.forEachValue(new TObjectProcedure<ArrayList<Interval>>() {\r
-\r
- @Override\r
- public boolean execute(ArrayList<Interval> intervals) {\r
- Collections.sort(intervals);\r
- ArrayList<Lane> lanes = new ArrayList<Lane>();\r
-\r
- int curLaneId = -1;\r
- Lane curLane = null;\r
- for(Interval in : intervals) {\r
- if(curLane == null || in.begin < curLane.getEnd()) {\r
- ++curLaneId;\r
- if(curLaneId < lanes.size())\r
- curLane = lanes.get(curLaneId);\r
- else {\r
- curLane = new Lane();\r
- lanes.add(curLane);\r
- }\r
- }\r
- else {\r
- while(curLaneId > 0) {\r
- Lane prevLane = lanes.get(curLaneId-1);\r
- if(prevLane.getEnd() > in.begin)\r
- break;\r
- --curLaneId;\r
- curLane = prevLane;\r
- }\r
- }\r
- curLane.addInterval(in);\r
- }\r
-\r
- for(Lane lane : lanes)\r
- viewer.addLane(lane);\r
- return true;\r
- }\r
-\r
- });\r
-\r
- // update viewer\r
- viewer.repaint();\r
- }\r
-\r
- public void saveImage() {\r
-\r
- }\r
-\r
- public static void main(String[] args) throws Exception {\r
- ThreadLog.setDefaultThreadLog(new ThreadLog());\r
-\r
- {\r
- Task A = ThreadLog.BEGIN("A");\r
- Thread.sleep(200);\r
- Task B = ThreadLog.BEGIN("B");\r
- Thread.sleep(100);\r
- B.end();\r
- Thread.sleep(100);\r
- Task C = ThreadLog.BEGIN("C");\r
- Thread.sleep(100);\r
- C.end();\r
- A.end();\r
- }\r
-\r
- ThreadLogVisualizer vis = new ThreadLogVisualizer();\r
- vis.setLog(ThreadLog.setDefaultThreadLog(null));\r
- vis.setVisible(true);\r
- }\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.threadlog.ui;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JToolBar;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import org.simantics.threadlog.Task;
+import org.simantics.threadlog.ThreadLog;
+
+import gnu.trove.map.hash.TLongObjectHashMap;
+import gnu.trove.procedure.TObjectProcedure;
+
+public class ThreadLogVisualizer extends JFrame {
+
+ private static final long serialVersionUID = 6250996509358338304L;
+
+ TimeLineViewer viewer = new TimeLineViewer();
+ JToolBar toolbar = new JToolBar("Thread Log Visualizer Tools");
+ JButton saveButton = new JButton(new SaveAction());
+
+ ThreadLog currentLog;
+
+ public ThreadLogVisualizer() {
+ super("Thread log visualizer");
+ setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ setSize(800, 600);
+
+ getContentPane().setLayout(new BorderLayout());
+ getContentPane().add(toolbar, BorderLayout.NORTH);
+ getContentPane().add(viewer, BorderLayout.CENTER);
+
+ toolbar.add(saveButton);
+ }
+
+ class SaveAction extends AbstractAction {
+ private static final long serialVersionUID = 1L;
+
+ public SaveAction() {
+ super("Save");
+ putValue(SHORT_DESCRIPTION, "Save the Current Log");
+ putValue(MNEMONIC_KEY, KeyEvent.VK_S);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JFileChooser chooser = new JFileChooser();
+ FileNameExtensionFilter filter = new FileNameExtensionFilter(
+ "Thread Logs (*.tlog)", "tlog", "tlog");
+ chooser.setFileFilter(filter);
+ int returnVal = chooser.showSaveDialog(ThreadLogVisualizer.this);
+ if (returnVal != JFileChooser.APPROVE_OPTION)
+ return;
+
+ try {
+ currentLog.serialize(chooser.getSelectedFile());
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ public void setLog(ThreadLog log) {
+ this.currentLog = log;
+
+ String[] tasks = log.getTasks();
+ double[] times = log.getTimes();
+
+ // Relativize to the first task
+ double minTime = Double.POSITIVE_INFINITY;
+ double maxTime = Double.NEGATIVE_INFINITY;
+
+ for(int i=0;i<times.length;i+=2) {
+ double temp = times[i];
+ if(temp < minTime)
+ minTime = temp;
+
+ temp = times[i+1];
+ if(temp > maxTime)
+ maxTime = temp;
+ }
+ for(int i=0;i<times.length;++i)
+ times[i] -= minTime;
+ maxTime -= minTime;
+
+ // Group intervals by thread
+ TLongObjectHashMap<ArrayList<Interval>> intervals = new TLongObjectHashMap<ArrayList<Interval>>();
+ long[] threads = log.getThreads();
+ for(int i=0;i<tasks.length;++i) {
+ long thread = threads[i];
+ ArrayList<Interval> in = intervals.get(thread);
+ if(in == null) {
+ in = new ArrayList<Interval>();
+ intervals.put(thread, in);
+ }
+ in.add(new Interval(tasks[i], times[i*2], times[i*2+1]));
+ }
+
+ // Create lanes
+ viewer.clear();
+ intervals.forEachValue(new TObjectProcedure<ArrayList<Interval>>() {
+
+ @Override
+ public boolean execute(ArrayList<Interval> intervals) {
+ Collections.sort(intervals);
+ ArrayList<Lane> lanes = new ArrayList<Lane>();
+
+ int curLaneId = -1;
+ Lane curLane = null;
+ for(Interval in : intervals) {
+ if(curLane == null || in.begin < curLane.getEnd()) {
+ ++curLaneId;
+ if(curLaneId < lanes.size())
+ curLane = lanes.get(curLaneId);
+ else {
+ curLane = new Lane();
+ lanes.add(curLane);
+ }
+ }
+ else {
+ while(curLaneId > 0) {
+ Lane prevLane = lanes.get(curLaneId-1);
+ if(prevLane.getEnd() > in.begin)
+ break;
+ --curLaneId;
+ curLane = prevLane;
+ }
+ }
+ curLane.addInterval(in);
+ }
+
+ for(Lane lane : lanes)
+ viewer.addLane(lane);
+ return true;
+ }
+
+ });
+
+ // update viewer
+ viewer.repaint();
+ }
+
+ public void saveImage() {
+
+ }
+
+ public static void main(String[] args) throws Exception {
+ ThreadLog.setDefaultThreadLog(new ThreadLog());
+
+ {
+ Task A = ThreadLog.BEGIN("A");
+ Thread.sleep(200);
+ Task B = ThreadLog.BEGIN("B");
+ Thread.sleep(100);
+ B.end();
+ Thread.sleep(100);
+ Task C = ThreadLog.BEGIN("C");
+ Thread.sleep(100);
+ C.end();
+ A.end();
+ }
+
+ ThreadLogVisualizer vis = new ThreadLogVisualizer();
+ vis.setLog(ThreadLog.setDefaultThreadLog(null));
+ vis.setVisible(true);
+ }
+}