-/*******************************************************************************\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 java.awt.Color;\r
-import java.awt.Dimension;\r
-import java.awt.Graphics;\r
-import java.awt.Graphics2D;\r
-import java.awt.Shape;\r
-import java.awt.event.MouseAdapter;\r
-import java.awt.event.MouseEvent;\r
-import java.awt.event.MouseMotionAdapter;\r
-import java.awt.event.MouseWheelEvent;\r
-import java.awt.event.MouseWheelListener;\r
-import java.awt.geom.Rectangle2D;\r
-import java.awt.geom.RoundRectangle2D;\r
-import java.text.DecimalFormat;\r
-import java.text.Format;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.Timer;\r
-import java.util.TimerTask;\r
-\r
-import javax.swing.JPanel;\r
-\r
-public class TimeLineViewer extends JPanel {\r
-\r
- private static final long serialVersionUID = -7410066541298449720L;\r
- \r
- public static long TOOL_TIP_DELAY = 500;\r
- public static double MIN_GRID_LINE_SEPARATION = 15;\r
- \r
- // Time line data\r
- List<Lane> lanes = new ArrayList<Lane>();\r
- \r
- // For panning and zooming\r
- double xScale = 100.0;\r
- double xOffset = 0.0;\r
- double yOffset = 0.0;\r
- int oldX;\r
- int oldY;\r
- \r
- // Tool tips\r
- Timer toolTipTimer = new Timer();\r
- class ToolTipTask extends TimerTask {\r
-\r
- @Override\r
- public void run() {\r
- System.out.println("show tooltip"); \r
- }\r
- \r
- }\r
- \r
- public TimeLineViewer() {\r
- addMouseListener(new MouseAdapter() {\r
- @Override\r
- public void mousePressed(MouseEvent e) {\r
- oldX = e.getX();\r
- oldY = e.getY();\r
- }\r
- });\r
- addMouseMotionListener(new MouseMotionAdapter() { \r
- @Override\r
- public void mouseDragged(MouseEvent e) {\r
- int curX = e.getX();\r
- int curY = e.getY();\r
- int diffX = curX - oldX;\r
- int diffY = curY - oldY;\r
- oldX = curX;\r
- oldY = curY;\r
- \r
- xOffset -= diffX/xScale;\r
- yOffset -= diffY;\r
- repaint();\r
- }\r
- TimerTask toolTipTask;\r
- @Override\r
- public void mouseMoved(MouseEvent e) {\r
- if(toolTipTask != null)\r
- toolTipTask.cancel();\r
- toolTipTask = new ToolTipTask();\r
- toolTipTimer.schedule(toolTipTask, TOOL_TIP_DELAY);\r
- }\r
- });\r
- addMouseWheelListener(new MouseWheelListener() { \r
- @Override\r
- public void mouseWheelMoved(MouseWheelEvent e) {\r
- xOffset += e.getX() / xScale;\r
- xScale *= Math.pow(1.25, -e.getWheelRotation());\r
- xOffset -= e.getX() / xScale;\r
- repaint();\r
- }\r
- });\r
- }\r
- \r
- public void addLane(Lane lane) {\r
- lanes.add(lane);\r
- }\r
- \r
- public void clear() {\r
- lanes.clear();\r
- }\r
- \r
- public void paintIntervals(Graphics2D g) { \r
- for(int laneId=0;laneId < lanes.size();++laneId) {\r
- Lane lane = lanes.get(laneId);\r
- \r
- double y = 35.0*laneId - yOffset;\r
- double height = 30.0;\r
- \r
- for(Interval interval : lane.intervals) {\r
- double x = (interval.begin - xOffset) * xScale; \r
- double width = (interval.end - interval.begin) * xScale;\r
- \r
- Shape shape = new RoundRectangle2D.Double(x, y, width, height, 10.0, 10.0);\r
- g.setColor(Color.WHITE);\r
- g.fill(shape);\r
- g.setColor(Color.BLACK);\r
- g.draw(shape);\r
- \r
- Rectangle2D bounds = g.getFontMetrics().getStringBounds(interval.text, g);\r
- if(bounds.getWidth() < width)\r
- g.drawString(interval.text, (float)(x+0.5*(width-bounds.getWidth())), (float)(y+20.0));\r
- }\r
- }\r
- }\r
- \r
- public void paintGrid(Graphics2D g) {\r
- Dimension dim = getSize();\r
- \r
- g.setBackground(Color.WHITE);\r
- g.clearRect(0, 0, dim.width, dim.height);\r
- \r
- double stepsize = 0.001;\r
- double majorStepsize;\r
- while(true) {\r
- majorStepsize = stepsize * 5.0;\r
- if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION)\r
- break;\r
- stepsize = majorStepsize;\r
- majorStepsize = stepsize * 2.0;\r
- if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION)\r
- break;\r
- stepsize = majorStepsize;\r
- }\r
- \r
- double firstP = Math.ceil(xOffset / stepsize) * stepsize;\r
- double lastP = Math.floor((xOffset + dim.width / xScale) / stepsize) * stepsize;\r
- if(firstP < 0.0)\r
- firstP = 0.0;\r
-\r
- Format format = new DecimalFormat();\r
- for(double p = firstP;p <= lastP; p+=stepsize) {\r
- int x = (int)((p - xOffset) * xScale);\r
- if(Math.abs(p/majorStepsize - Math.round(p/majorStepsize)) < 1e-3) {\r
- g.setColor(Color.BLACK);\r
- String text = format.format(p);\r
- Rectangle2D bounds = g.getFontMetrics().getStringBounds(text, g);\r
- g.drawString(text, (float)(x-bounds.getWidth()*0.5), 12.0f); \r
- }\r
- else\r
- g.setColor(Color.LIGHT_GRAY);\r
- g.drawLine(x, 14, x, (int)dim.getHeight());\r
- }\r
- }\r
- \r
- @Override\r
- public void paint(Graphics _g) {\r
- Graphics2D g = (Graphics2D)_g; \r
- \r
- paintGrid(g);\r
- paintIntervals(g);\r
- }\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.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import java.text.DecimalFormat;
+import java.text.Format;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import javax.swing.JPanel;
+
+public class TimeLineViewer extends JPanel {
+
+ private static final long serialVersionUID = -7410066541298449720L;
+
+ public static long TOOL_TIP_DELAY = 500;
+ public static double MIN_GRID_LINE_SEPARATION = 15;
+
+ // Time line data
+ List<Lane> lanes = new ArrayList<Lane>();
+
+ // For panning and zooming
+ double xScale = 100.0;
+ double xOffset = 0.0;
+ double yOffset = 0.0;
+ int oldX;
+ int oldY;
+
+ // Tool tips
+ Timer toolTipTimer = new Timer();
+ class ToolTipTask extends TimerTask {
+
+ @Override
+ public void run() {
+ System.out.println("show tooltip");
+ }
+
+ }
+
+ public TimeLineViewer() {
+ addMouseListener(new MouseAdapter() {
+ @Override
+ public void mousePressed(MouseEvent e) {
+ oldX = e.getX();
+ oldY = e.getY();
+ }
+ });
+ addMouseMotionListener(new MouseMotionAdapter() {
+ @Override
+ public void mouseDragged(MouseEvent e) {
+ int curX = e.getX();
+ int curY = e.getY();
+ int diffX = curX - oldX;
+ int diffY = curY - oldY;
+ oldX = curX;
+ oldY = curY;
+
+ xOffset -= diffX/xScale;
+ yOffset -= diffY;
+ repaint();
+ }
+ TimerTask toolTipTask;
+ @Override
+ public void mouseMoved(MouseEvent e) {
+ if(toolTipTask != null)
+ toolTipTask.cancel();
+ toolTipTask = new ToolTipTask();
+ toolTipTimer.schedule(toolTipTask, TOOL_TIP_DELAY);
+ }
+ });
+ addMouseWheelListener(new MouseWheelListener() {
+ @Override
+ public void mouseWheelMoved(MouseWheelEvent e) {
+ xOffset += e.getX() / xScale;
+ xScale *= Math.pow(1.25, -e.getWheelRotation());
+ xOffset -= e.getX() / xScale;
+ repaint();
+ }
+ });
+ }
+
+ public void addLane(Lane lane) {
+ lanes.add(lane);
+ }
+
+ public void clear() {
+ lanes.clear();
+ }
+
+ public void paintIntervals(Graphics2D g) {
+ for(int laneId=0;laneId < lanes.size();++laneId) {
+ Lane lane = lanes.get(laneId);
+
+ double y = 35.0*laneId - yOffset;
+ double height = 30.0;
+
+ for(Interval interval : lane.intervals) {
+ double x = (interval.begin - xOffset) * xScale;
+ double width = (interval.end - interval.begin) * xScale;
+
+ Shape shape = new RoundRectangle2D.Double(x, y, width, height, 10.0, 10.0);
+ g.setColor(Color.WHITE);
+ g.fill(shape);
+ g.setColor(Color.BLACK);
+ g.draw(shape);
+
+ Rectangle2D bounds = g.getFontMetrics().getStringBounds(interval.text, g);
+ if(bounds.getWidth() < width)
+ g.drawString(interval.text, (float)(x+0.5*(width-bounds.getWidth())), (float)(y+20.0));
+ }
+ }
+ }
+
+ public void paintGrid(Graphics2D g) {
+ Dimension dim = getSize();
+
+ g.setBackground(Color.WHITE);
+ g.clearRect(0, 0, dim.width, dim.height);
+
+ double stepsize = 0.001;
+ double majorStepsize;
+ while(true) {
+ majorStepsize = stepsize * 5.0;
+ if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION)
+ break;
+ stepsize = majorStepsize;
+ majorStepsize = stepsize * 2.0;
+ if(stepsize * xScale >= MIN_GRID_LINE_SEPARATION)
+ break;
+ stepsize = majorStepsize;
+ }
+
+ double firstP = Math.ceil(xOffset / stepsize) * stepsize;
+ double lastP = Math.floor((xOffset + dim.width / xScale) / stepsize) * stepsize;
+ if(firstP < 0.0)
+ firstP = 0.0;
+
+ Format format = new DecimalFormat();
+ for(double p = firstP;p <= lastP; p+=stepsize) {
+ int x = (int)((p - xOffset) * xScale);
+ if(Math.abs(p/majorStepsize - Math.round(p/majorStepsize)) < 1e-3) {
+ g.setColor(Color.BLACK);
+ String text = format.format(p);
+ Rectangle2D bounds = g.getFontMetrics().getStringBounds(text, g);
+ g.drawString(text, (float)(x-bounds.getWidth()*0.5), 12.0f);
+ }
+ else
+ g.setColor(Color.LIGHT_GRAY);
+ g.drawLine(x, 14, x, (int)dim.getHeight());
+ }
+ }
+
+ @Override
+ public void paint(Graphics _g) {
+ Graphics2D g = (Graphics2D)_g;
+
+ paintGrid(g);
+ paintIntervals(g);
+ }
+
+}