java make screensavers

package com.sun.play;

import javax.swing.*;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Properties;

/**
 * Digital rainbow rain
 */
public class BinaryRain extends JDialog {
    private static final long serialVersionUID = 1L;
    private Color foreground, background; // foreground color, background color
    private Dimension size; // Dimension class encapsulates a single object in the component height and width (integer precision)
    private char [] RAIN_CHARACTERS; // array of characters
    private boolean isColorful; // color is covered
    private boolean hasMusic; // whether to play music
    private AudioClip music; // audio objects
    private boolean isStart = false; // whether to start
    private RainPanel panel = new RainPanel();// RainPanel对象
    private ArrayList<Rain> rains = new ArrayList<Rain>();
    private Font rainFont = new Font("arial", Font.BOLD, 15);
    ; // create text fonts rain

    /**
     Initializing constructor *
     */
    private BinaryRain() {
        try {
            initProperties();
            init();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "Failed to init.\n" + e, "BinaryRain", JOptionPane.ERROR_MESSAGE);
            System.exit (1); // non-normal exit
        }
    }

    /**
     * Reads the configuration file and initialize
     *
     * @throws Exception
     */
    private void initProperties() throws Exception {
        Properties props = new Properties();
        File file = new File(System.getProperty("user.dir") + "/src/sun/game/resources/BinaryRain.properties");// 获取配置文件
        boolean dw = true, dh = true, df = true, db = true, dc = true, dcf = true;
        if (file.exists() && file.isFile()) {
            InputStream fis = new FileInputStream (file); // create a file input stream
            props.load (fis); // load the properties file
            // Get the foreground color, default default
            String strFore = props.getProperty("foreground", "default").toLowerCase();
            if (!"default".equals(strFore)) {
                df = false;
                foreground = getColor (strFore); // Get Color
                if (foreground == null) {
                    foreground = Color.getColor (strFore, Color.GREEN); // get the color of the object, the default green
                }
            }
            // Get the background color, default default
            String strBack = props.getProperty("background", "default").toLowerCase();
            if (!"default".equals(strBack)) {
                db = false;
                background = getColor (strBack); // Get Color
                if (background == null) {
                    background = Color.getColor (strBack, Color.GREEN); // get the color of the object, the default green
                }
            }
            // Get the width
            size = new Dimension();
            String strW = props.getProperty("width", "default").toLowerCase();
            if (!"default".equals(strW)) {
                dw = false;
                size.width = Integer.valueOf(strW);
            }
            // Gets the height
            String strH = props.getProperty("height", "default").toLowerCase();
            if (!"default".equals(strH)) {
                I = false;
                size.width = Integer.valueOf(strH);
            }
            // Get the array of characters
            String strC = props.getProperty("characters", "default");
            if (!"default".equalsIgnoreCase(strC)) {
                dc = false;
                String[] cs = strC.split(",");
                RAIN_CHARACTERS = new char[cs.length];
                for (int i = 0, s = RAIN_CHARACTERS.length; i < s; i++) {
                    RAIN_CHARACTERS[i] = cs[i].charAt(0);
                }
            }
            // determine whether the color covered
            String strCF = props.getProperty("colorful", "default");
            if (!"default".equalsIgnoreCase(strCF)) {
                dcf = false;
                isColorful = Boolean.valueOf(strCF);
            }
            // determine whether to play music
            String strM = props.getProperty("music", "default");
            if (!"default".equalsIgnoreCase(strM)) {
                File musicFile = new File(System.getProperty("user.dir") + "/src/main/resources/" + strM);
                if (musicFile.exists() && musicFile.isFile()) {
                    if ((music = Applet.newAudioClip(musicFile.toURI().toURL())) != null) {
                        hasMusic = true;
                    }
                }
            }
            fis.close();
        }
        if (dw & dh) {// the height and width are the default, acquiring high and wide-screen
            size = Toolkit.getDefaultToolkit().getScreenSize();
        } Else if (dw) {// width default, acquiring the screen width
            size.width = Toolkit.getDefaultToolkit().getScreenSize().width;
        } Else if (dh) {// height default, acquires the screen height
            size.height = Toolkit.getDefaultToolkit().getScreenSize().height;
        }
        if (df) {// default foreground color is
            foreground = Color.GREEN;
        }
        if (db) {// default background color
            background = Color.BLACK;
        }
        if (dc) {// array of characters is the default
            RAIN_CHARACTERS = new char[126 - 33 + 1];
            for (int c = 0, i = 33, l = RAIN_CHARACTERS.length; c < l; c++, i++) {
                RAIN_CHARACTERS[c] = (char) i;
            }
        }
        if (dcf) {// default color is covered
            isColorful = false;
        }
    }

    /**
     * Get a character string corresponding color
     *
     * @Param color color
     * @return
     */
    private Color getColor(String color) {
        if (color == null || color.isEmpty()) {
            return null;
        }
        if (color.startsWith("#")) {
            int i = Integer.valueOf(color.substring(1), 16);
            return new Color(i);
        }
        // [\\ d]: Digital [\\ p {Blank}]: spaces or tabs
        if (color.matches("[\\d]+[\\p{Blank}]*,[\\p{Blank}]*[\\d]+[\\p{Blank}]*,[\\p{Blank}]*[\\d]+")) {
            String[] cs = color.split("[\\p{Blank}]*,[\\p{Blank}]");
            if (cs.length != 3) {
                return null;
            }
            int r = Integer.valueOf(cs[0]);
            int g = Integer.valueOf(cs[1]);
            int b = Integer.valueOf(cs[2]);
            return new Color(r, g, b);
        }
        return null;
    }

    /**
     * Initialization window
     */
    private void init() {
        setAlwaysOnTop (true); // Set the front window
        setResizable (false); // can not be resized
        setUndecorated (true); // set this frame window loses modification (before it must setVisible) border and title bar
        setTitle ( "Binary Rain"); // set the title
        // create a BufferedImage object
        BufferedImage cursor = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB_PRE);
        setCursor (. Toolkit.getDefaultToolkit () createCustomCursor (cursor, new Point (8, 8), "Disable Cursor")); // confirm the shape of the cursor
        setSize (size); // set the window size
        setLocationRelativeTo (null); // Set the window relative to the position of the specified component, null represents the center of the screen
        addKeyListener (new KeyAdapter () {// add a key listener
            @Override
            public void keyPressed(KeyEvent e) {
                if ((e.isAltDown () && e.getKeyCode () == KeyEvent.VK_F4) || (e.getKeyCode () == KeyEvent.VK_ESCAPE)) {// press the Esc key or Alt + F4
                    setVisible (false); // set the window is not visible
                    System.exit (0); // stop the normal program
                }
            }
        });
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                if (isRaining()) {
                    stop();
                }
                System.exit (0); // stop the normal program
            }
        });
        add (panel, BorderLayout.CENTER); // the specified component to this container
    }

    /**
     * Rewrite setVisible method stops when the text is not displayed to create rain
     */
    public void setVisible(boolean flag) {
        super.setVisible(flag);
        if (!flag) {
            stop();
        }
    }

    /**
     * Whether to start creating text rain
     *
     * @return
     */
    public boolean isRaining() {
        return isStart;
    }

    /**
     * Stop writing rain
     */
    public void stop() {
        isStart = false; // start identifier is set to false
        if (hasMusic) {// play music
            music.stop (); // stop playing music
        }
    }

    /**
     * Start a new thread, create a text rain, using synchronized to ensure that only one thread can be executed within a time
     */
    private synchronized void newRain() {
        Rain r = new Rain(getRandomLength(), (int) (Math.random() * size.width), (int) (Math.random() * -60 * 15),
                (int) (Math.random() * 8 + 2), (float) (Math.random() * 10 + 10));
        rains.add(r);
        new Thread(r).start();
    }

    /**
     * Get random length (10-50)
     *
     * @return
     */
    public int getRandomLength() {
        return (int) (Math.random() * 40 + 10);
    }

    /**
     * Get random string
     *
     * @return
     */
    public String getRandomChar() {
        return String.valueOf(RAIN_CHARACTERS[(int) (Math.random() * RAIN_CHARACTERS.length)]);
    }

    /**
     * Get the size of the panel
     *
     * @return
     */
    public Dimension getFrameSize() {
        return size;
    }

    public void start() {
        if (hasMusic) {// play music
            music.loop (); // Loop
        }
        for (int c = 0, s = 108; c <s; c ++) {// create text 108 Rain
            newRain();
        }
        isStart = true;
        for (Rain r : rains) {
            new Thread(r).start();
        }
        new Thread(new Runnable() {
            public void run() {
                while (isStart) {
                    panel.repaint();
                }
            }
        }).start();
    }

    /**
     * Create a text panel rain
     */
    private final class RainPanel extends JPanel {
        private static final long serialVersionUID = 1L;

        public RainPanel() {
        }

        private final Color [] COLORS = new Color [] {// set the color of the text character rain
                new Color(255, 0, 0), new Color(255, 165, 0), new Color(255, 255, 0), new Color(0, 255, 0),
                new Color(0, 127, 0), new Color(0, 127, 255), new Color(139, 0, 255)};

        @Override
        public void paint(Graphics g) {
            if (isStart) {
                BufferedImage img = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);// 创建一个BufferedImage对象
                Graphics2D g2 = (Graphics2D) img.getGraphics (); // Get Graphics2D object
                g2.setColor (background); // set the color
                g2.fillRect (0, 0, size.width, size.height); // a rectangle filled with a predetermined color
                g2.setColor (foreground); // set the color
                // clone rain all text information to the Collection
                @SuppressWarnings("unchecked")
                Collection<Rain> collection = (Collection<Rain>) rains.clone();
                for (Iterator<Rain> it = collection.iterator(); it.hasNext(); ) {
                    Rain r = it.next();
                    if (r.isEnd ()) {// article text rain has ended
                        rains.remove (r); // Clear the strip removed from the set of text
                        newRain (); // create a new text rain
                        continue;
                    }
                    if (isColorful) {// Colors confluent
                        g2.setFont (rainFont.deriveFont (r.getSize ())); // set the text size text rain
                        String [] ss = r.getRainChars (); // get the text content of text rain
                        int x = r.getX (); // Get the text X-axis coordinate rain
                        int y = r.getY () - ss.length * 15; // Clear Y-axis coordinate acquiring text
                        for (int i = 0, sl = ss.length; i < sl; i++) {
                            if (i < 7) {
                                g2.setColor(COLORS[i]);
                            } else {
                                g2.setColor(COLORS[i % 7]);
                            }
                            g2.drawString(ss[i], x, y);
                            and + = 15;
                        }
                    } else {
                        g2.setFont (rainFont.deriveFont (r.getSize ())); // set the text size text rain
                        String [] ss = r.getRainChars (); // get the text content of text rain
                        int x = r.getX (); // Get the text X-axis coordinate rain
                        int y = r.getY () - ss.length * 15; // Clear Y-axis coordinate acquiring text
                        for (String s : ss) {
                            g2.drawString(s, x, y);
                            and + = 15;
                        }
                    }
                }
                g.drawImage (img, 0, 0, this); // the specified image rendering
            }
        }
    }

    /**
     * Create a section of text by rain thread
     */
    private final class Rain implements Runnable {
        private int rainSpeed; // rain rate
        private final String [] rainChars; // rains text
        private int rainX, rainY; // coordinate system text
        private float fontSize; // Text Size

        /**
         * Initialize a text rain
         *
         * Text length @param length text rain
         * @Param xx coordinates
         * @Param yy coordinates
         * @Param speed speed rain
         * @Param size Text Size
         */
        public Rain(int length, int x, int y, int speed, float size) {
            if (speed < 1) {
                throw new RuntimeException("The speed must be greater than or equal to 1.");
            }
            if (length < 5) {
                length = getRandomLength();
            }
            if (size < 1.0f) {
                size = 15.0f;
            }
            rainChars = new String[length + 1];
            for (int i = 0; i < length; i++) {
                rainChars[i] = getRandomChar();
            }
            rainChars[length] = " ";
            this.rainX = x;
            this.rainY = y;
            this.rainSpeed = speed;
            this.fontSize = size;
        }

        /**
         * Perform text rain
         */
        public void run() {
            while (isRaining() && rainY < getFrameSize().height + (rainChars.length + 1) * 15) {
                if (rainSpeed ​​<= 0) {// text rain velocity less than or equal to 0, the end of
                    break;
                }
                try {
                    Thread.sleep(rainSpeed);// 睡眠
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                rainY + = 2; // every movement downwardly 2
            }
            rainSpeed ​​= -1; // End of text rain velocity set to -1
        }

        /**
         * Get text
         *
         * @return
         */
        public String [] getRainChars () {
            return rainChars;
        }

        /**
         * Get Rain X-axis coordinate text
         *
         * @return
         */
        public int getX() {
            return rainX;
        }

        /**
         * Get the Y coordinate text rain
         *
         * @return
         */
        public int tide () {
            return rainY;
        }

        /**
         * Get text rain text size
         *
         * @return
         */
        public float getSize() {
            return fontSize;
        }

        /**
         * Text determine whether the end of the rain
         *
         * @return
         */
        public boolean isEnd() {
            return rainSpeed <= 0;
        }
    }

    public static void main(String[] args) {
        BinaryRain rain = new BinaryRain();
        rain.setVisible(true);
        rain.start();
    }
}

Guess you like

Origin blog.csdn.net/weixin_41825468/article/details/90771028