package com.han.java2d; import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.awt.font.FontRenderContext; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.net.URL; /** * The WeatherWizard demo uses the JSlider component as well as various graphics capabilities to generate and display * a specified weather type.<p> * Class note: Created by Gaowen on 14-1-11. */ public class WeatherWizard extends JPanel implements ChangeListener { private final WeatherPainter painter; private WeatherWizard() { setLayout(new BorderLayout()); Box box = Box.createHorizontalBox(); box.add(Box.createGlue()); box.add(new JLabel("Temperature:")); JSlider jSlider = new JSlider(20, 100, 65); jSlider.setMinorTickSpacing(5); jSlider.setMajorTickSpacing(20); jSlider.setPaintTicks(true); jSlider.setPaintLabels(true); jSlider.addChangeListener(this); box.add(jSlider); box.add(Box.createGlue()); add(box, BorderLayout.NORTH); painter = new WeatherPainter(loadImage("sun"), loadImage("cloud"), loadImage("rain"), loadImage("snow")); add(painter, BorderLayout.CENTER); } private BufferedImage loadImage(String name) { String imgFileName = "images/weather-" + name + ".png"; URL url = WeatherWizard.class.getResource(imgFileName); BufferedImage img = null; try { img = ImageIO.read(url); } catch (Exception e) { e.printStackTrace(); } return img; } private class WeatherPainter extends Component { private final BufferedImage snow; private final BufferedImage rain; private final BufferedImage cloud; private final BufferedImage sun; private int temperature; private Color textColor; private String feels; private String condStr; private Composite alpha0; private Composite alpha1; private BufferedImage img0; private BufferedImage img1; private WeatherPainter(BufferedImage snow, BufferedImage rain, BufferedImage cloud, BufferedImage sun) { this.snow = snow; this.rain = rain; this.cloud = cloud; this.sun = sun; temperature = 65; textColor = Color.yellow; } public void setTemperature(int temperature) { this.temperature = temperature; repaint(); } @Override public Dimension getPreferredSize() { return new Dimension(450, 125); } @Override public void paint(Graphics g) { Graphics2D g2 = (Graphics2D) g.create(); Dimension size = getSize(); Composite origComposite; setupWeatherReport(); origComposite = g2.getComposite(); if (alpha0 != null) g2.setComposite(alpha0); g2.drawImage(img0, 0, 0, size.width, size.height, 0, 0, img0.getWidth(null), img0.getHeight(null), null); if (img1 != null) { if (alpha1 != null) g2.setComposite(alpha1); g2.drawImage(img1, 0, 0, size.width, size.height, 0, 0, img1.getWidth(null), img1.getHeight(null), null); } g2.setComposite(origComposite); Font font = new Font("Serif", Font.PLAIN, 36); g2.setFont(font); String tempString = feels + " " + temperature + "F"; FontRenderContext frc = g2.getFontRenderContext(); Rectangle2D boundsTemp = font.getStringBounds(tempString, frc); Rectangle2D boundsCond = font.getStringBounds(condStr, frc); int wText = Math.max((int) boundsTemp.getWidth(), (int) boundsCond.getWidth()); int hText = (int) boundsTemp.getHeight() + (int) boundsCond.getHeight(); int rX = (size.width - wText) / 2; int rY = (size.height - hText) / 2; g2.setColor(Color.LIGHT_GRAY); g2.fillRect(rX, rY, wText, hText); g2.setColor(textColor); int xTextTemp = rX - (int) boundsTemp.getX(); int yTextTemp = rY - (int) boundsTemp.getY(); g2.drawString(tempString, xTextTemp, yTextTemp); int xTextCond = rX - (int) boundsCond.getX(); int yTextCond = rY - (int) boundsCond.getY() + (int) boundsTemp.getHeight(); g2.drawString(condStr, xTextCond, yTextCond); } private void setupWeatherReport() { if (temperature <= 32) { setupImages(snow); setupText("Snow", null); } else if (temperature <= 40) { setupImages(32, 40, snow, rain); setupText("Snow", "Rain"); } else if (temperature <= 50) { setupImages(rain); setupText("Rain", null); } else if (temperature <= 58) { setupImages(50, 58, rain, cloud); setupText("Rain", "Cloud"); } else if (temperature <= 65) { setupImages(cloud); setupText("Cloud", null); } else if (temperature <= 75) { setupImages(65, 75, cloud, sun); setupText("Cloud", "Sun"); } else { setupImages(sun); setupText("Sun", null); } } private void setupText(String s1, String s2) { if (temperature <= 32) { textColor = Color.blue; feels = "Freezing"; } else if (temperature <= 50) { textColor = Color.green; feels = "Cold"; } else if (temperature <= 65) { textColor = Color.yellow; feels = "Cool"; } else if (temperature <= 75) { textColor = Color.orange; feels = "Warm"; } else { textColor = Color.red; feels = "Hot"; } condStr = s1; if (s2 != null) { condStr += "/" + s2; } } private void setupImages(BufferedImage i0) { alpha0 = null; alpha1 = null; img0 = i0; img1 = null; } private void setupImages(int min, int max, BufferedImage i0, BufferedImage i1) { float alpha = (max - temperature) / (float) (max - min); alpha0 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha); alpha1 = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1 - alpha); img0 = i0; img1 = i1; } } @Override public void stateChanged(ChangeEvent e) { JSlider jSlider = (JSlider) e.getSource(); painter.setTemperature(jSlider.getValue()); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); } private static void createAndShowGUI() { JFrame jFrame = new JFrame("Weather Wizard"); JPanel contentPane = new WeatherWizard(); jFrame.setContentPane(contentPane); jFrame.pack(); jFrame.setLocationRelativeTo(null); jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jFrame.setVisible(true); } }