org.gannacademy.cdf.graphics.Image   A
last analyzed

Complexity

Total Complexity 26

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 169
rs 10
eloc 81
wmc 26

18 Methods

Rating   Name   Duplication   Size   Complexity  
A getImage() 0 2 1
A setLocation(double,double) 0 4 1
A setImage(String) 0 3 1
A setY(double) 0 3 1
A setWidth(double) 0 3 1
A draw(Graphics2D) 0 11 4
A setHeight(double) 0 3 1
A getPath() 0 2 1
A getWidth() 0 3 1
A getY() 0 3 1
A getHeight() 0 3 1
A setX(double) 0 3 1
A getShape() 0 3 1
A Image(String,double,double,DrawingPanel) 0 9 2
A getX() 0 3 1
A setImage(BufferedImage) 0 10 3
A rescaleImage() 0 8 3
A translate(double,double) 0 4 1
1
package org.gannacademy.cdf.graphics;
2
3
import org.gannacademy.cdf.graphics.ui.DrawingPanel;
4
5
import javax.imageio.ImageIO;
6
import java.awt.*;
7
import java.awt.geom.Rectangle2D;
8
import java.awt.image.BufferedImage;
9
import java.io.IOException;
10
11
/**
12
 * Render an image file
13
 *
14
 * @author <a href="https://github.com/gann-cdf/graphics/issues" target="_blank">Seth Battis</a>
15
 */
16
public class Image extends Drawable {
17
  private BufferedImage original, active;
18
  private String path;
19
  private double x, y, width, height;
20
21
  /**
22
   * <p>Construct a new image object</p>
23
   *
24
   * <p><img src="doc-files/Image.png" alt="Diagram of Image parameters"></p>
25
   *
26
   * <p>Initially, width and height of a new image object match the dimensions of the original image.</p>
27
   *
28
   * <p>Note that image files (as should all files used by your app internally) should be stored in a resources directory in your project. Maven creates this directory by default, but IDEs allow you to mark a subfolder of your project as the resources root. The path to the image file is relative to the root of the resources directory.</p>
29
   *
30
   * <p>All window coordinates are measured in pixels, with the X-axis increasing from left to right and the Y-axis
31
   * increasing from top to bottom. All window coordinates exist in the first quadrant.</p>
32
   *
33
   * <p><img src="doc-files/window-coordinates.png" alt="Diagram of window coordinates"></p>
34
   *
35
   * @param path         to the image resource
36
   * @param x            coordinate of image origin
37
   * @param y            coordinate of image origin
38
   * @param drawingPanel on which to draw
39
   */
40
  public Image(String path, double x, double y, DrawingPanel drawingPanel) {
41
    try {
42
      setImage(path);
43
      setX(x);
44
      setY(y);
45
      setDrawingPanel(drawingPanel);
46
    } catch (IOException e) {
47
        System.err.println(e.getMessage());
48
      e.printStackTrace();
0 ignored issues
show
Best Practice introduced by
Throwable.printStackTrace writes to the console which might not be available at runtime. Using a logger is preferred.
Loading history...
49
    }
50
  }
51
52
  /**
53
   * Underlying image data
54
   *
55
   * @return Underlying {@link BufferedImage} data
56
   */
57
  public BufferedImage getImage() {
58
    return original;
59
  }
60
61
  /**
62
   * <p>Replace the underlying {@link BufferedImage} data</p>
63
   *
64
   * <p>Replacing the underlying image data leaves other characteristics (fill, stroke, position) unchanged.</p>
65
   *
66
   * @param path to image resource
67
   * @throws IOException if the image resource cannot be accessed
68
   */
69
  public void setImage(String path) throws IOException {
70
    this.path = path;
71
    setImage(ImageIO.read(getClass().getResource(path)));
72
  }
73
74
  /**
75
   * <p>Replace the underlying {@link BufferedImage} data</p>
76
   *
77
   * <p>Replacing the underlying image data leaves other characteristics (fill, stroke, position) unchanged.</p>
78
   *
79
   * @param image data
80
   */
81
  public void setImage(BufferedImage image) {
82
    original = image;
83
84
    // only set width and height to match image if loading initial image
85
    if (active == null && original != null) {
86
      setWidth(original.getWidth());
87
      setHeight(original.getHeight());
88
      active = original;
89
    } else {
90
      rescaleImage();
91
    }
92
  }
93
94
  /**
95
   * Path to image resource
96
   *
97
   * @return Path to image resource
98
   */
99
  public String getPath() {
100
    return path;
101
  }
102
103
  /**
104
   * Rescale the underlying image data to match current width and height field values
105
   */
106
  protected void rescaleImage() {
107
    if (getWidth() > 0 && getHeight() > 0) {
108
      active = new BufferedImage((int) getWidth(), (int) getHeight(), original.getType());
109
      Graphics2D graphics = active.createGraphics();
110
      graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
111
      graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
112
      graphics.drawImage(original, 0, 0, (int) getWidth(), (int) getHeight(), null);
113
      graphics.dispose();
114
    }
115
  }
116
117
  @Override
118
  public Shape getShape() {
119
    return new Rectangle2D.Double(x, y, width, height);
120
  }
121
122
  @Override
123
  public double getX() {
124
    return x;
125
  }
126
127
  @Override
128
  public void setX(double x) {
129
    this.x = x;
130
  }
131
132
  @Override
133
  public double getY() {
134
    return y;
135
  }
136
137
  @Override
138
  public void setY(double y) {
139
    this.y = y;
140
  }
141
142
  @Override
143
  public double getWidth() {
144
    return width;
145
  }
146
147
  public void setWidth(double width) {
148
    this.width = width;
149
    rescaleImage();
150
  }
151
152
  @Override
153
  public double getHeight() {
154
    return height;
155
  }
156
157
  public void setHeight(double height) {
158
    this.height = height;
159
    rescaleImage();
160
  }
161
162
  @Override
163
  public void translate(double dx, double dy) {
164
    setX(x + dx);
165
    setY(y + dy);
166
  }
167
168
  @Override
169
  public void setLocation(double x, double y) {
170
    setX(x);
171
    setY(y);
172
  }
173
174
  @Override
175
  public void draw(Graphics2D graphics2D) {
176
    if (getFillColor() != TRANSPARENT) {
177
      graphics2D.setPaint(getFillColor());
178
      graphics2D.fill(getShape());
179
    }
180
    graphics2D.drawImage(active, (int) x, (int) y, null);
181
    if (getStroke() != NO_STROKE && getStrokeColor() != TRANSPARENT) {
182
      graphics2D.setStroke(getStroke());
183
      graphics2D.setPaint(getStrokeColor());
184
      graphics2D.draw(getShape());
185
    }
186
  }
187
}
188