Revision 6:7f66ae340e09

View differences:

src/main/java/cz/agents/alite/visualizer2d/Layer.java
9 9

  
10 10
    default public void deinit(VisPane<T> visPane) {}
11 11

  
12
    public void paint(VisCanvas visCanvas, Point2dAdapter<T> adapter);
12
    public void paint(VisInfo visInfo, Point2dAdapter<T> adapter);
13 13

  
14 14
}
src/main/java/cz/agents/alite/visualizer2d/VisCanvas.java
1
package cz.agents.alite.visualizer2d;
2

  
3
import java.awt.*;
4
import java.awt.geom.AffineTransform;
5
import java.awt.geom.NoninvertibleTransformException;
6
import java.awt.geom.Point2D;
7

  
8
/**
9
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
10
 */
11
public final class VisCanvas {
12

  
13
    private boolean screenTransformSet = true;
14
    private final AffineTransform worldTransform;
15
    private final AffineTransform screenTransform;
16
    private final Graphics2D canvas;
17
    private final Rectangle bounds;
18

  
19
    public VisCanvas(AffineTransform worldTransform, Graphics2D canvas, Rectangle bounds) {
20
        this.bounds = bounds;
21
        this.canvas = canvas;
22

  
23
        this.screenTransform = canvas.getTransform();
24
        this.worldTransform = new AffineTransform(screenTransform);
25
        this.worldTransform.concatenate(worldTransform);
26
    }
27

  
28
    public final Graphics2D getWorldCanvas() {
29
        if (screenTransformSet) {
30
            canvas.setTransform(worldTransform);
31
            screenTransformSet = false;
32
        }
33
        return canvas;
34
    }
35

  
36
    public final Graphics2D getScreenCanvas() {
37
        if (!screenTransformSet) {
38
            canvas.setTransform(screenTransform);
39
            screenTransformSet = true;
40
        }
41
        return canvas;
42
    }
43

  
44
    public final Rectangle getBounds() {
45
        return bounds;
46
    }
47

  
48
    public final Point2D toWorldCoordinates(Point2D screenCoordinates) {
49
        try {
50
            return worldTransform.inverseTransform(screenCoordinates, null);
51
        } catch (NoninvertibleTransformException e) {
52
            e.printStackTrace();
53
        }
54
        return null;
55
    }
56
}
src/main/java/cz/agents/alite/visualizer2d/VisInfo.java
1
package cz.agents.alite.visualizer2d;
2

  
3
import javax.vecmath.Point2d;
4
import java.awt.*;
5
import java.awt.geom.AffineTransform;
6
import java.awt.geom.NoninvertibleTransformException;
7
import java.awt.geom.Point2D;
8

  
9
/**
10
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
11
 */
12
public final class VisInfo {
13

  
14
    private boolean screenTransformSet = true;
15
    private final AffineTransform worldTransform;
16
    private final AffineTransform originalWorldTransform;
17
    private final AffineTransform screenTransform;
18
    private final Graphics2D canvas;
19
    private final Rectangle bounds;
20
    private final Point mousePosition;
21
    private final int rotationDeg;
22
    private final double zoom;
23

  
24
    public VisInfo(AffineTransform worldTransform, Graphics2D canvas, Rectangle bounds, Point mousePosition,
25
                   int rotationDeg, double zoom) {
26
        this.bounds = bounds;
27
        this.canvas = canvas;
28
        this.mousePosition = mousePosition;
29
        this.rotationDeg = rotationDeg;
30
        this.zoom = zoom;
31

  
32
        this.screenTransform = canvas.getTransform();
33
        this.worldTransform = new AffineTransform(screenTransform);
34
        this.worldTransform.concatenate(worldTransform);
35
        this.originalWorldTransform = worldTransform;
36
    }
37

  
38
    public final Graphics2D getWorldCanvas() {
39
        if (screenTransformSet) {
40
            canvas.setTransform(worldTransform);
41
            screenTransformSet = false;
42
        }
43
        return canvas;
44
    }
45

  
46
    public final Graphics2D getScreenCanvas() {
47
        if (!screenTransformSet) {
48
            canvas.setTransform(screenTransform);
49
            screenTransformSet = true;
50
        }
51
        return canvas;
52
    }
53

  
54
    public final Rectangle getBounds() {
55
        return bounds;
56
    }
57

  
58
    public final Point2D toWorldCoordinates(Point2D screenCoordinates) {
59
        try {
60
            return worldTransform.inverseTransform(screenCoordinates, null);
61
        } catch (NoninvertibleTransformException e) {
62
            e.printStackTrace();
63
        }
64
        return null;
65
    }
66

  
67
    public Point getMousePosition() {
68
        return mousePosition;
69
    }
70

  
71
    public double getZoom() {
72
        return zoom;
73
    }
74

  
75
    public Point2d getOffset() {
76
        return new Point2d(originalWorldTransform.getTranslateX(), originalWorldTransform.getTranslateY());
77
    }
78

  
79
    public int getRotationDeg() {
80
        return rotationDeg;
81
    }
82
}
src/main/java/cz/agents/alite/visualizer2d/VisPane.java
20 20
 */
21 21
public final class VisPane<T> {
22 22

  
23
    public static final int REFRESH_IN_MS = 40; //25 FPS
23
    public static final int REFRESH_IN_MS = 20; //50 FPS
24 24
    private static final ScheduledThreadPoolExecutor EXECUTOR = new ScheduledThreadPoolExecutor(1);
25 25

  
26 26
    private Layer<T> layer;
27 27
    //TODO solve volatile vs synchronized
28 28
    private volatile Point2dAdapter<T> adapter;
29
    private volatile Optional<VisCanvas> visCanvas = Optional.empty();
29
    private volatile Point mousePosition = new Point();
30
    private volatile Optional<VisInfo> visCanvas = Optional.empty();
30 31

  
31 32
    private boolean running = false;
32 33
    private ScheduledFuture<?> updateFuture;
......
34 35
    private boolean reinitializeBuffers = true;
35 36
    private BufferStrategy strategy;
36 37
    private Graphics2D graphics;
38

  
39
    private double zoom = 1;
40
    private int rotationDeg = 0;
37 41
    private final AffineTransform transform = new AffineTransform();
42

  
38 43
    private final Canvas canvas = new Canvas();
39 44
    private final JPanel panel = new JPanel();
40 45

  
......
103 108
        }
104 109
    }
105 110

  
106
    public Optional<VisCanvas> getVisCanvas() {
111
    public Optional<VisInfo> getVisCanvas() {
107 112
        return visCanvas;
108 113
    }
109 114

  
......
132 137
                transform.scale(multiplyFactor, multiplyFactor);
133 138
                transform.inverseTransform(scaleCenterScreen, postScale);
134 139
                transform.translate(postScale.getX()-presScale.getX(), postScale.getY()-presScale.getY());
140
                zoom *= multiplyFactor;
135 141
            } catch (NoninvertibleTransformException e) {
136 142
                e.printStackTrace();
137 143
            }
......
147 153
            try {
148 154
                transform.inverseTransform(centerScreen, centerWorld);
149 155
                transform.rotate(deltaAngleRad, centerWorld.getX(), centerWorld.getY());
156
                rotationDeg += deltaAngleDeg;
150 157
            } catch (NoninvertibleTransformException e) {
151 158
                e.printStackTrace();
152 159
            }
......
159 166

  
160 167
            AffineTransform originalTransform = graphics.getTransform();
161 168
            AffineTransform affineTransform = calculateAffineTransform();
162
            visCanvas = Optional.of(new VisCanvas(affineTransform, graphics, panel.getBounds()));
169
            visCanvas = Optional.of(new VisInfo(affineTransform, graphics, panel.getBounds(), mousePosition, rotationDeg, zoom));
163 170

  
164 171
            layer.paint(visCanvas.get(), adapter);
165 172

  
......
206 213
    public void removeMouseListener(MouseListener mouseListener) {
207 214
        canvas.removeMouseListener(mouseListener);
208 215
    }
216

  
217
    public void updateMousePosition(Point mousePostion) {
218
        this.mousePosition = mousePostion;
219
    }
209 220
}
src/main/java/cz/agents/alite/visualizer2d/VisPaneMouseListener.java
31 31
    }
32 32

  
33 33
    @Override
34
    public void mouseMoved(MouseEvent e) {}
34
    public void mouseMoved(MouseEvent e) {
35
        visPane.updateMousePosition(e.getPoint());
36
    }
35 37

  
36 38
    @Override
37 39
    public void mouseClicked(MouseEvent e) {}
src/main/java/cz/agents/alite/visualizer2d/demo/Demo.java
1 1
package cz.agents.alite.visualizer2d.demo;
2 2

  
3

  
3 4
import cz.agents.alite.visualizer2d.Point2dAdapter;
4 5
import cz.agents.alite.visualizer2d.VisPane;
5 6
import cz.agents.alite.visualizer2d.layers.ColorLayer;
6
import cz.agents.alite.visualizer2d.layers.DraggableLayer;
7 7
import cz.agents.alite.visualizer2d.layers.GroupLayer;
8
import cz.agents.alite.visualizer2d.layers.VisInfoLayer;
8 9
import cz.agents.alite.visualizer2d.layers.elements.ElementsLayer;
9 10
import cz.agents.alite.visualizer2d.layers.elements.PointElement;
10
import cz.agents.alite.visualizer2d.layers.textBackgroundLayer.ColoredTextElementImpl;
11
import cz.agents.alite.visualizer2d.layers.textBackgroundLayer.TextBackgroundLayer;
12
import cz.agents.alite.visualizer2d.layers.textBackgroundLayer.TextBackgroundLayerBuilder;
13 11

  
14 12
import javax.swing.*;
15 13
import javax.vecmath.Point2d;
......
28 26
        GroupLayer<Point2d> layers = GroupLayer.create();
29 27
        layers.addLayer(ColorLayer.create(Color.BLACK));
30 28
        layers.addLayer(ElementsLayer.create(() -> Arrays.asList(
31
                new PointElement<>(new Point2d(AngleProvider.TRANS_X, AngleProvider.TRANS_Y), 3, Color.RED),
32
                new PointElement<>(angleProvider.getPoint(), 3, Color.WHITE),
33
                new PointElement<>(new Point2d(AngleProvider.TRANS_X + 25, AngleProvider.TRANS_Y), 3, Color.GREEN))
29
                        new PointElement<>(new Point2d(AngleProvider.TRANS_X, AngleProvider.TRANS_Y), 3, Color.RED),
30
                        new PointElement<>(angleProvider.getPoint(), 3, Color.WHITE),
31
                        new PointElement<>(new Point2d(AngleProvider.TRANS_X + 25, AngleProvider.TRANS_Y), 3, Color.GREEN))
34 32
        ));
35
        TextBackgroundLayer textBackgroundLayer = TextBackgroundLayerBuilder.createTopLeft(15, 15,
36
                () -> Arrays.asList(new ColoredTextElementImpl(String.format("%f\n, %f", angleProvider.getPoint().x,
37
                        angleProvider.getPoint().y), Color.WHITE))
38
        ).setBackgroundColor(Color.RED).build();
39
        GroupLayer draggable = DraggableLayer.create(textBackgroundLayer);
40
        layers.addLayer(draggable);
33
        VisInfoLayer visInfoLayer = VisInfoLayer.create();
34
        //GroupLayer draggable = DraggableLayer.create(visInfoLayer);
35
        layers.addLayer(visInfoLayer);
41 36
        VisPane<Point2d> visPane = new VisPane<>(layers, Point2dAdapter.IDENTITY);
42 37
        JFrame frame = new JFrame("Visualizer2d Demo");
43 38
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
src/main/java/cz/agents/alite/visualizer2d/layers/ColorLayer.java
2 2

  
3 3
import cz.agents.alite.visualizer2d.Layer;
4 4
import cz.agents.alite.visualizer2d.Point2dAdapter;
5
import cz.agents.alite.visualizer2d.VisCanvas;
5
import cz.agents.alite.visualizer2d.VisInfo;
6 6

  
7 7
import java.awt.*;
8 8

  
......
22 22
    }
23 23

  
24 24
    @Override
25
    public void paint(VisCanvas visCanvas, Point2dAdapter<T> adapter) {
26
        Graphics2D graphics = visCanvas.getScreenCanvas();
25
    public void paint(VisInfo visInfo, Point2dAdapter<T> adapter) {
26
        Graphics2D graphics = visInfo.getScreenCanvas();
27 27
        graphics.setColor(color);
28
        Rectangle rectangle = visCanvas.getBounds();
28
        Rectangle rectangle = visInfo.getBounds();
29 29
        graphics.fill(rectangle);
30 30
    }
31 31
}
src/main/java/cz/agents/alite/visualizer2d/layers/DraggableLayer.java
2 2

  
3 3
import cz.agents.alite.visualizer2d.Layer;
4 4
import cz.agents.alite.visualizer2d.Point2dAdapter;
5
import cz.agents.alite.visualizer2d.VisCanvas;
5
import cz.agents.alite.visualizer2d.VisInfo;
6 6
import cz.agents.alite.visualizer2d.VisPane;
7 7

  
8 8
import java.awt.event.MouseEvent;
......
74 74
    }
75 75

  
76 76
    @Override
77
    public void paint(VisCanvas visCanvas, Point2dAdapter<T> adapter) {}
77
    public void paint(VisInfo visInfo, Point2dAdapter<T> adapter) {}
78 78

  
79 79
    @Override
80 80
    public void mouseDragged(MouseEvent e) {
src/main/java/cz/agents/alite/visualizer2d/layers/GroupLayer.java
2 2

  
3 3
import cz.agents.alite.visualizer2d.Layer;
4 4
import cz.agents.alite.visualizer2d.Point2dAdapter;
5
import cz.agents.alite.visualizer2d.VisCanvas;
5
import cz.agents.alite.visualizer2d.VisInfo;
6 6
import cz.agents.alite.visualizer2d.VisPane;
7 7

  
8 8
import java.util.HashSet;
......
42 42
    }
43 43

  
44 44
    @Override
45
    public final void paint(VisCanvas visCanvas, Point2dAdapter<T> adapter) {
45
    public final void paint(VisInfo visInfo, Point2dAdapter<T> adapter) {
46 46
        for (Layer<T> layer : layers) {
47
            layer.paint(visCanvas, adapter);
47
            layer.paint(visInfo, adapter);
48 48
        }
49 49
    }
50 50

  
src/main/java/cz/agents/alite/visualizer2d/layers/HudLayer.java
2 2

  
3 3
import cz.agents.alite.visualizer2d.Layer;
4 4
import cz.agents.alite.visualizer2d.Point2dAdapter;
5
import cz.agents.alite.visualizer2d.VisCanvas;
5
import cz.agents.alite.visualizer2d.VisInfo;
6 6
import cz.agents.alite.visualizer2d.layers.elements.Element;
7 7

  
8 8
import java.awt.*;
9
import java.util.Collections;
10
import java.util.Set;
9 11
import java.util.function.Supplier;
10 12

  
11 13
/**
......
13 15
 */
14 16
public class HudLayer implements Layer {
15 17

  
18
    public HudLayer create(Element element) {
19
        Set<Element> set = Collections.singleton(element);
20
        return create(() -> set);
21
    }
22

  
23
    public HudLayer create(Supplier<Iterable<Element>> elements) {
24
        return new HudLayer(elementsSupplier);
25
    }
26

  
16 27
    private final Supplier<Iterable<Element>> elementsSupplier;
17 28

  
18
    public HudLayer(Supplier<Iterable<Element>> elementsSupplier) {
29
    private HudLayer(Supplier<Iterable<Element>> elementsSupplier) {
19 30
        this.elementsSupplier = elementsSupplier;
20 31
    }
21 32

  
22 33
    @Override
23
    public void paint(VisCanvas visCanvas, Point2dAdapter adapter) {
24
        Graphics2D screen = visCanvas.getScreenCanvas();
25
        elementsSupplier.get().forEach(element -> element.paint(visCanvas, screen, Point2dAdapter.IDENTITY));
34
    public void paint(VisInfo visInfo, Point2dAdapter adapter) {
35
        Graphics2D screen = visInfo.getScreenCanvas();
36
        elementsSupplier.get().forEach(element -> element.paint(visInfo, screen, Point2dAdapter.IDENTITY));
26 37
    }
27 38
}
src/main/java/cz/agents/alite/visualizer2d/layers/VisInfoLayer.java
1 1
package cz.agents.alite.visualizer2d.layers;
2 2

  
3
import cz.agents.alite.visualizer2d.Layer;
4 3
import cz.agents.alite.visualizer2d.Point2dAdapter;
5
import cz.agents.alite.visualizer2d.VisCanvas;
6
import cz.agents.alite.visualizer2d.VisPane;
4
import cz.agents.alite.visualizer2d.VisInfo;
5
import cz.agents.alite.visualizer2d.layers.textBackgroundLayer.*;
6

  
7
import javax.vecmath.Point2d;
8
import java.awt.*;
9
import java.awt.geom.Point2D;
10
import java.util.Collections;
7 11

  
8 12
/**
9 13
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
10 14
 */
11
public class VisInfoLayer implements Layer {
15
public class VisInfoLayer extends AbstractTextBackgroundLayer {
12 16

  
17
    private final Color textColor = new Color(164, 172, 151);
13 18

  
19
    public static VisInfoLayer create() {
20
        return new VisInfoLayer(new Color(44, 44, 44, 152), Padding.DEFAUT_PADDING, new BottomOffsetPositionFunction(15, 15));
21
    }
14 22

  
15

  
16
    @Override
17
    public void init(VisPane visPane) {
18

  
23
    private VisInfoLayer(Color backgroundColor, Padding padding, PositionFunction positionFunction) {
24
        super(backgroundColor, padding, positionFunction);
19 25
    }
20 26

  
21 27
    @Override
22
    public void deinit(VisPane visPane) {
28
    protected Iterable<ColoredTextElement> getTextElements(VisInfo visInfo, Point2dAdapter adapter) {
29
        StringBuilder text = new StringBuilder();
23 30

  
24
    }
31
        Point2d offset = visInfo.getOffset();
32
        Point mousePosition = visInfo.getMousePosition();
33
        Point2D worldCoordinates = visInfo.toWorldCoordinates(mousePosition);
25 34

  
26
    @Override
27
    public void paint(VisCanvas visCanvas, Point2dAdapter adapter) {
35
        text.append(String.format("Zoom: %.2f\n", visInfo.getZoom()));
36
        text.append(String.format("Rotation: %d\n", visInfo.getRotationDeg()));
37
        text.append(String.format("Offset: (%.2f, %.2f)\n", offset.x, offset.y));
38
        text.append(String.format("Screen: (%d, %d)\n", mousePosition.x, mousePosition.x));
39
        text.append(String.format("World: (%.2f, %.2f)", worldCoordinates.getX(), worldCoordinates.getY()));
40

  
41
        return Collections.singleton(new ColoredTextElementImpl(text.toString(), textColor));
28 42

  
29 43
    }
30 44
}
src/main/java/cz/agents/alite/visualizer2d/layers/elements/Element.java
1 1
package cz.agents.alite.visualizer2d.layers.elements;
2 2

  
3 3
import cz.agents.alite.visualizer2d.Point2dAdapter;
4
import cz.agents.alite.visualizer2d.VisCanvas;
4
import cz.agents.alite.visualizer2d.VisInfo;
5 5

  
6 6
import java.awt.*;
7 7

  
......
10 10
 */
11 11
public interface Element<T> {
12 12

  
13
    public void paint(VisCanvas visCanvas, Graphics2D canvas, Point2dAdapter<T> adapter);
13
    public void paint(VisInfo visInfo, Graphics2D canvas, Point2dAdapter<T> adapter);
14 14

  
15 15
}
src/main/java/cz/agents/alite/visualizer2d/layers/elements/ElementsLayer.java
2 2

  
3 3
import cz.agents.alite.visualizer2d.Layer;
4 4
import cz.agents.alite.visualizer2d.Point2dAdapter;
5
import cz.agents.alite.visualizer2d.VisCanvas;
5
import cz.agents.alite.visualizer2d.VisInfo;
6 6

  
7 7
import java.awt.*;
8 8
import java.util.Arrays;
......
32 32

  
33 33
    //TODO check if forEach is as fast as for each cycle
34 34
    @Override
35
    public void paint(VisCanvas visCanvas, Point2dAdapter<T> adapter) {
36
        final Graphics2D worldCanvas = visCanvas.getWorldCanvas();
37
        elementsSupplier.get().forEach(element -> element.paint(visCanvas, worldCanvas, adapter));
35
    public void paint(VisInfo visInfo, Point2dAdapter<T> adapter) {
36
        final Graphics2D worldCanvas = visInfo.getWorldCanvas();
37
        elementsSupplier.get().forEach(element -> element.paint(visInfo, worldCanvas, adapter));
38 38
    }
39 39
}
src/main/java/cz/agents/alite/visualizer2d/layers/elements/PointElement.java
1 1
package cz.agents.alite.visualizer2d.layers.elements;
2 2

  
3 3
import cz.agents.alite.visualizer2d.Point2dAdapter;
4
import cz.agents.alite.visualizer2d.VisCanvas;
4
import cz.agents.alite.visualizer2d.VisInfo;
5 5

  
6 6
import javax.vecmath.Point2d;
7 7
import java.awt.*;
......
23 23
    }
24 24

  
25 25
    @Override
26
    public void paint(VisCanvas visCanvas, Graphics2D canvas, Point2dAdapter<T> adapter) {
26
    public void paint(VisInfo visInfo, Graphics2D canvas, Point2dAdapter<T> adapter) {
27 27
        Point2d center = adapter.convert(centerPosition);
28 28
        canvas.setColor(color);
29 29

  
src/main/java/cz/agents/alite/visualizer2d/layers/textBackgroundLayer/AbstractTextBackgroundLayer.java
1
package cz.agents.alite.visualizer2d.layers.textBackgroundLayer;
2

  
3
import cz.agents.alite.visualizer2d.Layer;
4
import cz.agents.alite.visualizer2d.Point2dAdapter;
5
import cz.agents.alite.visualizer2d.VisInfo;
6
import cz.agents.alite.visualizer2d.layers.DraggableLayer;
7

  
8
import java.awt.*;
9
import java.util.ArrayList;
10

  
11
/**
12
 * @author Ondrej Hrstka (ondrej.hrstka at agents.fel.cvut.cz)
13
 */
14
public abstract class AbstractTextBackgroundLayer implements Layer, DraggableLayer.Draggable {
15
    protected final Padding padding;
16
    protected final PositionFunction positionFunction;
17
    protected final Color backgroundColor;
18
    private Rectangle rectangle;
19
    private boolean active = false;
20

  
21
    public AbstractTextBackgroundLayer(Color backgroundColor, Padding padding, PositionFunction positionFunction) {
22
        this.backgroundColor = backgroundColor;
23
        this.padding = padding;
24
        this.positionFunction = positionFunction;
25
    }
26

  
27
    @Override
28
    public void paint(VisInfo visInfo, Point2dAdapter adapter) {
29

  
30
        Graphics2D canvas = visInfo.getScreenCanvas();
31
        Iterable<ColoredTextElement> elements = getTextElements(visInfo, adapter);
32

  
33
        FontMetrics fontMetrics = canvas.getFontMetrics();
34
        java.util.List<ColoredTextElement> textLines = new ArrayList<>();
35
        int maxLineSize = 0;
36
        int totalLines = 0;
37

  
38
        active = false;
39
        for (ColoredTextElement element : elements) {
40
            active = true;
41

  
42
            textLines.add(element);
43

  
44
            String[] textByLines = element.getTextByLines();
45
            totalLines += textByLines.length;
46
            for (String line : textByLines) {
47
                maxLineSize = checkMaxLineSize(maxLineSize, fontMetrics, line);
48
            }
49

  
50
        }
51

  
52
        if (active == false) {
53
            return;
54
        }
55

  
56
        int yStep = fontMetrics.getHeight();
57

  
58
        int width = padding.getLeft() + maxLineSize + padding.getRight();
59
        int height = totalLines * yStep + padding.getTop() + padding.getBottom();
60

  
61
        Dimension drawingDimension = visInfo.getBounds().getSize();
62
        Point topLeft = positionFunction.getTopLeftPoint(width, height, drawingDimension);
63

  
64
        if (rectangle == null) {
65
            rectangle = new Rectangle(topLeft);
66
        }
67

  
68
        rectangle.setLocation(topLeft);
69
        rectangle.setSize(width, height);
70
        int x = topLeft.x;
71
        int y = topLeft.y;
72

  
73
        canvas.setColor(backgroundColor);
74
        canvas.fill(rectangle);
75

  
76
        x += padding.getLeft();
77
        y += padding.getTop() + fontMetrics.getAscent();
78

  
79
        for (ColoredTextElement textLine : textLines) {
80
            canvas.setColor(textLine.getColor());
81
            for (String line : textLine.getTextByLines()) {
82
                canvas.drawString(line, x, y);
83
                y += yStep;
84
            }
85

  
86
        }
87
    }
88

  
89
    protected abstract Iterable<ColoredTextElement> getTextElements(VisInfo visInfo, Point2dAdapter adapter);
90

  
91
    private int checkMaxLineSize(int maxLineSize, FontMetrics fontMetrics, String line) {
92
        return Math.max(maxLineSize, fontMetrics.stringWidth(line));
93
    }
94

  
95
    public boolean isActive() {
96
        return active;
97
    }
98

  
99
    @Override
100
    public boolean isInArea(int x, int y) {
101
        return rectangle != null && rectangle.contains(x, y);
102
    }
103

  
104
    @Override
105
    public void moveLocation(int deltaX, int deltaY) {
106
        positionFunction.moveLocation(deltaX, deltaY);
107
    }
108
}
src/main/java/cz/agents/alite/visualizer2d/layers/textBackgroundLayer/Padding.java
1 1
package cz.agents.alite.visualizer2d.layers.textBackgroundLayer;
2 2

  
3 3
public class Padding {
4

  
5
    public static final int DEFAULT_LEFT = 15;
6
    public static final int DEFAULT_RIGHT = 15;
7
    public static final int DEFAULT_BOTTOM = 15;
8
    public static final int DEFAULT_TOP = 15;
9

  
10
    public static final Padding DEFAUT_PADDING = new Padding(DEFAULT_LEFT, DEFAULT_RIGHT, DEFAULT_BOTTOM, DEFAULT_TOP);
11

  
4 12
    private final int leftPadding;
5 13
    private final int rightPadding;
6 14
    private final int bottomPadding;
src/main/java/cz/agents/alite/visualizer2d/layers/textBackgroundLayer/TextBackgroundLayer.java
1 1
package cz.agents.alite.visualizer2d.layers.textBackgroundLayer;
2 2

  
3
import cz.agents.alite.visualizer2d.Layer;
4 3
import cz.agents.alite.visualizer2d.Point2dAdapter;
5
import cz.agents.alite.visualizer2d.VisCanvas;
6
import cz.agents.alite.visualizer2d.layers.DraggableLayer;
4
import cz.agents.alite.visualizer2d.VisInfo;
7 5

  
8 6
import java.awt.*;
9
import java.util.ArrayList;
10
import java.util.List;
11 7
import java.util.function.Supplier;
12 8

  
13 9
/**
......
24 20
 * @see PositionFunction
25 21
 * @see cz.agents.alite.visualizer2d.layers.DraggableLayer.Draggable
26 22
 */
27
public class TextBackgroundLayer implements Layer, DraggableLayer.Draggable {
23
public class TextBackgroundLayer extends AbstractTextBackgroundLayer {
28 24

  
29
    private final Padding padding;
30 25
    private final Supplier<? extends Iterable<ColoredTextElement>> supplier;
31
    private final PositionFunction positionFunction;
32
    private final Color backgroundColor;
33

  
34
    private Rectangle rectangle;
35
    private boolean active = false;
36 26

  
37 27
    /**
38 28
     * Default implementation of factory method. It is recommended to use {@link TextBackgroundLayerBuilder} instead.
......
50 40

  
51 41
    private TextBackgroundLayer(Supplier<? extends Iterable<ColoredTextElement>> supplier, PositionFunction positionFunction, Padding padding,
52 42
                                Color backgroundColor) {
53
        this.padding = padding;
43
        super(backgroundColor, padding, positionFunction);
54 44
        this.supplier = supplier;
55
        this.positionFunction = positionFunction;
56
        this.backgroundColor = backgroundColor;
57 45
    }
58 46

  
59 47
    @Override
60
    public void paint(VisCanvas visCanvas, Point2dAdapter adapter) {
61

  
62
        Graphics2D canvas = visCanvas.getScreenCanvas();
63
        Iterable<ColoredTextElement> elements = supplier.get();
64

  
65
        FontMetrics fontMetrics = canvas.getFontMetrics();
66
        List<ColoredTextElement> textLines = new ArrayList<>();
67
        int maxLineSize = 0;
68
        int totalLines = 0;
69

  
70
        active = false;
71
        for (ColoredTextElement element : elements) {
72
            active = true;
73

  
74
            textLines.add(element);
75

  
76
            String[] textByLines = element.getTextByLines();
77
            totalLines += textByLines.length;
78
            for (String line : textByLines) {
79
                maxLineSize = checkMaxLineSize(maxLineSize, fontMetrics, line);
80
            }
81

  
82
        }
83

  
84
        if (active == false) {
85
            return;
86
        }
87

  
88
        int yStep = fontMetrics.getHeight();
89

  
90
        int width = padding.getLeft() + maxLineSize + padding.getRight();
91
        int height = totalLines * yStep + padding.getTop() + padding.getBottom();
92

  
93
        Dimension drawingDimension = visCanvas.getBounds().getSize();
94
        Point topLeft = positionFunction.getTopLeftPoint(width, height, drawingDimension);
95

  
96
        if (rectangle == null) {
97
            rectangle = new Rectangle(topLeft);
98
        }
99

  
100
        rectangle.setLocation(topLeft);
101
        rectangle.setSize(width, height);
102
        int x = topLeft.x;
103
        int y = topLeft.y;
104

  
105
        canvas.setColor(backgroundColor);
106
        canvas.fill(rectangle);
107

  
108
        x += padding.getLeft();
109
        y += padding.getTop() + fontMetrics.getAscent();
110

  
111
        for (ColoredTextElement textLine : textLines) {
112
            canvas.setColor(textLine.getColor());
113
            for (String line : textLine.getTextByLines()) {
114
                canvas.drawString(line, x, y);
115
                y += yStep;
116
            }
117

  
118
        }
48
    protected Iterable<ColoredTextElement> getTextElements(VisInfo visInfo, Point2dAdapter adapter) {
49
        return supplier.get();
119 50
    }
120 51

  
121
    private int checkMaxLineSize(int maxLineSize, FontMetrics fontMetrics, String line) {
122
        return Math.max(maxLineSize, fontMetrics.stringWidth(line));
123
    }
124

  
125
    public boolean isActive() {
126
        return active;
127
    }
128

  
129
    @Override
130
    public boolean isInArea(int x, int y) {
131
        return rectangle != null && rectangle.contains(x, y);
132
    }
133

  
134
    @Override
135
    public void moveLocation(int deltaX, int deltaY) {
136
        positionFunction.moveLocation(deltaX, deltaY);
137
    }
138

  
139 52

  
140 53
}
src/main/java/cz/agents/alite/visualizer2d/layers/textBackgroundLayer/TextBackgroundLayerBuilder.java
14 14

  
15 15
    public static final Color DEFAULT_COLOR = new Color(0, 0, 0, 100);
16 16

  
17
    public static final int DEFAULT_LEFT_PADDING = 15;
18
    public static final int DEFAULT_RIGHT_PADDING = 15;
19
    public static final int DEFAULT_BOTTOM_PADDING = 15;
20
    public static final int DEFAULT_TOP_PADDING = 15;
21

  
22 17
    private Supplier<? extends Iterable<ColoredTextElement>> supplier;
23 18
    private PositionFunction positionFunction;
24 19
    private Color backgroundColor = DEFAULT_COLOR;
25
    private Padding padding = new Padding(DEFAULT_LEFT_PADDING, DEFAULT_RIGHT_PADDING, DEFAULT_BOTTOM_PADDING, DEFAULT_TOP_PADDING);
20

  
21
    private Padding padding = Padding.DEFAUT_PADDING;
26 22

  
27 23
    /**
28 24
     * Create builder with {@link TopLeftPositionFunction}.

Also available in: Unified diff