??????? 每个人都有追求美的愿望,程序员在其他人眼中也许就是整天宅在寝室,厚厚的眼睛片,半个月不洗澡不洗头,可以用蓬头垢面来形容,但我觉得并不是这样,我觉的每个程序员都是艺术家,画家用笔来勾勒美丽的画面,音乐家用乐器奏出美丽的乐符,而我们程序员可以用代码来改变世界,用代码来画出美丽的画面,代码就是我们的绘画工具,我们画出的东西可以完爆艺术系的小男生小女生。下面向大家来抛出一个石头,希望广大IT工作者能在代码中找到乐趣,也变得有艺术气息一些,用自己的双手敲出震撼艺术系小女生的奇幻图片。
?????? 本人目前是一个刚刚涉足Java的初学者,前面做了一个画图板http://mntms.iteye.com/blog/1961426,因此也对Java类库中的绘图类和颜色类(Color)有了一定了解,今天想和大家分享一下在画平面图的基础上绘制一些简单的3D图片出来,在无聊的代码世界中让自己也眼前亮一下。下面介绍一下我制作的简单3D图画板。
?????? 这个画板一共分四个区域,每个区域可以画一种图片,点击相应区域内的按钮执行相应的动作,下面是运行的总体效果(点击全部按钮后):
?????
?点击删除渐变线按钮后效果如下:
?
????? 接下来具体和大家分享一下实现方法和步奏(代码上已经详细注释):
?????
class="java">package 简单的3D; import java.awt.Color; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; /** * 创建一个Draw3D的类,继承JFrame类,同时实现动作监听器,这样 * 就不需要再写一个监听器类,也不用传参(传画布对象)也不用生成监听器对象 */ public class Draw3D extends JFrame implements ActionListener { //入口函数 public static void main(String[] args) { //创建对象并调用类的初始化画板的方法 Draw3D draw = new Draw3D(); draw.init(); } //初始化画板的方法 public void init() { this.setTitle("3D画图板"); this.setSize(800,760); this.setDefaultCloseOperation(3); //使窗体的位置居中 this.setLocationRelativeTo(null); //将窗体的默认的布局取消,才能使用setBounds()方法将四个面板插入到指定的位置 this.setLayout(null); //将窗体分成四个区域(四个面板),并将每个面板的背景色设置成黑色,更能体现艺术的效果 jp1 = new JPanel(); jp1.setBackground(Color.black); jp1.setBounds(0,0,400,380); jp2 = new JPanel(); jp2.setBackground(Color.black); jp2.setBounds(400, 0, 400, 380); jp3 = new JPanel(); jp3.setBackground(Color.black); jp3.setBounds(0, 380, 400, 380); jp4 = new JPanel(); jp4.setBackground(Color.black); jp4.setBounds(400, 380,400, 380); //将每个面板的默认的布局取消,才能使用setBounds()方法插入相应的按钮组件 jp1.setLayout(null); jp2.setLayout(null); jp3.setLayout(null); jp4.setLayout(null); //给每个面板添加控制按钮,是用setBounds()将按钮组件安放到指定的位置 //此处使用setBounds()时要注意的是设置坐标的时候是相对于每块面板的,而不是整个窗体 JButton buC1 = new JButton("删除"); JButton buC2 = new JButton("删除"); JButton buC3 = new JButton("删除"); JButton buC4 = new JButton("删除"); //插入按钮的位置应该相对于每个面板,而不是整个窗体 buC1.setBounds(280, 10,80, 20); buC2.setBounds(280, 10,80, 20); buC3.setBounds(280, 10,80, 20); buC4.setBounds(280, 10,80, 20); JButton bu1 = new JButton("立体矩"); bu1.setBounds(80, 10,80, 20); jp1.add(bu1); jp1.add(buC1); JButton bu2 = new JButton("立体球"); bu2.setBounds(80, 10, 80, 20); jp2.add(bu2); jp2.add(buC2); JButton bu3 = new JButton("体三角"); bu3.setBounds(80, 10, 80, 20); jp3.add(bu3); jp3.add(buC3); JButton bu4 = new JButton("渐变线"); bu4.setBounds(80, 10, 80, 20); jp4.add(bu4); jp4.add(buC4); //给每个按钮添加命令 bu1.setActionCommand("3DRect"); bu2.setActionCommand("3DOval"); bu3.setActionCommand("Prim"); bu4.setActionCommand("litix"); //用数字分别代表每个画板上的caozuo.html" target="_blank">删除操作clear1代表删除立体矩,clear2代表删除立体球 //clear3代表删除体三角,clear4代表删除渐变线 buC1.setActionCommand("clear1"); buC2.setActionCommand("clear2"); buC3.setActionCommand("clear3"); buC4.setActionCommand("clear4"); //给每个按钮添加监听器 bu1.addActionListener(this); bu2.addActionListener(this); bu3.addActionListener(this); bu4.addActionListener(this); buC1.addActionListener(this); buC2.addActionListener(this); buC3.addActionListener(this); buC4.addActionListener(this); //添加两条分界线,划分出四个区域 JButton bu6 = new JButton(); bu6.setBackground(Color.blue); bu6.setBounds(400, 5, 1, 780); JButton bu7 = new JButton(); bu7.setBackground(Color.blue); bu7.setBounds(3, 380, 780, 1); //将四块面板添加到窗体上 this.add(jp1); this.add(jp2); this.add(jp3); this.add(jp4); this.add(bu6); this.add(bu7); this.setVisible(true); //给每个面板获取画布对象,对应相应的面板 g1 = jp1.getGraphics(); g2 = jp2.getGraphics(); g3 = jp3.getGraphics(); g4 = jp4.getGraphics(); } /** * 重写动作监听器中的方法,实现点击不同的按钮执行相应的操作,通过e.getActionCommand() * 来判断点击的是哪个按钮并执行 */ public void actionPerformed(ActionEvent e) { if(e.getActionCommand().equals("3DRect")) { //画3DRect使用循环绘制矩形,同时改变矩形的大小并改变颜色,实现3D的效果 for(int i = 0; i <=100; i++) { int m =i; g1.setColor(new Color(2*i,2*i,i)); g1.drawRect(50+m, 50+m, 250-2*m, 250-2*m); } } else if(e.getActionCommand().equals("3DOval")) { //画3DOval,使用fillOval()方法,同时循环改变大小和颜色 for(int m = 0; m <= 100; m++) { g2.setColor(new Color(m,2*m,m)); g2.fillOval(50+m, 50+m,250-2*m, 250-2*m); } } else if(e.getActionCommand().equals("Prim")) { //画体三角,首先做一个三角形,在此基础上循环,并改变颜色 for(int m = 0; m <= 250; m++) { g3.setColor(new Color(m,m,250)); g3.drawLine(200, 40+m, 20+m,300-m ); g3.setColor(new Color(m,250,m)); g3.drawLine(200, 40+m, 380-m, 300-m); g3.setColor(new Color(250,m,m)); g3.drawLine(380-m, 300-m,20+m , 300-m); } }else if(e.getActionCommand().equals("litix")) { //画渐变线,在一条的基础上实现长度和颜色的渐变 for(int m = 0; m <= 240; m++) { g4.setColor(new Color(20,m,250)); g4.drawLine(80+m,300-m,250-m ,300-m); } } //删除动作的实现,使用每个面板的背景色来作为绘图颜色绘制指定大小的fillRect图形,从而覆盖原来画的图形,实现删除 else if(e.getActionCommand().equals("clear1")) { g1.setColor(jp1.getBackground()); g1.fillRect(40, 40, 290, 290); }else if(e.getActionCommand().equals("clear2")) { g2.setColor(jp2.getBackground()); g2.fillRect(40, 40, 290, 290); }else if(e.getActionCommand().equals("clear3")) { g3.setColor(jp3.getBackground()); g3.fillRect(20, 40, 380, 290); }else if(e.getActionCommand().equals("clear4")) { g4.setColor(jp4.getBackground()); g4.fillRect(10, 40, 380, 290); } } //将画布对象和面板对象设置成Draw3D类的私有属性,实现在类中不同方法中的使用 private Graphics g1; private Graphics g2; private Graphics g3; private Graphics g4; private JPanel jp1; private JPanel jp2; private JPanel jp3; private JPanel jp4; }
????
?? ?如果不给每个面板设置背景色,绘制的效果如下:
?
???? 虽然实现的方法很简单,但是还是希望初学者们或者已经学有所成的老程序员们去做一做,因为从中我们能感受到Java给我们带来的乐趣,我们用代码也可以绘制出迷人的图画,只要敢于尝试,敢于想象,当自己面前出现奇幻的图像时还是会被自己感动的,我觉得作为初学者的我们就要先从java中找到学习它的乐趣,那样我们才会有坚持下去的动力,培养自己的兴趣很重要,兴趣是最好的老师。
?
?
?
?
?
?
?
?
?
?