zoukankan      html  css  js  c++  java
  • java Swing 图片缓冲机制

    java Swing 图片缓冲机制:

    参考:http://jorneyr.iteye.com/blog/868858#comments

    package util;
    
    import java.awt.geom.Point2D;
    
    public class GeometryUtil {
        // 两点之间的距离
        public static double distanceOfPoints(Point2D p1, Point2D p2) {
            double disX = p2.getX() - p1.getX();
            double disY = p2.getY() - p1.getY();
            double dis = Math.sqrt(disX * disX + disY * disY);
    
            return dis;
        }
    
        // 两点的中点
        public static Point2D middlePoint(Point2D p1, Point2D p2) {
            double x = (p1.getX() + p2.getX()) / 2;
            double y = (p1.getY() + p2.getY()) / 2;
    
            return new Point2D.Double(x, y);
        }
    
        // 在两点所在直线上,以从startPoint到endPoint为方向,离startPoint的距离disToStartPoint的点
        public static Point2D extentPoint(Point2D startPoint, Point2D endPoint, double disToStartPoint) {
            double disX = endPoint.getX() - startPoint.getX();
            double disY = endPoint.getY() - startPoint.getY();
            double dis = Math.sqrt(disX * disX + disY * disY);
            double sin = (endPoint.getY() - startPoint.getY()) / dis;
            double cos = (endPoint.getX() - startPoint.getX()) / dis;
            double deltaX = disToStartPoint * cos;
            double deltaY = disToStartPoint * sin;
    
            return new Point2D.Double(startPoint.getX() + deltaX, startPoint.getY() + deltaY);
        }
    
        // 绕原点的旋转矩阵,绕任意点旋转,可以先移动到原点,旋转,然后再移回去
        // cosθ -sinθ 0
        // sinθ +conθ 0
        // 0000 +0000 1
        // x = r*cosα, y = r*sinα
        // x' = r*cos(α+θ) = r*cosα*cosθ - r*sinα*sinθ = x*cosθ - y*sinθ
        // y' = r*sin(α+θ) = r*sinα*cosθ + r*cosα*sinθ = x*sinθ + y*cosθ
        // (x, y)绕圆心旋转degree度
        public static Point2D rotate(double x, double y, double degree) {
            return rotate(x, y, 0, 0, degree);
        }
    
        // (x, y)绕(ox, oy)旋转degree度
        public static Point2D rotate(double x, double y, double ox, double oy, double degree) {
            x -= ox;
            y -= oy;
    
            double cos = Math.cos(Math.toRadians(degree));
            double sin = Math.sin(Math.toRadians(degree));
    
            double temp = x * cos - y * sin;
            y = x * sin + y * cos;
            x = temp;
    
            return new Point2D.Double(x + ox, y + oy);
        }
    
        public static void main(String[] args) {
            Point2D p = rotate(50, 10, 10);
            System.out.println(p);
            p = rotate(100, 60, 50, 50, 10);
            System.out.println(p);
        }
    }
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GraphicsConfiguration;
    import java.awt.GraphicsDevice;
    import java.awt.GraphicsEnvironment;
    import java.awt.RenderingHints;
    import java.awt.Transparency;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.geom.Point2D;
    import java.awt.image.BufferedImage;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    import util.GeometryUtil;
    @SuppressWarnings("serial")
    public class Growing extends JPanel {
        private List<Point2D> ps = new ArrayList<Point2D>();
        private Timer timer;
        private boolean stopped = false;
        public Growing() {
            ps.add(new Point2D.Double(0, 0));
            ps.add(new Point2D.Double(800, 0));
            timer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    grow();
                    repaint();
                }
            });
            timer.start();
        }
        public void grow() {
            if (stopped) {
                return;
            }
            List<Point2D> temp = new ArrayList<Point2D>();
            temp.add(ps.get(0));
            for (int i = 0; i < ps.size() - 1; ++i) {
                Point2D p0 = ps.get(i);
                Point2D p4 = ps.get(i + 1);
                double len = GeometryUtil.distanceOfPoints(p0, p4);
                if (len < 0.02) {
                    // 当线条长度小于1时,就停止再增长
                    System.out.println(ps.size());
                    timer.stop();
                    return;
                }
                Point2D p1 = GeometryUtil.extentPoint(p0, p4, len / 3);
                Point2D p3 = GeometryUtil.extentPoint(p0, p4, len * 2 / 3);
                Point2D p2 = GeometryUtil.rotate(p3.getX(), p3.getY(), p1.getX(), p1.getY(), 60);
                temp.add(p1);
                temp.add(p2);
                temp.add(p3);
                temp.add(p4);
            }
            // 将增长的计算结果赋予ps变量;
            ps = null;
            ps = temp;
            temp = null;
        }
        int i = 0; // 记录绘制了几次;
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            // 修改type的值使用不同的绘制方式,1为compatible image, 2为swing的back-buffer
            int type = 2;
            // 改变窗口的大小,可以看到直接对intermediate image操作比直接对swing back-buffer操作快很多.
            // 所以有很多绘制操作时,使用triple buffer是很有必要的(因为Swing已经默认使用了双缓冲).
            if (type == 1) {
                // [[[1]]]: 操作 compatible image 速度非常快
                renderWithBuf(g2d, getWidth(), getHeight());
            } else {
                // [[[2]]]: 操作Swing的 back-buffer 速度非常慢
                render(g2d, getWidth(), getHeight());
            }
            System.out.println("Growing.paintComponent(Graphics):" + i++);
        }
        private BufferedImage bufImg;
        protected void renderWithBuf(Graphics2D g2d, int w, int h) {
            if (bufImg == null || bufImg.getWidth() != w || bufImg.getHeight() != h) {
                bufImg = createCompatibleImage(w, h, Transparency.OPAQUE);
                // bufImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            }
            Graphics2D gg = bufImg.createGraphics();
            render(gg, w, h);
            gg.dispose();
            g2d.drawImage(bufImg, 0, 0, null);
        }
        protected void render(Graphics2D g2d, int w, int h) {
            g2d.setBackground(Color.BLACK);
            g2d.clearRect(0, 0, w, h);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.translate(0, h - 20);
            g2d.setColor(Color.WHITE);
            for (int i = 0; i < ps.size() - 1; ++i) {
                Point2D sp = ps.get(i);
                Point2D ep = ps.get(i + 1);
                g2d.drawLine((int) sp.getX(), -(int) sp.getY(), (int) ep.getX(), -(int) ep.getY());
            }
        }
        // 创建硬件适配的缓冲图像,为了能显示得更快速
        public static BufferedImage createCompatibleImage(int w, int h, int type) {
            GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice device = env.getDefaultScreenDevice();
            GraphicsConfiguration gc = device.getDefaultConfiguration();
            return gc.createCompatibleImage(w, h, type);
        }
        private static void createGuiAndShow() {
            JFrame frame = new JFrame("Growing");
            frame.getContentPane().add(new Growing());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(800, 400);
            frame.setAlwaysOnTop(true);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    createGuiAndShow();
                }
            });
        }
    }
    import java.awt.geom.Point2D;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.eclipse.swt.SWT;
    import org.eclipse.swt.events.PaintEvent;
    import org.eclipse.swt.events.PaintListener;
    import org.eclipse.swt.graphics.GC;
    import org.eclipse.swt.graphics.Image;
    import org.eclipse.swt.graphics.Rectangle;
    import org.eclipse.swt.graphics.Transform;
    import org.eclipse.swt.layout.FillLayout;
    import org.eclipse.swt.widgets.Canvas;
    import org.eclipse.swt.widgets.Display;
    import org.eclipse.swt.widgets.Shell;
    
    import util.GeometryUtil;
    
    public class GrowingSWT
    {
        private final Shell shell;
        private final Canvas canvas;
    
        private List<Point2D> ps = new ArrayList<Point2D>();
        private boolean stopped = false;
        Image image = null;
        int type = 1;
    
        private final Runnable timer = new Runnable() {
            public void run()
            {
                shell.getDisplay().timerExec(500, timer);
                grow();
                canvas.redraw();
            }
        };
    
        GrowingSWT(final Display display)
        {
            shell = new Shell(display, SWT.DOUBLE_BUFFERED | SWT.SHELL_TRIM);
            shell.setLayout(new FillLayout());
            canvas = new Canvas(shell, SWT.NULL);
            canvas.addPaintListener(new PaintListener() {
                public void paintControl(PaintEvent e)
                {
                    long time = System.currentTimeMillis();
                    if (type == 1) {
                        e.gc.drawImage(getBuffer(false), 0, 0);
                    } else {
                        render(e.gc);
                    }
                    time = System.currentTimeMillis() - time;
                    if (time > 10) {
                        System.out.println(time);
                    }
                }
    
            });
            ps.add(new Point2D.Double(0, 0));
            ps.add(new Point2D.Double(800, 0));
            display.timerExec(500, timer);
        }
    
        Image getBuffer( boolean withRefresh)
        {
            Rectangle bounds = canvas.getBounds();
            if (image == null || !image.getBounds().equals(bounds)) {
                image = new Image(shell.getDisplay(), bounds);
                renderWithBuffer(image);
            } else if (withRefresh) {
                renderWithBuffer(image);
            }
            return image;
        }
        public void grow()
        {
            if (stopped) {
                return;
            }
    
            List<Point2D> temp = new ArrayList<Point2D>();
            temp.add(ps.get(0));
    
            for (int i = 0; i < ps.size() - 1; ++i) {
                Point2D p0 = ps.get(i);
                Point2D p4 = ps.get(i + 1);
                double len = GeometryUtil.distanceOfPoints(p0, p4);
    
                if (len < 0.1) {
                    // 当线条长度小于1时,就停止再增长
                    System.out.println(ps.size());
                    shell.getDisplay().timerExec(-1, timer);
                    return;
                }
    
                Point2D p1 = GeometryUtil.extentPoint(p0, p4, len / 3);
                Point2D p3 = GeometryUtil.extentPoint(p0, p4, len * 2 / 3);
                Point2D p2 = GeometryUtil.rotate(p3.getX(), p3.getY(), p1.getX(), p1.getY(), 60);
    
                temp.add(p1);
                temp.add(p2);
                temp.add(p3);
                temp.add(p4);
            }
    
            ps = null;
            ps = temp;
            temp = null;
            if (type == 1) {
                getBuffer(true);
            }
        }
    
        private void renderWithBuffer(Image image)
        {
            GC _gc = new GC(image);
            render(_gc);
            _gc.dispose();
        }
    
        private void render(GC gc)
        {
            Display display = shell.getDisplay();
            gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
            Rectangle bounds = canvas.getBounds();
            gc.fillRectangle(bounds);
            gc.setAdvanced(true);
            gc.setAntialias(SWT.ON);
    
            Transform transform = new Transform(display);
            transform.translate(0, bounds.height - 20);
            gc.setTransform(transform);
    
            gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
            for (int i = 0; i < ps.size() - 1; ++i) {
                Point2D sp = ps.get(i);
                Point2D ep = ps.get(i + 1);
                gc.drawLine((int) sp.getX(), -(int) sp.getY(), (int) ep.getX(), -(int) ep.getY());
            }
        }
    
        public static void main(String[] args)
        {
            Display display = Display.getDefault();
            Shell shell = new GrowingSWT(display).shell;
            shell.setSize(800, 400);
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
        }
    
    }
  • 相关阅读:
    Linux CentOS6环境下MySQL5.1升级至MySQL5.5版本过程
    linux卸载mysql
    springboot2.x+security对明文密码加密
    AJAX模拟登录注册
    Jedis工具类
    java连接Redis
    centOS 6.5 以及7以上的开启端口,以及重启防火墙指令
    Mybatis连接数据库错误he server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one
    Git clone时出现Please make sure you have the correct access rights and the repository exists.问题已解决。
    Spring Cloud-集群配置的eureka
  • 原文地址:https://www.cnblogs.com/stono/p/5016167.html
Copyright © 2011-2022 走看看