📄 carview.java
字号:
/* * To change this template, choose Tools | Templates * and open the template in the editor. */package zdrive.panels;/** * * @author Mikhail */import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.RenderingHints;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.geom.AffineTransform;import java.awt.geom.GeneralPath;import java.io.File;import java.awt.image.BufferedImage;import java.io.IOException;import javax.imageio.ImageIO;import java.util.HashMap;import javax.swing.BorderFactory;import javax.swing.JPanel;import javax.swing.Timer;/** * * @author user */public class CarView extends JPanel implements ActionListener { public static final String DIRECTION_N = "N"; public static final String DIRECTION_NE = "NE"; public static final String DIRECTION_E = "E"; public static final String DIRECTION_SE = "SE"; public static final String DIRECTION_S = "S"; public static final String DIRECTION_SW = "SW"; public static final String DIRECTION_W = "W"; public static final String DIRECTION_NW = "NW"; public static final Color LIGHT_DEFAULT_COLOR = Color.LIGHT_GRAY; public static final Color LIGHT_ON1_COLOR = Color.RED; public static final Color LIGHT_ON2_COLOR = new Color(0.7f, 0.0f, 0.0f); private static final double PERIOD = 800.0; private static final double radius = 2; private static final double cf = 0.1; private static final double vOffset = 60; private static final double vWidth = 5; private static final double vRectHeight = 25; private static final double hOffset = 40; private static final double hWidth = 10; private static final double hRectWidth = 50; private static final double inMargin = 10; private static final double bwMargin = 10; private static final double extMargin = 10; private Timer timer; private double X0; private double Y0; private double X1; private double Y1; private double X2; private double Y2; private double X3; private double Y3; private double X4; private double Y4; private double totalWidth; private double totalHeight; private BufferedImage carImage = null; private HashMap<String, LightData> mapping = new HashMap<String, LightData>(); public CarView() { setBorder(BorderFactory.createLineBorder(Color.black)); setBackground(Color.BLACK); setDoubleBuffered(true); X0 = extMargin; Y0 = extMargin; X1 = X0 + hWidth + 2 * radius; Y1 = Y0 + vWidth + 2 * radius; X2 = X1 + hOffset + 2 * radius + bwMargin; Y2 = Y1 + vOffset + 2 * radius + bwMargin; X3 = X2 + hRectWidth + 2 * radius + bwMargin; Y3 = Y2 + vRectHeight + 2 * radius + bwMargin; X4 = X3 + hOffset + 2 * radius; Y4 = Y3 + vOffset + 2 * radius; totalWidth = X4 + extMargin + hWidth + 2 * radius; totalHeight = Y4 + extMargin + vWidth + 2 * radius; mapping.put(DIRECTION_N, new LightData()); mapping.put(DIRECTION_NE, new LightData()); mapping.put(DIRECTION_E, new LightData()); mapping.put(DIRECTION_SE, new LightData()); mapping.put(DIRECTION_S, new LightData()); mapping.put(DIRECTION_SW, new LightData()); mapping.put(DIRECTION_W, new LightData()); mapping.put(DIRECTION_NW, new LightData()); timer = new Timer(100, this); timer.setInitialDelay(1000); timer.start(); } public void lightOn (String light) { mapping.get(light).on = true; } public void lightOff (String light) { mapping.get(light).on = false; } @Override public Dimension getPreferredSize() { return new Dimension(200,400); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = null; if (g instanceof Graphics2D) g2 = (Graphics2D)g; AffineTransform transform = g2.getTransform(); g2.scale(getWidth() / totalWidth, getHeight() / totalHeight); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(mapping.get(DIRECTION_NW).color); fillRoundedRectCorner(g2, X0, Y0, vWidth, hWidth, vOffset, hOffset, false, true); g.setColor(mapping.get(DIRECTION_NE).color); fillRoundedRectCorner(g2, X3, Y0, vWidth, hWidth, vOffset, hOffset, false, false); g.setColor(mapping.get(DIRECTION_SW).color); fillRoundedRectCorner(g2, X0, Y3, vWidth, hWidth, vOffset, hOffset, true, true); g.setColor(mapping.get(DIRECTION_SE).color); fillRoundedRectCorner(g2, X3, Y3, vWidth, hWidth, vOffset, hOffset, true, false); g.setColor(mapping.get(DIRECTION_N).color); fillRoundedRect(g2, X2, Y0, hRectWidth, vWidth); g.setColor(mapping.get(DIRECTION_S).color); fillRoundedRect(g2, X2, Y4, hRectWidth, vWidth); g.setColor(mapping.get(DIRECTION_W).color); fillRoundedRect(g2, X0, Y2, hWidth, vRectHeight); g.setColor(mapping.get(DIRECTION_E).color); fillRoundedRect(g2, X4, Y2, hWidth, vRectHeight); g.setColor(Color.ORANGE); if (carImage == null) fillRoundedRect(g2, X1 + inMargin, Y1 + inMargin, X4 - X1 - 2 * inMargin - 2 * radius, Y4 - Y1 - 2 * inMargin - 2 * radius); else g2.drawImage(carImage, (int)(X1 + inMargin), (int)(Y1 + inMargin), (int)(X4 - X1 - 2 * inMargin), (int)(Y4 - Y1 - 2 * inMargin), null); g2.setTransform(transform); } public void setCarImage (String path) { try { carImage = ImageIO.read(getClass().getResource(path)); } catch (IOException e) { e.printStackTrace(); } } private Color setMixedColor (Color c1, Color c2, double f) { return new Color((int)(c1.getRed() * f + c2.getRed() * (1 - f)), (int)(c1.getGreen() * f + c2.getGreen() * (1 - f)), (int)(c1.getBlue() * f + c2.getBlue() * (1 - f))); } private class LightData { public LightData () { color = LIGHT_DEFAULT_COLOR; on = false; } public Color color; public boolean on; }; private void updateLights (double t) { double x = t * Math.PI; double v = 0.5 + 0.405 * Math.cos(x) + 0.045 * Math.cos(3 * x) + 0.016 * Math.cos(5 * x); for (LightData ld : mapping.values()) { if (ld.on) { ld.color = setMixedColor(LIGHT_ON1_COLOR, LIGHT_ON2_COLOR, v); } else { ld.color = LIGHT_DEFAULT_COLOR; } } repaint(); } public void actionPerformed(ActionEvent e) { updateLights(System.currentTimeMillis() / PERIOD); } private void curveA (GeneralPath path, double x0, double y0, double xc, double yc, double x1, double y1) { path.curveTo(x0 * cf + xc * (1 - cf), y0 * cf + yc * (1 - cf), x1 * cf + xc * (1 - cf), y1 * cf + yc * (1 - cf), x1, y1); } private static void flip (double[] intervals) { double sum = 0; for (int i = 0; i < intervals.length; ++i) sum += intervals[i]; intervals[0] = sum - intervals[0]; for (int i = 1; i < intervals.length; ++i) intervals[i] = -intervals[i]; } private void fillRoundedRectCorner (Graphics2D g2, double x0, double y0, double wv, double wh, double lv, double lh, boolean vflip, boolean hflip) { GeneralPath path = new GeneralPath(); double[] hint = new double[] {0, radius, lh, radius, radius, wh, radius}; double[] vint = new double[] {0, radius, wv, radius, radius, lv, radius}; if (vflip) flip(vint); if (hflip) flip(hint); double[] y = new double[7]; double[] x = new double[7]; x[0] = x0 + hint[0]; y[0] = y0 + vint[0]; for (int i = 1; i < 7; ++i) { x[i] = x[i - 1] + hint[i]; y[i] = y[i - 1] + vint[i]; } path.moveTo(x[1], y[0]); curveA(path, x[1], y[0], x[0], y[0], x[0], y[1]); path.lineTo(x[0], y[2]); curveA(path, x[0], y[2], x[0], y[3], x[1], y[3]); path.lineTo(x[2], y[3]); curveA(path, x[2], y[3], x[3], y[3], x[3], y[4]); path.lineTo(x[3], y[5]); curveA(path, x[3], y[5], x[3], y[6], x[4], y[6]); path.lineTo(x[5], y[6]); curveA(path, x[5], y[6], x[6], y[6], x[6], y[5]); path.lineTo(x[6], y[1]); curveA(path, x[6], y[1], x[6], y[0], x[5], y[0]); path.lineTo(x[1], y[0]); g2.fill(path); } private void fillRoundedRect (Graphics2D g2, double x0, double y0, double w,double h) { GeneralPath path = new GeneralPath(); double y1 = y0 + radius; double y2 = y1 + h; double y3 = y2 + radius; double x1 = x0 + radius; double x2 = x1 + w; double x3 = x2 + radius; path.moveTo(x1, y0); curveA(path, x1, y0, x0, y0, x0, y1); path.lineTo(x0, y2); curveA(path, x0, y2, x0, y3, x1, y3); path.lineTo(x2, y3); curveA(path, x2, y3, x3, y3, x3, y2); path.lineTo(x3, y1); curveA(path, x3, y1, x3, y0, x2, y0); path.lineTo(x1, y0); g2.fill(path); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -