【Java】按钮数组波纹效果

简介

最近Java学到了布局管理器,看到GridLayout就很有意思,老师说可以做Excel表格什么的,心中突发奇想,于是就想做一个波纹状按钮效果(事后一想可能是我键盘光效的影响-。-),网上一搜,虽然有这个名词,但是和我想的不太一样。于是开始着手去做。

实现流程

  1. 布局界面
  2. 找到被点击的按钮
  3. 以该按钮为起点进行BFS,搜层次,
  4. 按照层次进行多线程染色

涉及到点

布局管理,按钮数组,多线程,延时,BFS

实现代码

点击查看代码
package test;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.LinkedList;
import java.util.Queue;

class MyLayout extends Frame implements ActionListener{
	
	//按钮数组大小
	private int ROWS = 10;
	private int COLS = 10;
	
	class MyButton extends Button{
		public int x,y;//按钮在数组中的下标
		public int deep;//按钮的层次
	}
	
	private MyButton btn[][] = new MyButton[ROWS][COLS];
	private int vis[][] = new int[ROWS][COLS];
	private Color a = new Color(252,157,154);//原始颜色
	private Color b = new Color(254,67,101);//点击颜色
	private int dir[][] = new int[][]{{0,1},{1,0},{0,-1},{-1,0}};
	
	public MyLayout() {
		//常规设置
		this.setTitle("波纹按钮效果示意");
		this.setSize(500, 500);
		this.setLayout(new GridLayout(ROWS,COLS));//网格状布局
		this.setResizable(false);//不可改变大小
		//设置窗口在屏幕中央
		Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
		int x = (int) screensize.getWidth() / 2 - this.getWidth() / 2;
		int y = (int) screensize.getHeight() / 2 - this.getHeight() / 2;	
		this.setLocation(x, y);
		//设置窗口可见
		this.setVisible(true);
		//使关闭窗口有效
		this.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				MyLayout.this.dispose();
			}
		});
		
		for(int i=0;i<ROWS;i++) {
			for(int j=0;j<COLS;j++) {
				btn[i][j] = new MyButton();
				btn[i][j].setBackground(a);
				btn[i][j].x = i;
				btn[i][j].y = j;
				btn[i][j].addActionListener(this);//注册监听
				this.add(btn[i][j]);
			}
		}
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		//获取按钮数组中点击按钮下标
		//通过坐标和长宽计算
		MyButton bt = (MyButton)e.getSource();
		int idx = bt.getY()/bt.getHeight();
		int idy = bt.getX()/bt.getWidth();
		goButton(idx, idy);
		init();
	}
	
	public void init(){
		for(int i=0;i<ROWS;i++){
			for(int j=0;j<COLS;j++){
				vis[i][j] = 0; //未访问过
			}
		}
	}
	public void changeColor(int x,int y,Color preColor,Color nextColor,int time) {
		//btn[x][y].setBackground(preColor);
		//延时
		new Thread() {
            public void run() {
            	btn[x][y].setBackground(preColor);
            	try {
//            		System.out.println("延时!+"+time+"end");
            		Thread.sleep(time);
                 } catch (InterruptedException e) {
                	 e.printStackTrace();
                 }
            	btn[x][y].setBackground(nextColor);
            	try {
//            		System.out.println("延时!+"+time+"end");
                    Thread.sleep(time);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
            	btn[x][y].setBackground(preColor);
            }
        }.start();
	}
	
	public void goButton(int idx,int idy) {
		//BFS
		Queue<MyButton> q = new LinkedList<MyButton>();
		btn[idx][idy].deep = 0;//起始点第0层
		q.offer(btn[idx][idy]);
		vis[idx][idy] = 1;
//		System.out.println(idx+","+idy+"被调用~");
		while(!q.isEmpty()) {
			MyButton head = q.poll();
			for(int i=0;i<4;i++) {
				int tx = head.x + dir[i][0];
				int ty = head.y + dir[i][1];
				if(judge(tx,ty)) {
					btn[tx][ty].deep = head.deep + 1;
					changeColor(tx,ty,a, b, btn[tx][ty].deep*50);
					q.offer(btn[tx][ty]);
//					System.out.println("改变颜色"+tx+','+ty+",   deep:"+(head.deep+1));
				}
			}
		}
//		System.out.println("size" + q.size());
	}
	
	public Boolean judge(int idx,int idy) {
		if(idx<0||idx>=ROWS||idy<0||idy>=COLS) return false;
		if(vis[idx][idy] == 1)return false; //用过了
		vis[idx][idy] = 1;
		return true;
	}
	
}
public class waterButton {
	public static void main(String[] args) throws Exception {
		/**
		 *	 实现的效果
		 *	点击一个按钮,然后引发连锁反应变颜色,类似水的波纹
		 */
		MyLayout ml = new MyLayout();
	}
	
}

颜色搭配

搭配1:
原:R:252,G:157,B:154
后:R:254,G:67,B:101

搭配2:
原:R:200,G:200,B:169
后:R:131,G:175,B:155

实现效果

后记

好了,前面装成大佬的样子,现在还原成弱鸡的真实面目,其实我写demo的时候卡住了,无法进展的那种,所以我去请教sc大佬,大佬和我一起讨论,解决问题,感觉很好,最后实际上大佬写出的demo,而大佬的代码再加上一行代码就能实现这个效果。哈哈不过还是很高兴的, 70%成就感啦, 也很开心。

但是在我分享的过程中(弱鸡获得成就感的方式),结果发现,有一个people已经知道了,我很奇怪,追问下去,发现她的朋友psj大佬已经发给她过了,原来sc专业大佬和psj学习大佬,竟然很熟悉!
我不仅感慨

强者还是喜欢和强者一块玩。

想我这种弱鸡,还是需要努力奋斗的。

成就感50%

也很开心啦,是自己一点一点写出来的东西,谁还不心疼呢。

不过,今天还被sc大佬夸奖博客好看

100%成就感

posted @ 2020-04-19 20:35  熊子q  阅读(138)  评论(0编辑  收藏  举报