]> gitweb.hamatoma.de Git - robosim/commitdiff
Text widget, status line master
authorhama <hama@siduction.net>
Sat, 8 Nov 2014 07:48:18 +0000 (08:48 +0100)
committerhama <hama@siduction.net>
Sat, 8 Nov 2014 07:48:18 +0000 (08:48 +0100)
src/jlection/robotic/RobotModel.java
src/jlecture/simulation/Alignment.java [new file with mode: 0644]
src/jlecture/simulation/ISheet.java
src/jlecture/simulation/ITextWidget.java [new file with mode: 0644]
src/jlecture/simulation/Model.java
src/jlecture/simulation/WidgetType.java
src/jlecture/swing/PanelSwing.java
src/jlecture/swing/SheetSwing.java
src/jlecture/swing/TextSwing.java [new file with mode: 0644]

index 6968c5504d0e41f8f14e412911a26cb598317eb7..14bbc0c102da5aa156e704140c5c91f1341de1c2 100644 (file)
@@ -38,9 +38,10 @@ public class RobotModel extends Model {
     public void createModel() {
         final int count = 1000;
         final int width = 3;
     public void createModel() {
         final int count = 1000;
         final int width = 3;
+        addStatusSegment(this.positionStep, "");
+
         Barrier barrier = new Barrier(this.sheet.createRectangle(new PointRW(
         Barrier barrier = new Barrier(this.sheet.createRectangle(new PointRW(
-            500,
-            100), new DimensionRW(600, 100), false, this));
+            500, 100), new DimensionRW(600, 100), false, this));
         barrier.getWidget().setColorBackground(Color.gray);
         this.things.add(barrier);
         barrier = new Barrier(this.sheet.createRectangle(new PointRW(500, 400),
         barrier.getWidget().setColorBackground(Color.gray);
         this.things.add(barrier);
         barrier = new Barrier(this.sheet.createRectangle(new PointRW(500, 400),
diff --git a/src/jlecture/simulation/Alignment.java b/src/jlecture/simulation/Alignment.java
new file mode 100644 (file)
index 0000000..2f57405
--- /dev/null
@@ -0,0 +1,14 @@
+/**
+ *
+ */
+package jlecture.simulation;
+
+/**
+ * Defines some names for horizontal and vertical alignment.
+ *
+ * @author hm
+ *
+ */
+public enum Alignment {
+    UNDEF, LEFT, RIGHT, CENTER, TOP, MIDDLE, BOTTOM
+}
index ed8232caf2cd60e4bfba0abb56e9f50dd535f9eb..7e3336cb7d2060c9400d3bd32e40e08606ea6b1e 100644 (file)
@@ -24,9 +24,28 @@ public interface ISheet {
      *            the simulator model
      * @return a X cross widget
      */
      *            the simulator model
      * @return a X cross widget
      */
-    IWidget createRectangle(PointRW center, DimensionRW dimension,
+    public IWidget createRectangle(PointRW center, DimensionRW dimension,
         boolean filled, Model model);
 
         boolean filled, Model model);
 
+    /**
+     * Creates a piece of text.
+     *
+     * @param text
+     *            the text to show
+     * @param size
+     *            the font size (in dots)
+     * @param center
+     *            the position of the text. See the following alignments
+     * @param horizontalAlignment
+     *            LEFT: the text is left of the center...
+     * @param verticalAlignment
+     *            TOP: the text is on the center
+     * @return the created text
+     */
+    public IWidget createText(final String text, final int size,
+        final PointRW center, final Alignment horizontalAlignment,
+        final Alignment verticalAlignment);
+
     /**
      * Creates a X cross widget.
      *
     /**
      * Creates a X cross widget.
      *
@@ -38,7 +57,8 @@ public interface ISheet {
      *            the simulator model
      * @return a X cross widget
      */
      *            the simulator model
      * @return a X cross widget
      */
-    IWidget createXCross(PointRW center, DimensionRW dimension, Model model);
+    public IWidget createXCross(PointRW center, DimensionRW dimension,
+        Model model);
 
     /**
      * Returns the width and height of the sheet.
 
     /**
      * Returns the width and height of the sheet.
diff --git a/src/jlecture/simulation/ITextWidget.java b/src/jlecture/simulation/ITextWidget.java
new file mode 100644 (file)
index 0000000..86199aa
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ *
+ */
+package jlecture.simulation;
+
+/**
+ * Defines a text widget.
+ *
+ * @author hm
+ *
+ */
+public interface ITextWidget extends IWidget {
+    /**
+     * Returns the text of the widget.
+     *
+     * @return the current text
+     */
+    String getText();
+
+    /**
+     * Sets the text of the widget.
+     *
+     * @param text
+     *            the new text
+     */
+    void setText(String text);
+}
index f50a862027371931f144954242a7edeb285100c1..4acf834bf66e43f874681e596b755fda23a8fa34 100644 (file)
@@ -3,9 +3,12 @@
  */
 package jlecture.simulation;
 
  */
 package jlecture.simulation;
 
+import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Dimension;
+import java.awt.Point;
 import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.awt.Rectangle;
 import java.util.ArrayList;
+import java.util.Hashtable;
 import java.util.List;
 import java.util.Random;
 
 import java.util.List;
 import java.util.Random;
 
@@ -66,6 +69,40 @@ public abstract class Model {
      * Counts the number of collisions inside <code>openPosition()</code>.
      */
     public int openPositionCollisions = 0;
      * Counts the number of collisions inside <code>openPosition()</code>.
      */
     public int openPositionCollisions = 0;
+    /**
+     * current number of the simulation step.
+     */
+    protected int step = 0;
+    /**
+     * The position of the status line segment displaying the step (in % of the
+     * width)
+     */
+    protected Double positionStep = 0.0;
+
+    /**
+     * Text color of a normal text in the status line.
+     */
+    protected Color colorStatusNormal = Color.black;
+
+    /**
+     * Text color of a warning in the status line.
+     */
+    protected Color colorStatusWarning = Color.cyan;
+
+    /**
+     * Text color of an error message in the status line.
+     */
+    protected Color colorStatusError = Color.red;
+
+    /**
+     * The start time of the simulation (in millisec from 1.1.1970)
+     */
+    private long startTime = 0;
+
+    /**
+     * The status line segments. Allows to change texts.
+     */
+    private final Hashtable<Double, IWidget> statusSegments = new Hashtable<Double, IWidget>();
 
     /**
      * Constructor.
 
     /**
      * Constructor.
@@ -77,6 +114,26 @@ public abstract class Model {
         this.region = region;
     }
 
         this.region = region;
     }
 
+    /**
+     * Shows a text in the status line
+     *
+     * @param xRelative
+     *            start position in % from the width
+     * @param text
+     *            text to display
+     */
+    public void addStatusSegment(final Double xRelative, final String text) {
+
+        final double x = this.region.x + xRelative / 100.0 * this.region.width;
+        final double y = -this.region.height / 100.0 * 2;
+
+        if (this.statusSegments.contains(xRelative))
+            log(String.format("status segment already exists: %.0f", xRelative));
+        else
+            this.statusSegments.put(xRelative, this.sheet.createText(text, 12,
+                new PointRW(x, y), Alignment.LEFT, Alignment.TOP));
+    }
+
     /**
      * Checks whether a given object collides with one of the other simulated
      * objects.
     /**
      * Checks whether a given object collides with one of the other simulated
      * objects.
@@ -179,8 +236,8 @@ public abstract class Model {
             if (current != exclude) {
                 final RectangleRW contour = current.widget.getContour();
                 if (point.x >= contour.x && point.y >= contour.y
             if (current != exclude) {
                 final RectangleRW contour = current.widget.getContour();
                 if (point.x >= contour.x && point.y >= contour.y
-                        && point.x < contour.x + contour.width
-                        && point.y < contour.y + contour.height) {
+                    && point.x < contour.x + contour.width
+                    && point.y < contour.y + contour.height) {
                     rc = current;
                     break;
                 }
                     rc = current;
                     break;
                 }
@@ -200,7 +257,7 @@ public abstract class Model {
             count++;
             rc.x = this.region.x + this.random.nextDouble() * this.region.width;
             rc.y = this.region.x + this.random.nextDouble()
             count++;
             rc.x = this.region.x + this.random.nextDouble() * this.region.width;
             rc.y = this.region.x + this.random.nextDouble()
-                    * this.region.height;
+                * this.region.height;
         } while (occupied(rc, null) != null);
         this.openPositionCollisions += count - 1;
         return rc;
         } while (occupied(rc, null) != null);
         this.openPositionCollisions += count - 1;
         return rc;
@@ -239,6 +296,28 @@ public abstract class Model {
         this.sheet = sheet;
     }
 
         this.sheet = sheet;
     }
 
+    /**
+     * Change the text of a status line segment.
+     *
+     * @param xRelative
+     *            identifier of the segment (start position in % of the width)
+     * @param text
+     *            the new text
+     * @param color
+     *            the new color
+     */
+    public void setStatusSegmentText(final Double xRelative, final String text,
+        final Color color) {
+        final IWidget widget = this.statusSegments.get(xRelative);
+        if (widget == null)
+            log(String.format("status segment does not exist: %.0f", xRelative));
+        else {
+            final ITextWidget textWidget = (ITextWidget) widget;
+            textWidget.setText(text);
+            textWidget.setColor(color);
+        }
+    }
+
     /**
      * Executes one simulation step.
      *
     /**
      * Executes one simulation step.
      *
@@ -254,6 +333,14 @@ public abstract class Model {
     public void simulationStep() {
         if (this.isReady) {
             this.now = System.currentTimeMillis();
     public void simulationStep() {
         if (this.isReady) {
             this.now = System.currentTimeMillis();
+            if (this.step++ == 0)
+                this.startTime = this.now;
+            else if (this.step % 5 == 0) {
+                final long duration = (this.now - this.startTime) / 1000L;
+                setStatusSegmentText(this.positionStep, String.format(
+                    "step %d time: %d sec (%.1f/sec)", this.step, duration,
+                    (double) this.step / duration), this.colorStatusNormal);
+            }
             // do the moves
             for (int ix = this.firstIndexMovables; ix < this.things.size(); ix++) {
                 final ThingRW thing = this.things.get(ix);
             // do the moves
             for (int ix = this.firstIndexMovables; ix < this.things.size(); ix++) {
                 final ThingRW thing = this.things.get(ix);
@@ -290,6 +377,29 @@ public abstract class Model {
         }
     }
 
         }
     }
 
+    /**
+     * Transforms a real world point to a pixel point.
+     *
+     * <pre>
+     * deltaX = x - xMin
+     * wRW / wPx = deltaXRW / deltaXPx =&gt; deltaPx = deltaXRW * wPx / wRW
+     * xPx = xMinPx + deltaXPx, xMinPx = 0
+     * xPx = deltaPx = deltaXRW * wPx / wRW
+     * xPx = (xRW - xMinRW) * (xMaxRW - xMinRW) / xMaxPx
+     * </pre>
+     *
+     * @param pointRW
+     *            the point to convert
+     * @param point
+     *            OUT: the calculated point
+     */
+    public void transform(final PointRW pointRW, final Point point) {
+        final Dimension dimension = this.sheet.getDimension();
+        point.x = (int) ((pointRW.x - this.region.x) * this.region.width / dimension.width);
+        point.y = dimension.height
+            - (int) ((pointRW.y - this.region.y) * this.region.height / dimension.height);
+    }
+
     /**
      * Transforms a real world rectangle to a native rectangle.
      *
     /**
      * Transforms a real world rectangle to a native rectangle.
      *
@@ -311,9 +421,9 @@ public abstract class Model {
         final Dimension dimension = this.sheet.getDimension();
 
         rectangle.x = (int) ((rectangleRW.x - this.region.x)
         final Dimension dimension = this.sheet.getDimension();
 
         rectangle.x = (int) ((rectangleRW.x - this.region.x)
-                * this.region.width / dimension.width);
-        rectangle.y = (int) ((rectangleRW.y - this.region.y)
-                * this.region.height / dimension.height);
+            * this.region.width / dimension.width);
+        rectangle.y = dimension.height
+            - (int) ((rectangleRW.y - this.region.y) * this.region.height / dimension.height);
         rectangle.width = (int) (rectangleRW.width * dimension.width / this.region.width);
         rectangle.height = (int) (rectangleRW.height * dimension.height / this.region.height);
     }
         rectangle.width = (int) (rectangleRW.width * dimension.width / this.region.width);
         rectangle.height = (int) (rectangleRW.height * dimension.height / this.region.height);
     }
index 7aa0d2b2d5c6c9d4becc0316203b88bd434a446d..8e3e7a33c3238736079f1f27b1649f6c5e69dd8e 100644 (file)
@@ -10,5 +10,5 @@ package jlecture.simulation;
  *
  */
 public enum WidgetType {
  *
  */
 public enum WidgetType {
-    UNDEF, RECTANGLE, XCROSS, LINE, POINT
+    UNDEF, RECTANGLE, XCROSS, LINE, POINT, TEXT
 }
 }
index f3509403aac89a8f40c40567df3aecff0c4dbe5a..3f94f2fcdf0b0d181e7621ec41911b55c524f7ce 100644 (file)
@@ -35,7 +35,7 @@ class PanelSwing extends JPanel {
      * @param model
      *            the simulator model
      */
      * @param model
      *            the simulator model
      */
-    public PanelSwing(Model model) {
+    public PanelSwing(final Model model) {
         this.model = model;
     }
 
         this.model = model;
     }
 
@@ -45,12 +45,11 @@ class PanelSwing extends JPanel {
      * @param graphics
      *            the drawing parameter like pencil
      */
      * @param graphics
      *            the drawing parameter like pencil
      */
-    private void doDrawing(Graphics graphics) {
+    private void doDrawing(final Graphics graphics) {
         final Graphics2D g2d = (Graphics2D) graphics;
 
         g2d.setColor(this.foreground);
         g2d.setBackground(this.background);
         final Graphics2D g2d = (Graphics2D) graphics;
 
         g2d.setColor(this.foreground);
         g2d.setBackground(this.background);
-
         for (final IWidget item : this.model.getItems()) {
             final WidgetSwing item2 = (WidgetSwing) item;
             item2.draw(g2d);
         for (final IWidget item : this.model.getItems()) {
             final WidgetSwing item2 = (WidgetSwing) item;
             item2.draw(g2d);
@@ -58,7 +57,7 @@ class PanelSwing extends JPanel {
     }
 
     @Override
     }
 
     @Override
-    public void paintComponent(Graphics graphics) {
+    public void paintComponent(final Graphics graphics) {
         super.paintComponent(graphics);
         doDrawing(graphics);
     }
         super.paintComponent(graphics);
         doDrawing(graphics);
     }
index a2a89bb2ab3406ebb09435f974a50451f78ca3da..28aba6aa12dd7f6bf3924ebf31dcfd1d481d078a 100644 (file)
@@ -8,6 +8,7 @@ import java.awt.event.ActionListener;
 import javax.swing.JFrame;
 import javax.swing.Timer;
 
 import javax.swing.JFrame;
 import javax.swing.Timer;
 
+import jlecture.simulation.Alignment;
 import jlecture.simulation.DimensionRW;
 import jlecture.simulation.ISheet;
 import jlecture.simulation.IWidget;
 import jlecture.simulation.DimensionRW;
 import jlecture.simulation.ISheet;
 import jlecture.simulation.IWidget;
@@ -73,6 +74,15 @@ public class SheetSwing extends JFrame implements ISheet, ActionListener {
         return new RectangleSwing(center, dimension, filled, model);
     }
 
         return new RectangleSwing(center, dimension, filled, model);
     }
 
+    @Override
+    public IWidget createText(final String text, final int size,
+        final PointRW center, final Alignment horizontalAlignment,
+        final Alignment verticalAlignment) {
+        final TextSwing rc = new TextSwing(text, size, center,
+            horizontalAlignment, verticalAlignment, this.model);
+        return rc;
+    }
+
     @Override
     public IWidget createXCross(final PointRW center,
         final DimensionRW dimension, final Model model) {
     @Override
     public IWidget createXCross(final PointRW center,
         final DimensionRW dimension, final Model model) {
@@ -94,7 +104,7 @@ public class SheetSwing extends JFrame implements ISheet, ActionListener {
 
         add(new PanelSwing(this.model));
 
 
         add(new PanelSwing(this.model));
 
-        setSize(this.dimension.width, this.dimension.height);
+        setSize(this.dimension.width, this.dimension.height * 120 / 100);
 
         if (this.position == null)
             // build the window in the center:
 
         if (this.position == null)
             // build the window in the center:
diff --git a/src/jlecture/swing/TextSwing.java b/src/jlecture/swing/TextSwing.java
new file mode 100644 (file)
index 0000000..12d4062
--- /dev/null
@@ -0,0 +1,159 @@
+/**
+ *
+ */
+package jlecture.swing;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+
+import jlecture.simulation.Alignment;
+import jlecture.simulation.ITextWidget;
+import jlecture.simulation.Model;
+import jlecture.simulation.PointRW;
+import jlecture.simulation.WidgetType;
+
+/**
+ * @author hm
+ *
+ */
+public class TextSwing extends WidgetSwing implements ITextWidget {
+    /**
+     * font size in dots.
+     */
+    private final int size;
+    /**
+     * Text which will be shown.
+     */
+    private String text;
+    /**
+     * The width of the text in pixel.
+     */
+    private int textWidth = 0;
+    /**
+     * The height of the text in pixel.
+     */
+    private int textHeight = 0;
+    /**
+     * the text will be drawn with this font.
+     */
+    Font font = null;
+    /**
+     * Helper to calculate width and height. Will be initialized when a
+     * <code>Graphics</code> is available.
+     */
+    FontMetrics fontMetrics = null;
+    Point nativeCenter = new Point(0, 0);
+    Alignment horizontalAlignment;
+    Alignment verticalAlignment;
+
+    /**
+     * Contructor.
+     *
+     * @param text
+     *            the text to show
+     * @param size
+     *            the font size in dots
+     * @param center
+     *            the text will be centered around this point
+     * @param model
+     *            the simulation model
+     */
+    public TextSwing(final String text, final int size, final PointRW center,
+        final Alignment horizontalAlignment, final Alignment verticalAlignment,
+        final Model model) {
+        super(center, model);
+        this.size = size;
+        this.text = text;
+        this.font = new Font("Helvetica", Font.PLAIN, this.size);
+        this.horizontalAlignment = horizontalAlignment;
+        this.verticalAlignment = verticalAlignment;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see jlecture.swing.WidgetSwing#calculateContour()
+     */
+    @Override
+    protected void calculateContour() {
+        // TODO Auto-generated method stub
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see jlecture.swing.WidgetSwing#draw(java.awt.Graphics2D)
+     */
+    @Override
+    public void draw(final Graphics2D graphics) {
+        if (this.font == null) {
+            this.fontMetrics = graphics.getFontMetrics(this.font);
+            this.textWidth = this.fontMetrics.stringWidth(this.text);
+            this.textHeight = this.fontMetrics.getHeight();
+        }
+        final Color safeColor = graphics.getColor();
+        graphics.setColor(this.color);
+        this.model.transform(this.center, this.nativeCenter);
+        int x, y;
+        switch (this.horizontalAlignment) {
+        case LEFT:
+            x = this.nativeCenter.x;
+            break;
+        case RIGHT:
+            x = this.nativeCenter.x - this.textWidth;
+            break;
+        default:
+            x = this.nativeCenter.x - this.textWidth / 2;
+            break;
+        }
+        switch (this.verticalAlignment) {
+        case TOP:
+            y = this.nativeCenter.y + this.textHeight;
+            break;
+        case BOTTOM:
+            y = this.nativeCenter.y;
+            break;
+        default:
+            y = this.nativeCenter.y - this.textHeight / 2;
+            break;
+        }
+        graphics.drawString(this.text, x, y);
+        graphics.setColor(safeColor);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see jlecture.simulation.IWidget#getMaxDimension()
+     */
+    @Override
+    public double getMaxDimension() {
+        // TODO Auto-generated method stub
+        return 0;
+    }
+
+    @Override
+    public String getText() {
+        return this.text;
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see jlecture.simulation.IWidget#getWidgetType()
+     */
+    @Override
+    public WidgetType getWidgetType() {
+        return WidgetType.TEXT;
+    }
+
+    @Override
+    public void setText(final String text) {
+        this.text = text;
+
+    }
+
+}