利用Java实现带GUI的气泡诗词特效

目录
  • 实现效果
  • 示例代码
    • AlgoVisualizer.java
    • AlgoFrame.java
    • Circle.java
    • AlgoVisHelper.java

实现效果

实现第个气泡中心显示一个字,在框中随意运动,用空格键按下运行停止,再按下左键运动继续。用鼠标左键按下选中的圆变为填充的,再次按下又变为不填充的。参考:https://github.com/liuyubobobo/

示例代码

AlgoVisualizer.java

import java.awt.*;
import java.awt.event.*;

public class AlgoVisualizer {
    private Object data;
    private Circle[] circles;
    private AlgoFrame frame;
    private boolean isAnmiated = true;

    public AlgoVisualizer(int sceneWidth, int sceneHeight, int N){

        circles = new Circle[N];
        int R = 50;

        for(int i = 0; i < N; i++)
        {
            int x = (int)(Math.random()*(sceneWidth-2*R)) + R;
            int y = (int)(Math.random()*(sceneHeight-2*R)) + R;

            int vx = (int)(Math.random()*11) - 5;
            int vy = (int)(Math.random()*11) - 5;
            circles[i] = new Circle(x, y, R, vx, vy);

        }

        EventQueue.invokeLater(()->{
             frame = new AlgoFrame("Welcome-Java", sceneWidth, sceneHeight);
             frame.addKeyListener(new AlgoKeyListener());
            frame.addMouseListener(new AlgoMouseListener());

            new Thread(()->{run();}).start();
        });
    }

    public AlgoVisualizer(int sceneWidth, int sceneHeight, int N, String centerLael){

        Circle.showLabel = true;

        circles = new Circle[N];
        int R = 50;

        for(int i = 0; i < N; i++)
        {
            int x = (int)(Math.random()*(sceneWidth-2*R)) + R;
            int y = (int)(Math.random()*(sceneHeight-2*R)) + R;

            int vx = (int)(Math.random()*11) - 5;
            int vy = (int)(Math.random()*11) - 5;
            circles[i] = new Circle(x, y, R, vx, vy);
            circles[i] = new Circle(x, y, R, vx, vy, centerLael.charAt(i) + "");

        }

        EventQueue.invokeLater(()->{
            frame = new AlgoFrame("Welcome-Java", sceneWidth, sceneHeight);
            frame.addKeyListener(new AlgoKeyListener());
            frame.addMouseListener(new AlgoMouseListener());
            new Thread(()->{
                run();
            }).start();
        });
    }

    private void run(){

        while(true)
        {
            //绘制当前数据
            frame.render(circles);
            AlgoVisHelper.pause(20);
            //更新数据
            if(isAnmiated)
            {
                for(Circle circle:circles)
                    circle.move(0, 0, frame.getCanvasWidth(), frame.getCanvasHeight());
            }
        }
    }

    private class AlgoKeyListener extends KeyAdapter {
        @Override
        public void keyReleased(KeyEvent event)
        {
            if(event.getKeyChar() == ' ')
            {
                isAnmiated = !isAnmiated;
            }
        }
    }

    private class AlgoMouseListener extends MouseAdapter{
        @Override
        public void mousePressed (MouseEvent event)
        {
            event.translatePoint(0,
//                    (frame.getBounds().height -frame.getCanvasHeight()));
                    -(frame.getBounds().height -frame.getCanvasHeight()));

//            System.out.println(event.getPoint());

            for(Circle circle:circles)
            {
                if(circle.contain(event.getPoint())){
                    circle.isFilled = !circle.isFilled;
                }

            }

        }
    }

    public static void main(String[] args) {

        String poemData = "三月七日沙湖道中遇雨。雨具先去,同行皆狼狈,余独不觉。已而遂晴,故作此词 \n" +
                "莫听穿林打叶声,何妨吟啸且徐行。竹杖芒鞋轻胜马,谁怕? 一蓑烟雨任平生。\n" +
                "料峭春风吹酒醒,微冷,山头斜照却相迎。回首向来萧瑟处,归去,也无风雨也无晴。";

        int sceneWidth = 800;
        int sceneHeight = 800;
        int N = 15;

//        AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight, N);
        AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight, N, poemData);

    }
}

AlgoFrame.java

import javax.swing.*;
import java.awt.*;

public class AlgoFrame extends JFrame {
    private int canvasWidth;
    private int canvasHeight;
    public AlgoFrame(String title, int canvasWidth, int canvasHeight){

        super(title);

        this.canvasHeight = canvasHeight;
        this.canvasWidth = canvasWidth;

        AlgoCanvas canvas = new AlgoCanvas();
        setContentPane(canvas);
        pack();

        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public AlgoFrame(String title){
        this(title, 1024, 768);
    }

    public int getCanvasWidth(){return  canvasWidth;}
    public int getCanvasHeight() {return canvasHeight;}

    private Circle[] circles;

    public void render(Circle[] circles)
    {
        this.circles = circles;
        repaint();
    }

    private Object data;
    public void render(Object data)
    {
        this.data = data;
        repaint();
    }
    private class AlgoCanvas extends JPanel{

        public AlgoCanvas(){
            super(true);
        }

        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            Graphics2D g2d =(Graphics2D)g;

            RenderingHints hints = new RenderingHints(
                    RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.addRenderingHints(hints);

            AlgoVisHelper.setStrokeWidth(g2d, 1);
            AlgoVisHelper.setColor(g2d, Color.RED);

            g2d.setFont( new Font("SimSun", Font.BOLD, 16));

            for (Circle circle: circles)
            {
                if(!circle.isFilled)
                {
                    AlgoVisHelper.strokeCircle(g2d, circle.x, circle.y, circle.getR() );
                }
                else
                {
                    AlgoVisHelper.fillCircle(g2d, circle.x, circle.y, circle.getR());
                }

                if(Circle.showLabel)
                {
//                    AlgoVisHelper.showPoem(g2d,circle.x, circle.y, circle.centerLabel);
                    AlgoVisHelper.drawText(g2d,circle.centerLabel,circle.x, circle.y);

                }
            }

        }

        @Override
        public Dimension getPreferredSize(){
//            System.out.println("Run getPreferredSize()");
            return new Dimension(canvasWidth, canvasHeight);
        }
    }
}

Circle.java

import java.awt.*;

public class Circle {
    public int x, y;
    private int r;
    public int vx, vy;
    public String centerLabel;
    static public boolean showLabel = false;
    public boolean isFilled = false;

    public Circle(int x, int y, int r, int vx, int vy)
    {
        this.x = x;
        this.y = y;
        this.r = r;
        this.vx = vx;
        this.vy = vy;
    }
    public Circle(int x, int y, int r, int vx, int vy, String centerLabel)
    {
        this.x = x;
        this.y = y;
        this.r = r;
        this.vx = vx;
        this.vy = vy;
        this.centerLabel = centerLabel;
    }
    public int getR(){return r;}

    public void move(int minx, int miny, int maxx, int maxy){
        x += vx;
        y += vy;

        checkCollision(minx, miny, maxx, maxy);
    }

    private void checkCollision(int minx, int miny, int maxx, int maxy) {
        if (x - r < minx) {
            x = r;
            vx = -vx;
        }
        if (x + r >= maxx) {
            x = maxx - r;
            vx = -vx;
        }
        if (y - r < miny) {
            y = r;
            vy = -vy;
        }
        if (y + r >= maxy) {
            y = maxy - r;
            vy = -vy;
        }

    }

    public boolean contain(Point p)
    {
        return (x - p.x) * (x - p.x) + (y - p.y)*(y - p.y) <= r*r;
    }

}

AlgoVisHelper.java

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;

public class AlgoVisHelper {
    private AlgoVisHelper(){}

    public static void setStrokeWidth(Graphics2D g2d, int w){
        int strokeWidth = w;
        g2d.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    }

    public static void strokeCircle(Graphics2D g2d, int x, int y, int r){
        Ellipse2D circle = new Ellipse2D.Double(x-r, y-r, 2*r, 2*r);
        g2d.draw(circle);
    }

    public static void fillCircle(Graphics2D g2d, int x, int y, int r){
        Ellipse2D circle = new Ellipse2D.Double(x-r, y-r, 2*r, 2*r);
        g2d.fill(circle);
    }

    public static void strokeRectangle(Graphics2D g2d, int x, int y, int w, int h)
    {
        Rectangle2D rectangle = new Rectangle2D.Double(x, y, w, h);
        g2d.draw(rectangle);
    }

    public static void fillRectangle(Graphics2D g2d, int x, int y, int w, int h)
    {
        Rectangle2D rectangle = new Rectangle2D.Double(x, y, w, h);
        g2d.fill(rectangle);
    }

    public static void putImage(Graphics2D g2d, int x, int y, String imageURL){
        ImageIcon icon = new ImageIcon(imageURL);
        Image image = icon.getImage();
        g2d.drawImage(image, x, y, null);
    }

    public  static void drawText(Graphics2D g2d, String text, int centerx, int centery)
    {
        if(text == null)
            throw new IllegalArgumentException("Text is null");

        FontMetrics metrics = g2d.getFontMetrics();
        int w = metrics.stringWidth(text);
        int h = metrics.getDescent();
        g2d.drawString(text, centerx - w/2, centery + h);
    }

    public static void showPoem(Graphics2D g2d,  int x, int y, String poem){

        g2d.drawString(poem,x, y);

//        g2d.drawString("醉", x, y);
    }
    public static void setColor(Graphics2D g2d, Color color){
        g2d.setColor(color);
    }

    public static void pause(int t)
    {
        try{
            Thread.sleep(t);
        }
        catch (InterruptedException e){
            System.out.println("Error in sleepping");
        }
    }

}

以上就是利用Java实现带GUI的气泡诗词特效的详细内容,更多关于Java气泡诗词的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java GUI实现多个窗口切换效果

    本文实例为大家分享了vue + element ui实现锚点定位的具体代码,供大家参考,具体内容如下 功能: 主要实现的功能为实现多个界面的切换,并且一个window的打开和关闭可以影响其他window. 不足: ①可以多次多开同一个界面(可以加一个变量控制)②没有实现一个的窗体关闭,它的子窗体也随即关闭的效果 效果图: 第一个界面(主界面) package 多界面跳转; import javax.swing.*; import java.awt.*; import java.awt.event

  • java实现动态图片效果

    本文实例为大家分享了java实现动态图片效果,供大家参考,具体内容如下 源码 package forGame; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; //动态效果 public class Demo_1 extends JF

  • Java实现万年历效果

    本文实例为大家分享了Java实现万年历效果的具体代码,供大家参考,具体内容如下 要求: 综合运用GUI编程.事件处理.Calendar类应用等知识设计一款月历,要求能通过输入(或选择)年月的方式正确显示当前月份的所有日期. 一.分析需求: 1.设计一个窗体,该窗体为BorderLayout布局:2.窗体的中心添加一个Panel容器:Panel容器的布局是7行7列的GridLayout布局,Panel容器中放置49个标签,用来显示日历:3.实现判断是否是闰年:4.计算某一个月的天数:5.明白一个月

  • Java实现动态日历效果

    本文实例为大家分享了Java实现动态日历效果的具体代码,供大家参考,具体内容如下 题目:动态日历 输入年份,月份,显示当前月份日历布局 分析 实现日历的基本思想为:确定一个基准日期,计算从基准日期到指定年份月份的前一个月的总天数,计算这个总天数的前提为判断指定年份是否是闰年(闰年是可以被400整除或者可以被4整除但不被100整除的年份),利用总天数除以7的余数可以确定当前月份前面的空格数,要想简单的使此余数为空格数,则基准日期必须为1月1日并且是星期一,大部分日历的基准日期为1900年1月1日,

  • java基于GUI实现简单画笔小画板

    在一块画板上实现鼠标点击画图案的功能(本文未实现拖动划线功能),供大家参考,具体内容如下 思路 与java设计GUI的大体思路一致, 先设置Frame类作为框架, 其中添加组件类作为功能补充. 该设计中需要设置鼠标监听类, 给frame加上组件 this.addMouseListener(new MyMouseListener()); 并自己实现一个监听类, implements需要重写所有方法, 所以使用适配器 private class MyMouseListener extends Mou

  • 利用Java实现带GUI的气泡诗词特效

    目录 实现效果 示例代码 AlgoVisualizer.java AlgoFrame.java Circle.java AlgoVisHelper.java 实现效果 实现第个气泡中心显示一个字,在框中随意运动,用空格键按下运行停止,再按下左键运动继续.用鼠标左键按下选中的圆变为填充的,再次按下又变为不填充的.参考:https://github.com/liuyubobobo/ 示例代码 AlgoVisualizer.java import java.awt.*; import java.awt

  • Java的带GUI界面猜数字游戏的实现示例

    先导包 import java.util.*; import javax.swing.*; 再写主方法 public static void main(String[] args) { } 新声明一个Scanner和随机数 public static void main(String[] args) { Scanner in = new Scanner(System.in); Random r = new Random(); } 让UIManager爬取系统窗口样式 try { UIManage

  • 利用java实现二维码和背景图的合并

    背景介绍: 最近我们这边需要做一个自动生成二维码并且还要将二维码嵌入现有的背景模板中,一直又没写过这些方面的东西,突然写还真是有点迷糊,特别是对于java图片API并不很熟悉,所以参考了很多网友的分享,很快做出来了,现在分享一下 注意: 关于二维码的生成方式在文章java生成带logo的多彩二维码已经写过了,大家可以合起来一起使用. 实例代码: BufferedImage image= bim;//二维码 BufferedImage bg= ImageIO.read(路径);//获取北京图片 G

  • Java定时任务:利用java Timer类实现定时执行任务的功能

    一.概述 在java中实现定时执行任务的功能,主要用到两个类,Timer和TimerTask类.其中Timer是用来在一个后台线程按指定的计划来执行指定的任务. TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务,具体要执行的代码写在TimerTask需要被实现的run方法中. 二.先看一个最简单的例子 我们通过代码来说明 import java.text.SimpleDateFormat; import java.util.Date; import java.util.T

  • 利用Java反射机制实现对象相同字段的复制操作

    一.如何实现不同类型对象之间的复制问题? 1.为什么会有这个问题? 近来在进行一个项目开发的时候,为了隐藏后端数据库表结构.同时也为了配合给前端一个更友好的API接口文档(swagger API文档),我采用POJO来对应数据表结构,使用VO来给传递前端要展示的数据,同时使用DTO来进行请求参数的封装.以上是一个具体的场景,可以发现这样子一个现象:POJO.VO.DTO对象是同一个数据的不同视图,所以会有很多相同的字段,由于不同的地方使用不同的对象,无可避免的会存在对象之间的值迁移问题,迁移的一

  • Java 生成带Logo和文字的二维码

    ZXing 是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库,它包含了联系到其他语言的端口.Zxing 可以实现使用手机的内置的摄像头完成条形码的扫描及解码.本章讲解用 ZXing 生成和扫码二维码. 依赖 在Java项目中pom.xml加入: <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version&g

  • 利用java实现二叉搜索树

    二叉搜索树的定义 它是一颗二叉树 任一节点的左子树上的所有节点的值一定小于该节点的值 任一节点的右子树上的所有节点的值一定大于该节点的值 特点: 二叉搜索树的中序遍历结果是有序的(升序)! 实现一颗二叉搜索树 实现二叉搜索树,将实现插入,删除,查找三个方面 二叉搜索树的节点是不可以进行修改的,如果修改,则可能会导致搜索树的错误 二叉搜索树的定义类 二叉搜索树的节点类 -- class Node 二叉搜索树的属性:要找到一颗二叉搜索树只需要知道这颗树的根节点. public class BST {

  • Java 由浅入深带你掌握图的遍历

    目录 1.图的遍历 2.深度优先遍历 3.利用DFS判断有向图是否存在环 4.广度优先遍历 1.图的遍历 从图中某一顶点出发访问图中其余顶点,且每个顶点仅被访问一次 图的遍历有两种深度优先遍历DFS.广度优先遍历BFS 2.深度优先遍历 深度优先遍历以深度为优先进行遍历,简单来说就是每次走到底.类似于二叉树的前序遍历 思路: 1.以某一个顶点为起点进行深度优先遍历,并标记该顶点已访问 2.以该顶点为起点选取任意一条路径一直遍历到底,并标记访问过的顶点 3.第2步遍历到底后回退到上一个顶点,重复第

  • 如何利用Java AWT 创建一个简易计算器

    目录 一.关于AWT 二.逻辑部分 1.对于数字按钮 2.对于算术按钮 3.对于等号按钮 4.对于清除按钮 5.对于退格按钮 6.特殊插件功能 7.==例如==: 三.GIF演示 四.附完整代码 摘要:手把手教你使用 Java AWT 创建一个简易计算器. 一.关于AWT AWT (抽象窗口工具包)是一个有助于构建 GUI 的 API (图形用户界面)基于 java 应用程序.GUI使用一些图形帮助用户交互.它主要由一组的类和方法所必需的,如在一个简化的方式创建和管理的GUI按钮,窗口,框架,文

  • Java实现简单GUI登录和注册界面

    本文实例为大家分享了Java实现简单GUI登录和注册界面的具体代码,供大家参考,具体内容如下 先看效果图: 登陆界面: 注册界面: 实现代码如下: 一.登陆界面 package cn.bms.view; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; imp

随机推荐