文档章节

【分形算法】Jason带你飞之3——java AWT菜单和button的事件响应

realsa
 realsa
发布于 2014/12/07 17:37
字数 1843
阅读 572
收藏 10

现在只剩下了最后10%的工作——添加菜单和按钮的功能。菜单栏可以选择两种模式:单一规则和随机规则模式;点击按钮实现单步迭代。

1、先来个简单的,菜单事件

1.1、问曰:什么是菜单事件?如何实现菜单事件?

答曰:我也不懂,但你一看下面的这个代码就懂了……{!参考http://blog.csdn.net/selena1122/article/details/37810579}

package myFenxing.release;

import java.awt.CheckboxMenuItem;
import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.MenuShortcut;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 * 简单的菜单项例子
 * 菜单条-----菜单-----菜单项
 * 其中,菜单中可以包含菜单,组成二级菜单
 * @author elena
 * @date 2014-7-15上午09:51:29
 * @version 1.0
 */
public class SimpleMenu {
	private Frame f = new Frame("菜单测试");
	private MenuBar mb = new MenuBar();
	Menu file = new Menu("文件");
	Menu edit = new Menu("编辑");
	MenuItem newItem = new MenuItem("新建");
	MenuItem saveItem = new MenuItem("保存");
	// 创建exititem菜单项,指定使用ctrl+x快捷键
	MenuItem exitItem = new MenuItem("退出", new MenuShortcut(KeyEvent.VK_X));
	CheckboxMenuItem autoWrap = new CheckboxMenuItem("自动换行");
	MenuItem copyiItem = new MenuItem("复制");
	MenuItem pasteItem = new MenuItem("粘贴");
	Menu format = new Menu("格式");
	// 创建commentem菜单项,指定使用ctrl+shift+/快捷键
	MenuItem commentItem = new MenuItem("注释", new MenuShortcut(
			KeyEvent.VK_SLASH, true));
	MenuItem cancelItem = new MenuItem("取消注释");
	private TextArea ta = new TextArea(6, 40);

	public void init() {
		// 以匿名内部类的形式创建菜单监听器
		ActionListener menuListener = new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				String cmd = e.getActionCommand();
				ta.append("单击" + cmd + "菜单" + "\n");
				if (cmd.equals("退出")) {
					System.exit(0);
				}

			}
		};
		commentItem.addActionListener(menuListener);
		exitItem.addActionListener(menuListener);
		// 为file菜单添加菜单项
		file.add(newItem);
		file.add(saveItem);
		file.add(exitItem);
		// 为edit菜单添加菜单项
		edit.add(autoWrap);// 自动换行
		// 使用addseparator方法来添加菜单分割线
		edit.addSeparator();
		edit.add(copyiItem);
		edit.add(pasteItem);
		// 为format菜单添加菜单项
		format.add(commentItem);
		format.add(cancelItem);
		// 使用添加new menuitem(”-“)的方式添加菜单分割线
		edit.add(new MenuItem("-"));
		// 将format菜单组合到edit菜单中,从而形成二级菜单
		edit.add(format);
		// 将file edit菜单添加到mb菜单条中
		mb.add(file);
		mb.add(edit);
		// 为窗体f设置菜单条
		f.setMenuBar(mb);
		// 以匿名内部类的形式创建事件监听器对象
		f.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				ta.append("用户试图关闭窗口\n");
				System.exit(0);
			}
		});
		f.add(ta);
		f.pack();
		f.setVisible(true);

	}

	public static void main(String[] args) {
		new SimpleMenu().init();
	}

}

1.2、覆写actionPerformed方法

@Override

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

String cmd = e.getActionCommand();

if (cmd.equals("退出")) {

System.exit(0);

}else if(cmd.equals("单一规则")){

//System.out.print("单一规则");

this.statement= "F"; mode=1; itemChange=true;

this.statement= this.caluStatement1(4);

this.reinit();

}else if(cmd.equals("随机规则")){

this.statement= "F"; mode=2; itemChange=true;

this.statement= this.caluStatement2(5);

this.reinit();

}else if(cmd.equals("技术支持")){

try { Process process = Runtime.getRuntime().exec("explorer http://my.oschina.net/SnifferApache/blog/353418");

 } catch (IOException IOe) {

  IOe.printStackTrace();

 }

}else if(cmd.equals("About 牛逼的树")){

JOptionPane.showMessageDialog(this, "LLC实验室制作\nhttp:gdauto.gdut.edu.cn/");

}

}

注意:选中某个模式之后,需要重新计算statement,并重新画图。同时还要改变按钮显示文字,所以要在reinit方法中添加

canvas.setStatement(statement);

canvas.repaint();

if(this.itemChange){

this.itemChange= false;

this.step= 1;//重置步骤数

button_step.setLabel("单步迭代");

            label_step.setText("       ");

}

而Canvas的repaint方法是在当前参数基础上重新画图,不满足需要,所以我们也要覆写repaint,添加

//清除旧的图像

repaint(0, 0, 0, getWidth(), getHeight());

//重置画图参数

pStartX =320;        //原始起始点340,20

    pStartY =20;

    direction_init =90;  // 作画时的初始方向

    direction =direction_init;

    lengthF =4.5;  //步长

    rotation =30;  //给定转角

2、单步迭代功能

根据当前的模式来决定单步实现哪个规则,计算新的statement,再次画图即可

//button的响应事件
	public boolean action(Event ev, Object arg){
		 if ( ev.target instanceof Button) {
		        String button = (String) arg;
		        if (button.equals("单步迭代")) {
		            button_step.setLabel("迭代一步");
		            label_step.setText("第"+step+"步");
		            this.statement= "F";
		            if(mode== 1){
		            	this.caluStatement1(1);
		            }else{
		            	this.caluStatement2(1);
		            }	            
		            this.reinit();
		        }
		        if (button.equals("迭代一步")){
		        	step++;
		            label_step.setText("第"+step+"步");
		            this.statement= "F";
		            if(mode== 1){
		            	this.caluStatement1(step);
		            }else{
		            	this.caluStatement2(step);
		            }
		            this.reinit();
		        }
		        return true;
		 }else return false;
		}


3、最终版的全部源码和功能截图

package myFenxing.UI;
/**
 * @author Jason 
 * @Corp LLC lab
 * @version LS grammar implementation
 */
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.IOException;
import java.util.Vector;

import javax.swing.JOptionPane;

//画布
class MyCanvas extends Canvas{
	String statement;		//LS文法表达式
	int pStartX =320;        //起始点340,20
    int pStartY =20;
    double direction_init =90;  // 作画时的初始方向
    double direction =direction_init;
    double lengthF =4.5;
    double rotation =30;
    int StartDepth =7;     //画图深度
    doublePoint a, b;       // 画线段所需的两点
	MyCanvas(){
		setBackground(Color.black);
	}
	public void setStatement(String s){
		this.statement= s;
	}
	//改变窗口大小的时候会调用此方法重新绘图
	public void paint(Graphics g){
		//System.out.print("\n"+this.statement);
		a = new doublePoint(pStartX,pStartY); // 起始点
		g.setColor(new Color(110,170,60)); // 定义画笔的颜色绿色
		draw(g,this.statement);
	}
	//核心方法
	public void draw(Graphics g, String statement){
	        Vector aPoint = new Vector();//用堆栈记录[]中的内容
	        Vector aDirection = new Vector();
	        String sDirection;

	        int i;
	        int j;
	        char c; 	//System.out.print("\ndraw length "+statement.length());
	        for (i=0;i<statement.length();i++) {
	        	//获取公理中第i个字符,即解释instruction
	            c = statement.charAt(i);
				if (c=='F') {
		                double rad = 2*Math.PI*direction/360 ; // 角度转换
		                double p = lengthF * Math.cos(rad);
		                double q = lengthF * Math.sin(rad);
		                b = new doublePoint(a.x+p, a.y+q);
		                //g=this.getGraphics();
		                g.drawLine((int)(a.x), (int)(400-a.y), (int)(b.x) ,(int)(400-b.y));
		                a = b; // 前一线段的终点为后一线段的起始点            
		        }
		        else if (c=='+') direction += rotation; //逆时针转角度
		        else if (c=='-') direction -= rotation; //顺时针转角度
		        else if (c=='[') {  //入栈
		            aPoint.addElement(a);
		            sDirection = String.valueOf(direction);
		            aDirection.addElement(sDirection);
		        }
		        else if (c==']') {  //出栈
		            a=(doublePoint)(aPoint.elementAt(aPoint.size()-1));
		            sDirection=(String)(aDirection.elementAt(aDirection.size()-1));
		            direction=Double.valueOf(sDirection).doubleValue();
		            aPoint.removeElementAt(aPoint.size()-1);
		            aDirection.removeElementAt(aDirection.size()-1);
		        }
	        }//System.out.print("\ndraw over;");
		}
	@Override
	public void repaint(){
		//清除旧的图像
		repaint(0, 0, 0, getWidth(), getHeight());
		 //重置画图参数
		 pStartX =320;        //起始点340,20
	     pStartY =20;
	     direction_init =90;  // 作画时的初始方向
	     direction =direction_init;
	     lengthF =4.5;
	     rotation =30;
	     this.paint(getGraphics());
	}
}
//窗口
class MyWindow extends Frame implements ActionListener{
	MyCanvas canvas= new MyCanvas();
	//在画布中绘图的起始点340,20
	int pStartX =320;        
    int pStartY =20;
	Panel pSouth= new Panel();
	MenuBar menubar= new MenuBar();
	Menu menu1= new Menu("文件"); Menu mn_mode= new Menu(); Menu help= new Menu("帮助");
	MenuItem item1= new MenuItem("退出");
	MenuItem mn_mode_1= new MenuItem(); MenuItem mn_mode_2= new MenuItem();
	MenuItem help_1= new MenuItem("技术支持"); MenuItem help_2= new MenuItem("About 牛逼的树");
	
	Choice choice= new Choice();		
	Button button_step= new Button("单步迭代");
	Label label_step= new Label("          ");
	Label info= new Label("LLC LAB");
	//LS文法需要的变量
	String statement,replacement;  
	int step=1;//单步迭代的步骤
	int mode=2;//模式1:单一规则,模式2:随机规则
	boolean itemChange= false;//false表示item没有改变
    String sStart;           //公理;起始字符串
    String sRule[][];        //存储规则
    //构造方法
	MyWindow(){
		//默认状态下的公理
		sStart = "F";//给公理赋值
		statement= sStart; replacement= "F[+F]F[-F]F" ;
	  	//用来随机抽取,绘制随机植物
	    sRule = new String [10][2];		    
		//设置UI 
		setBackground(Color.lightGray);
		choice.addItem("牛逼的树");
		pSouth.add(choice);
		pSouth.add(button_step);
		pSouth.add(label_step);
		pSouth.add(info);
		add(canvas,BorderLayout.CENTER);
		add(pSouth,BorderLayout.SOUTH);
		//设置menu		
		this.setMenuBar(menubar);		
		menubar.add(menu1); menubar.add(mn_mode); menubar.add(help);
		menu1.add(item1);
		mn_mode.add(mn_mode_1); mn_mode.add(mn_mode_2); help.add(help_1); help.add(help_2);
		mn_mode.setLabel("生成模式");
		mn_mode_1.setLabel("单一规则"); mn_mode_2.setLabel("随机规则");
		item1.addActionListener(this);
		mn_mode_1.addActionListener(this);
		mn_mode_2.addActionListener(this);
		help_1.addActionListener(this);
		help_2.addActionListener(this);
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		//略	
	}
	//button的响应事件
	public boolean action(Event ev, Object arg){
		 if ( ev.target instanceof Button) {
		        String button = (String) arg;
		        //略
		 }else return false;
		}
	//响应关闭操作
	protected void processWindowEvent(WindowEvent e) {
        super.processWindowEvent(e);
        if (e.getID() == WindowEvent.WINDOW_CLOSING) {
          System.exit(0);
        }
      }
	//窗口名称
    public synchronized void setTitle(String title) {
        super.setTitle(title);
        enableEvents(AWTEvent.WINDOW_EVENT_MASK);
      }
	
	public void init() {
		//将计算出的statement传递给画布
		canvas.setStatement(statement);		
		this.setSize(pStartX*2,550);
	    //获得屏幕长和宽,dimension类在一个单一对象中封装组建的宽和高
	    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
	    this.setLocation((d.width - this.getSize().width) / 2, (d.height - this.getSize().height) / 2);
	    this.setVisible(true);  
	}
	//操作之后刷新
	public void reinit(){
		//将计算出的statement传递给画布
		canvas.setStatement(statement);
		canvas.repaint();
		if(this.itemChange){
			this.itemChange= false;
			this.step= 1;//重置步骤数
			button_step.setLabel("单步迭代");
            label_step.setText("       ");
		}
	}
	/**计算LS表达式*/
        //略
/**Main method*/
public class randomLS {
	public static void main(String args[]){
		MyWindow instance= new MyWindow();
		instance.setTitle("牛逼的树");
		instance.statement= instance.caluStatement2(5);
		instance.init();
	}
}

效果图




© 著作权归作者所有

realsa

realsa

粉丝 33
博文 84
码字总数 107087
作品 0
广州
程序员
私信 提问
加载中

评论(2)

realsa
realsa 博主

引用来自“张涛OSC”的评论

又见AWT人才,赶快转Android吧

13我也觉得java写图形界面逗逼的,但一方面要完成老师任务,另一方面思路和知识点对于初学者java的同学会有一点启发吧
kymjs张涛
kymjs张涛
又见AWT人才,赶快转Android吧
OSChina 技术周刊第十三期 —— 每周技术精粹

每周技术抢先看,总有你想要的! 移动开发 【翻译】appcompat v21: 让 Android 5.0 前的设备支持 Material Design... 【软件】可直接商用的《动漫之家》APP 开源,基于 CrossApp! 【博客】i...

OSC编辑部
2014/12/14
5.7K
3
Google 网页工具包的网友评论

Google 网页工具包——GWT 提供了一组基于Java语言的开发包,这个开发包的设计参考Java AWT包设计,类命名规则、接口设计、事件监听等都和AWT非常类似。熟悉Java AWT的开发者不需要花费多大的...

红薯
2009/12/11
581
2
Google网页工具包 GWT 2.1.1 发布

Google 网页工具包——GWT 提供了一组基于Java语言的开发包,这个开发包的设计参考Java AWT包设计,类命名规则、接口设计、事件监听等都和AWT非常类似。熟悉Java AWT的开发者不需要花费多大的...

绿悠悠
2010/12/20
1K
1
细说Java GUI:AWT,SWT,Swing

历史 Internet上有许多围绕这一争论的故事。你可能已经听说过它们中的大多数了,其中之一有助于让你理清头绪,让我们就从这里开始,Amy Fowler是Swing阵营的一个倡导者。 回到上个世纪90年代...

javasql
2014/02/05
5.3K
3
GWT 2.8.0 RC1 发布,Google 网页工具包

GWT 2.8.0 RC1 发布了,Google 网页工具包——GWT 提供了一组基于Java语言的开发包,这个开发包的设计参考Java AWT包设计,类命名规则、接口设计、事件监听等都和AWT非常类似。熟悉Java AWT的...

杨S
2016/08/02
1K
8

没有更多内容

加载失败,请刷新页面

加载更多

javaagent使用demo详解

javaagent又称java探针,结合javassist或asm等框架对字节码文件进行操作,从而更优雅的实现“AOP”等功能,减少对原代码的侵入性等。从而我们可以借此来实现微服务等的全链路追踪以及项目环境...

xiaomin0322
31分钟前
3
0
jar包是怎么提交到Spark上运行的

我们都知道,写好spark程序后,可以通过命令行spark-submit方式提交到集群,那么这个具体的过程是怎么搞得呢? spark有多种集群方式,如yarn,standalone等。提交方式又分为client和cluster...

守望者之父
45分钟前
5
0
最好的重试是指数后退和抖动

1. 概述 在本教程中,我们将探讨如何使用两种不同的策略改进客户端重试:指数后退和抖动。 2. 重试 在分布式系统中,多个组件之间的网络通信随时可能发生故障。 客户端应用程序通过实现重试来...

liululee
56分钟前
5
0
聊一聊大厂内部的安全管理机制

工作了两个月了体会到了很多之前做外包小项目没有的东西,不得不说大厂的还是有自己一套的完善的体制,不会像B站那样泄露自己整个后台的源码这种事情发生。 电脑办公 比如说在使用电脑办公这...

gzc426
今天
7
0
如何利用deeplearning4j中datavec对图像进行处理

NativeImageLoader Labelloader = new NativeImageLoader(112, 112, 3,new FlipImageTransform(-1)); 一、导读 众所周知图像是有红绿蓝三种颜色堆叠而成,利用deeplearning对图像处理,必须把...

冷血狂魔
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部