package org.concord.energy2d.view; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Polygon; import java.awt.RenderingHints; import java.awt.Stroke; import java.awt.geom.Arc2D; import java.awt.geom.Area; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import javax.swing.Icon; import org.concord.energy2d.model.Cloud; import org.concord.energy2d.model.Fan; import org.concord.energy2d.model.Heliostat; import org.concord.energy2d.model.Tree; /** * @author Charles Xie * */ public abstract class Symbol implements Icon { protected int xSymbol = 0, ySymbol = 0, wSymbol = 8, hSymbol = 8; protected Color color = Color.white; protected Stroke stroke = new BasicStroke(1); protected boolean paintBorder; protected boolean pressed; protected boolean disabled; protected int offsetX, offsetY; protected int marginX, marginY; public void setDisabled(boolean disabled) { this.disabled = disabled; } public boolean isDisabled() { return disabled; } public void setPressed(boolean pressed) { this.pressed = pressed; } public boolean isPressed() { return pressed; } public void setColor(Color color) { this.color = color; } public Color getColor() { return color; } public void setStroke(Stroke stroke) { this.stroke = stroke; } public Stroke getStroke() { return stroke; } public void setBorderPainted(boolean paintBorder) { this.paintBorder = paintBorder; } public boolean isBorderPainted() { return paintBorder; } public void setOffsetX(int offsetX) { this.offsetX = offsetX; } public int getOffsetX() { return offsetX; } public void setOffsetY(int offsetY) { this.offsetY = offsetY; } public int getOffsetY() { return offsetY; } public void setMarginX(int marginX) { this.marginX = marginX; } public int getMarginX() { return marginX; } public void setMarginY(int marginY) { this.marginY = marginY; } public int getMarginY() { return marginY; } public void setSymbolWidth(int wSymbol) { this.wSymbol = wSymbol; } public int getSymbolWidth() { return wSymbol; } public void setSymbolHeight(int hSymbol) { this.hSymbol = hSymbol; } public int getSymbolHeight() { return hSymbol; } public void setIconWidth(int width) { wSymbol = width - marginX * 2; } public int getIconWidth() { return wSymbol + marginX * 2; } public void setIconHeight(int height) { hSymbol = height - marginY * 2; } public int getIconHeight() { return hSymbol + marginY * 2; } public boolean contains(int rx, int ry) { return rx > xSymbol && rx < xSymbol + wSymbol && ry > ySymbol && ry < ySymbol + hSymbol; } public void paintIcon(Component c, Graphics g, int x, int y) { xSymbol = x + offsetX; ySymbol = y + offsetY; Graphics2D g2 = (Graphics2D) g; g2.setColor(color); if (paintBorder) { g.drawRoundRect(xSymbol, ySymbol, wSymbol, hSymbol, 10, 10); } g2.setStroke(stroke); } public Symbol getScaledInstance(float scale) { try { Symbol icon = getClass().newInstance(); icon.setIconWidth((int) (scale * icon.getIconWidth())); icon.setIconHeight((int) (scale * icon.getIconHeight())); return icon; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return null; } public Image createImage(Component c) { BufferedImage image = new BufferedImage(getIconWidth(), getIconHeight(), BufferedImage.TYPE_INT_ARGB); Graphics g = image.createGraphics(); try { paintIcon(c, g, 0, 0); return image; } finally { g.dispose(); } } static class Moon extends Symbol { public Moon(Color color, int w, int h) { setColor(color); setIconWidth(w); setIconHeight(h); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; Area a = new Area(new Ellipse2D.Float(xSymbol, ySymbol, wSymbol, hSymbol)); a.subtract(new Area(new Ellipse2D.Float(xSymbol + wSymbol * 0.25f, ySymbol, wSymbol, hSymbol))); g2.fill(a); } } static class Sun extends Symbol { public Sun(Color color, int w, int h) { setColor(color); setIconWidth(w); setIconHeight(h); setStroke(new BasicStroke(2)); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; Ellipse2D.Float s = new Ellipse2D.Float(xSymbol, ySymbol, wSymbol * 0.75f, hSymbol * 0.75f); g2.fill(s); int x1, y1; double angle = 0; int n = 8; for (int i = 0; i < n; i++) { angle = i * Math.PI * 2 / n; x1 = (int) (s.getCenterX() + 10 * Math.cos(angle)); y1 = (int) (s.getCenterY() + 10 * Math.sin(angle)); g2.drawLine(x1, y1, (int) s.getCenterX(), (int) s.getCenterY()); } } } public static class Thermometer extends Symbol { private int value; private int ballDiameter; private boolean isButtonIcon; public Thermometer(boolean isButtonIcon) { this.isButtonIcon = isButtonIcon; } public void setValue(int value) { this.value = value; } public int getBarHeight() { return hSymbol - Math.round(wSymbol * 1.5f); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; if (isButtonIcon) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); } g2.setColor(Color.white); g2.fillRect(xSymbol, ySymbol, wSymbol, hSymbol); ballDiameter = Math.round(wSymbol * 1.45f); int x2 = xSymbol + wSymbol / 2; int y2 = ySymbol + hSymbol - ballDiameter / 2; if (value != 0) { g2.setColor(Color.red); BasicStroke bs = new BasicStroke(wSymbol * 0.3f); g2.setStroke(bs); g2.drawLine(x2, y2 - value, x2, y2); } g2.setColor(Color.black); g2.setStroke(stroke); g2.drawRect(xSymbol, ySymbol, wSymbol, hSymbol); int n = hSymbol / 2; for (int i = 1; i < n; i++) { g2.drawLine(xSymbol, ySymbol + i * 2, Math.round(xSymbol + 0.2f * wSymbol), ySymbol + i * 2); g2.drawLine(xSymbol + wSymbol, ySymbol + i * 2, Math.round(xSymbol + wSymbol - 0.2f * wSymbol), ySymbol + i * 2); } x2 = Math.round(xSymbol - wSymbol * 0.25f); g2.setColor(Color.lightGray); g2.fillOval(x2, y2, ballDiameter, ballDiameter); g2.setColor(Color.black); g2.drawOval(x2, y2, ballDiameter, ballDiameter); } } public static class HeatFluxSensor extends Symbol { private Stroke stroke2; private boolean isButtonIcon; public HeatFluxSensor(boolean isButtonIcon) { stroke2 = new BasicStroke(3); this.isButtonIcon = isButtonIcon; } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); int y2 = Math.round(ySymbol + hSymbol * 0.5f); Graphics2D g2 = (Graphics2D) g; if (isButtonIcon) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); } g2.setColor(Color.white); g2.fillRect(xSymbol, ySymbol, wSymbol, hSymbol); g2.fillOval(xSymbol - 7, y2 - 3, 6, 6); g2.setColor(Color.black); g2.drawRect(xSymbol, ySymbol, wSymbol, hSymbol); for (int i = 4; i < wSymbol - 4; i += 4) { if (i % 8 == 0) { g2.drawLine(xSymbol + i, ySymbol, xSymbol + i + 4, ySymbol + hSymbol); } else { g2.drawLine(xSymbol + i, ySymbol + hSymbol, xSymbol + i + 4, ySymbol); } } g2.drawLine(xSymbol - 2, y2, xSymbol + 4, y2); g2.drawOval(xSymbol - 7, y2 - 3, 6, 6); g2.setStroke(stroke2); g2.drawLine(xSymbol, ySymbol, xSymbol + wSymbol, ySymbol); g2.drawLine(xSymbol, ySymbol + hSymbol, xSymbol + wSymbol, ySymbol + hSymbol); } } public static class Anemometer extends Symbol { private float angle; private boolean isButtonIcon; public Anemometer(boolean isButtonIcon) { this.isButtonIcon = isButtonIcon; } public void setAngle(float angle) { this.angle = angle; } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; if (isButtonIcon) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); } double xc = xSymbol + wSymbol * 0.5; double yc = ySymbol + hSymbol * 0.5; g2.setColor(Color.white); g.fillOval(Math.round(xSymbol + wSymbol * 0.4f), Math.round(ySymbol + hSymbol * 0.4f), Math.round(wSymbol * 0.2f), Math.round(hSymbol * 0.2f)); g2.setColor(Color.black); g.drawOval(Math.round(xSymbol + wSymbol * 0.4f), Math.round(ySymbol + hSymbol * 0.4f), Math.round(wSymbol * 0.2f), Math.round(hSymbol * 0.2f)); g2.rotate(angle, xc, yc); int[] xPoints = new int[] { (int) xc, Math.round(xSymbol + wSymbol * 0.4f), Math.round(xSymbol + wSymbol * 0.6f) }; int[] yPoints = new int[] { ySymbol, Math.round(ySymbol + hSymbol * 0.4f), Math.round(ySymbol + hSymbol * 0.4f) }; g2.setColor(Color.white); g.fillPolygon(xPoints, yPoints, 3); g2.setColor(Color.black); g.drawPolygon(xPoints, yPoints, 3); double theta = 2.0 * Math.PI / 3.0; g2.rotate(theta, xc, yc); g2.setColor(Color.white); g.fillPolygon(xPoints, yPoints, 3); g2.setColor(Color.black); g.drawPolygon(xPoints, yPoints, 3); g2.rotate(theta, xc, yc); g2.setColor(Color.white); g.fillPolygon(xPoints, yPoints, 3); g2.setColor(Color.black); g.drawPolygon(xPoints, yPoints, 3); g2.rotate(-angle - 2 * theta, xc, yc); } } public static class ParticleFeederIcon extends Symbol { private Color borderColor; private boolean isButtonIcon; public ParticleFeederIcon(Color color, Color borderColor, boolean isButtonIcon) { setColor(color); setBorderColor(borderColor); this.isButtonIcon = isButtonIcon; } public void setBorderColor(Color borderColor) { this.borderColor = borderColor; } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; if (isButtonIcon) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); } g2.setStroke(stroke); g2.setColor(color); g2.fillRoundRect(xSymbol, ySymbol, wSymbol, hSymbol, 8, 8); g2.setColor(borderColor); g2.drawRoundRect(xSymbol, ySymbol, wSymbol, hSymbol, 8, 8); g2.fillOval(Math.round(xSymbol + 0.5f * wSymbol - 2), Math.round(ySymbol + 0.5f * hSymbol - 2), 4, 4); } } public static class FanIcon extends Symbol { private Color borderColor; private float speed, angle, rotation; private boolean isButtonIcon; public FanIcon(Color color, Color borderColor, boolean isButtonIcon) { setColor(color); setBorderColor(borderColor); this.isButtonIcon = isButtonIcon; } public void setSpeed(float speed) { this.speed = speed; } public void setAngle(float angle) { this.angle = angle; } public void setRotation(float rotation) { this.rotation = rotation; } public void setBorderColor(Color borderColor) { this.borderColor = borderColor; } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; if (isButtonIcon) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); } Area a = Fan.getShape(new Rectangle2D.Float(xSymbol, ySymbol, wSymbol > 0 ? wSymbol : getIconWidth(), hSymbol > 0 ? hSymbol : getIconHeight()), speed, angle, (float) Math.abs(Math.sin(rotation))); g2.setColor(color); g2.fill(a); g2.setColor(borderColor); g2.setStroke(stroke); g2.draw(a); } } public static class HeliostatIcon extends Symbol { private Color borderColor; private float angle; private boolean isButtonIcon; public HeliostatIcon(Color color, Color borderColor, boolean isButtonIcon) { setColor(color); setBorderColor(borderColor); this.isButtonIcon = isButtonIcon; } public void setAngle(float angle) { this.angle = angle; } public void setBorderColor(Color borderColor) { this.borderColor = borderColor; } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; if (isButtonIcon) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); } Area a = Heliostat.getShape(new Rectangle2D.Float(xSymbol, ySymbol, wSymbol > 0 ? wSymbol : getIconWidth(), hSymbol > 0 ? hSymbol : getIconHeight()), angle); g2.setColor(color); g2.fill(a); g2.setColor(borderColor); g2.setStroke(stroke); g2.draw(a); } } public static class CloudIcon extends Symbol { private Color borderColor; private boolean isButtonIcon; public CloudIcon(boolean isButtonIcon) { this.isButtonIcon = isButtonIcon; } public void setBorderColor(Color borderColor) { this.borderColor = borderColor; } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; if (isButtonIcon) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); } Area a = Cloud.getShape(new Rectangle2D.Float(xSymbol, ySymbol, wSymbol > 0 ? wSymbol : getIconWidth(), hSymbol > 0 ? hSymbol : getIconHeight())); g2.setColor(color); g2.fill(a); g2.setColor(borderColor); g2.setStroke(stroke); g2.draw(a); } } public static class TreeIcon extends Symbol { private byte type; private Color borderColor; private boolean isButtonIcon; public TreeIcon(byte type, boolean isButtonIcon) { this.type = type; this.isButtonIcon = isButtonIcon; } public void setType(byte type) { this.type = type; } public void setBorderColor(Color borderColor) { this.borderColor = borderColor; } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; if (isButtonIcon) { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); } Area a = Tree.getShape(new Rectangle2D.Float(xSymbol, ySymbol, wSymbol > 0 ? wSymbol : getIconWidth(), hSymbol > 0 ? hSymbol : getIconHeight()), type); g2.setColor(color); g2.fill(a); g2.setColor(borderColor); g2.setStroke(stroke); g2.draw(a); } } static class SwitchIcon extends Symbol { public SwitchIcon(Color color, int w, int h) { setColor(color); setIconWidth(w); setIconHeight(h); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; float thickness = ((BasicStroke) stroke).getLineWidth(); Rectangle2D.Float s = new Rectangle2D.Float(xSymbol + wSymbol * 0.2f, ySymbol + hSymbol * 0.2f, wSymbol * 0.6f, hSymbol * 0.6f); Arc2D.Float a = new Arc2D.Float(s, 80 - thickness * 10, thickness * 20 - 340, Arc2D.OPEN); g2.draw(a); g2.drawLine((int) (xSymbol + wSymbol * 0.5f), (int) (ySymbol + hSymbol * 0.1f), (int) (xSymbol + wSymbol * 0.5f), (int) (ySymbol + hSymbol * 0.4f)); } } static class GraphIcon extends Symbol { private Stroke s2 = new BasicStroke(1); public GraphIcon(Color color, int w, int h) { setColor(color); setIconWidth(w); setIconHeight(h); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; int x0 = (int) (xSymbol + wSymbol * 0.25f); int y0 = (int) (ySymbol + hSymbol * 0.25f); g2.drawRect(x0 - 1, y0 - 1, (int) (wSymbol * 0.5f) + 2, (int) (hSymbol * 0.5f) + 2); g2.setStroke(s2); if (pressed) { g2.drawLine(x0, y0, (int) (x0 + wSymbol * 0.5f), (int) (y0 + hSymbol * 0.5f)); g2.drawLine(x0, (int) (y0 + hSymbol * 0.5f), (int) (x0 + wSymbol * 0.5f), y0); } else { g2.drawLine(x0, (int) (y0 + hSymbol * 0.25f), (int) (x0 + wSymbol * 0.25f), (int) (y0 + hSymbol * 0.5f)); g2.drawLine((int) (x0 + wSymbol * 0.25f), (int) (y0 + hSymbol * 0.5f), (int) (x0 + wSymbol * 0.5f), y0); } } } static class ResetIcon extends Symbol { public ResetIcon(Color color, int w, int h) { setColor(color); setIconWidth(w); setIconHeight(h); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; Rectangle2D.Float s = new Rectangle2D.Float(xSymbol + wSymbol * 0.4f, ySymbol + hSymbol * 0.3f, wSymbol * 0.4f, hSymbol * 0.4f); Arc2D.Float a = new Arc2D.Float(s, -90, 180, Arc2D.OPEN); g2.draw(a); int x0 = Math.round(xSymbol + wSymbol * 0.3f); int y0 = Math.round(ySymbol + hSymbol * 0.28f); g2.drawLine(Math.round(xSymbol + wSymbol * 0.55f), y0, x0, y0); g2.drawLine(x0, y0, x0 + 2, y0 - 2); g2.drawLine(x0, y0, x0 + 2, y0 + 2); y0 += Math.round(hSymbol * 0.4f); g2.drawLine(Math.round(xSymbol + wSymbol * 0.55f), y0, x0, y0); } } static class StartIcon extends Symbol { private int d = 4; private Stroke s2 = new BasicStroke(d); public StartIcon(Color color, int w, int h) { setColor(color); setIconWidth(w); setIconHeight(h); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); if (pressed) { ((Graphics2D) g).setStroke(s2); g.drawLine(xSymbol + wSymbol / 2 - d + 1, ySymbol + d * 2, xSymbol + wSymbol / 2 - d + 1, ySymbol + hSymbol - d * 2); g.drawLine(xSymbol + wSymbol / 2 + d - 1, ySymbol + d * 2, xSymbol + wSymbol / 2 + d - 1, ySymbol + hSymbol - d * 2); } else { int[] xpoints = new int[] { xSymbol + wSymbol / 2 - d, xSymbol + wSymbol - d, xSymbol + wSymbol / 2 - d }; int[] ypoints = new int[] { ySymbol + d, ySymbol + hSymbol / 2, ySymbol + hSymbol - d }; g.fillPolygon(new Polygon(xpoints, ypoints, 3)); } } } static class NextIcon extends Symbol { public NextIcon(Color color, int w, int h) { setColor(color); setIconWidth(w); setIconHeight(h); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); g.setColor(disabled ? Color.gray : color); int d = 4; int[] xpoints = new int[] { xSymbol + 3 * d, xSymbol + wSymbol - d, xSymbol + 3 * d }; int[] ypoints = new int[] { ySymbol + d, ySymbol + hSymbol / 2, ySymbol + hSymbol - d }; g.fillPolygon(new Polygon(xpoints, ypoints, 3)); g.fillRect(xSymbol + d, ySymbol + hSymbol / 2 - d, 2 * d, 2 * d); } } static class PrevIcon extends Symbol { public PrevIcon(Color color, int w, int h) { setColor(color); setIconWidth(w); setIconHeight(h); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); g.setColor(disabled ? Color.gray : color); int d = 4; int[] xpoints = new int[] { xSymbol + wSymbol - 3 * d, xSymbol + d, xSymbol + wSymbol - 3 * d }; int[] ypoints = new int[] { ySymbol + d, ySymbol + hSymbol / 2, ySymbol + hSymbol - d }; g.fillPolygon(new Polygon(xpoints, ypoints, 3)); g.fillRect(xSymbol + wSymbol - 3 * d, ySymbol + hSymbol / 2 - d, 2 * d, 2 * d); } } static class ModeIcon extends Symbol { private Stroke stroke2 = new BasicStroke(1.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 1, new float[] { 1 }, 0); public ModeIcon(Color color, int w, int h) { setColor(color); setIconWidth(w); setIconHeight(h); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, x, y); Graphics2D g2 = (Graphics2D) g; if (pressed) { g2.setStroke(stroke2); g2.drawOval(xSymbol + 5, ySymbol + 5, wSymbol - 10, hSymbol - 10); g2.drawOval(xSymbol + 10, ySymbol + 10, wSymbol - 20, hSymbol - 20); g2.drawOval(xSymbol + 15, ySymbol + 15, wSymbol - 30, hSymbol - 30); } else { g2.rotate(Math.PI / 3, xSymbol + wSymbol / 2, ySymbol + hSymbol / 2); int d = 6; int[] xpoints = new int[] { xSymbol + wSymbol - 2 * d, xSymbol + d, xSymbol + wSymbol - 2 * d }; int[] ypoints = new int[] { ySymbol + 3 * d / 2, ySymbol + hSymbol / 2, ySymbol + hSymbol - 3 * d / 2 }; g.fillPolygon(new Polygon(xpoints, ypoints, 3)); g.fillRect(xSymbol + wSymbol - 3 * d, ySymbol + hSymbol / 2 - d / 2, 2 * d, d); g2.rotate(-Math.PI / 3, xSymbol + wSymbol / 2, ySymbol + hSymbol / 2); } } } public static class ArrowHead extends Symbol { public ArrowHead(Color color, int w, int h) { setColor(color); setIconWidth(w); setIconHeight(h); } @Override public void paintIcon(final Component c, final Graphics g, final int x, final int y) { g.setColor(color); final int x2 = wSymbol / 2; final int y2 = hSymbol / 2; final int[] vx = new int[] { 2, wSymbol - 2, x2 }; final int[] vy = new int[] { y2 - 2, y2 - 2, y2 + 4 }; g.fillPolygon(vx, vy, vx.length); } } static class LogoIcon extends Symbol { private Font font; private int cornerDiameter = 20; public LogoIcon() { font = new Font("Book Antiqua", Font.BOLD, 14); } public void paintIcon(Component c, Graphics g, int x, int y) { super.paintIcon(c, g, xSymbol, ySymbol); Graphics2D g2 = (Graphics2D) g; String s = "Energy2D"; g2.setFont(font); FontMetrics fm = g.getFontMetrics(); wSymbol = fm.stringWidth(s) + 10; hSymbol = fm.getHeight() + fm.getDescent() + 3; xSymbol = x - 6; ySymbol = y - fm.getAscent() - 3; g2.setColor(Color.gray); g2.fillRoundRect(xSymbol, ySymbol, wSymbol, hSymbol, cornerDiameter, cornerDiameter); g2.setStroke(stroke); g2.setColor(color); g2.drawRoundRect(xSymbol, ySymbol, wSymbol, hSymbol, cornerDiameter, cornerDiameter); g2.setColor(Color.black); g2.drawString(s, x + 1, y - 1); g2.drawString(s, x + 1, y + 1); g2.drawString(s, x - 1, y - 1); g2.drawString(s, x - 1, y + 1); g2.setColor(Color.lightGray); g2.drawString(s, x, y); } } }