package org.cctv2;
import java.awt.*;import java.awt.event.*;import javax.swing.*;class RaceMap extends JPanel implements Runnable
{ private int x=0,y=0; //bt的位置,也即控制的小方块的位置 private int w=15,h=15; //bt的宽,高 private int direction=0; //方向 private boolean tag=true; //结束标示符 JButton bt; //控制的小方块 Thread th; //线程,获得此线程,方便对象调用此线程 private double speed=1; //速度 private Color color=Color.BLACK; //中间框的颜色 //Icon icon; RaceMap() { //this.setSize(400, 400); setLayout(null);//要将布局管理器设为空,才能对里面的控件地方做设置 setBackground(Color.WHITE); bt=new JButton(); //bt.setIcon(icon); add(bt); bt.setBackground(Color.RED); //设置背景 //setBounds(100,100,400,400); bt.setBounds(0, 0, w, h); //设置初始地方 bt.addKeyListener(new KeyAdapter() //添加键盘监听,控制方向 { public void keyPressed(KeyEvent e) { if(e.getKeyCode()==KeyEvent.VK_UP) //上 { if(direction==0) //本身为向上时,加速 speed+=0.1; else if(direction==1) //本身为向下时,减速 { speed-=0.1; if(speed<=1) //减速到1时,反向向上 direction=0; } else //本身为向左或向右时,仅改变方向 direction=0; } else if(e.getKeyCode()==KeyEvent.VK_DOWN) //下 direction=1; else if(e.getKeyCode()==KeyEvent.VK_LEFT) //左 direction=2; else if(e.getKeyCode()==KeyEvent.VK_RIGHT) //右 direction=3; } }); th=new Thread(this);//获得此线程,方便下面对象直接启动此线程 } //要有继承Runnable或Thread才能用此,也即要有自己的线程 public void makeRun() { tag=true; Graphics g=getGraphics(); g.setColor(Color.MAGENTA);//这样画会容易被擦掉 g.fillOval(10, 10, 50, 50); bt.requestFocusInWindow(); //自动获得焦点,不用按TAB再获得 g.dispose(); } public void setSpeed(double speed) //设置速度 { this.speed=speed; bt.requestFocusInWindow(); //自动获得焦点,不用按TAB再获得 } public void setFillRectColor(String st) //设置中间矩形的颜色 { if(st.equals("蓝色")) color=Color.BLUE; else if(st.equals("绿色")) color=Color.GREEN; else color=Color.BLACK; repaint(); bt.requestFocusInWindow(); //自动获得焦点,不用按TAB再获得 } public void setButtonWidthHeigth(int w,int h) { this.w=w; this.h=h; bt.setSize(w, h); bt.requestFocusInWindow(); //自动获得焦点,不用按TAB再获得 } public void run() { bt.requestFocusInWindow(); //自动获得焦点,不用按TAB再获得 while(tag) { if(direction==0) //向上 跟的第2句是出边框时的操作 { //比如出上边框了就到最下面去 y-=speed; if(y+h<=1) y=this.getHeight(); } else if(direction==1) //向下 { y+=speed; if(y>=this.getHeight()) y=0; } else if(direction==2) //向左 { x-=speed; if(x+w<=1) x=this.getWidth(); } else //向右 { x+=speed; if(x>=this.getWidth()) x=0; } bt.setLocation(x, y); try { Thread.sleep(10); //控制速度 } catch(InterruptedException e) {} if(x+w>130&&x<330&&y+h>130&&y<330) //判断是否与中间矩形相碰 { tag=false; repaint(); x=0; y=0; } } } public void paint(Graphics g) { //g.setColor(Color.WHITE); //g.fillRect(0, 0, this.getWidth()-1, this.getHeight()-1); super.paint(g);//如果不写此,加的控件刚开始时不会显现 if(tag==true) g.setColor(color); //画笔 else g.setColor(Color.CYAN); g.fillRect(130, 130, 200, 200); //填充矩形 //g.fillRect(40, 40, 25, 25); if(tag==false) { g.setColor(Color.RED); g.drawString("游戏结束", this.getWidth()/2-30,this.getWidth()/2); } }}class UpPanel extends Panel
{ TextField tf; //速度 JButton bt1; //提交速度 JButton bt2; //开始 Choice ch; //指示中间框的颜色 Checkbox cb1; Checkbox cb2; Checkbox cb3; CheckboxGroup cbg; public UpPanel() { setLayout(new FlowLayout(FlowLayout.LEFT)); tf=new TextField(10); bt1=new JButton("提交速度"); bt2=new JButton("点我开始"); ch=new Choice(); ch.add("黑色"); ch.add("绿色"); ch.add("蓝色"); cbg=new CheckboxGroup(); cb1=new Checkbox("小",cbg,false); cb2=new Checkbox("中",cbg,true); cb3=new Checkbox("大",cbg,false); add(tf); add(bt1); add(bt2); add(ch); add(cb1); add(cb2); add(cb3); //bt1.addActionListener(new myActionPerformed(tf)); } }public class CarRace extends JFrame
{ RaceMap rm; //主面板 下面(实际是在Frame中间) //Button bt; //按钮 “点我开始” UpPanel upp; //面板2 上面 //Thread th; public CarRace() { super("RaceMapTest"); rm=new RaceMap(); //th=new Thread(rm); upp=new UpPanel(); upp.bt2.addActionListener(new myActionPerformed(rm)); upp.bt1.addActionListener(new myActionPerformed(upp.tf,rm)); upp.ch.addItemListener(new myItemListener(rm,upp.ch)); upp.cb1.addItemListener(new myItemListener(rm,upp.cb1)); upp.cb2.addItemListener(new myItemListener(rm,upp.cb2)); upp.cb3.addItemListener(new myItemListener(rm,upp.cb3)); //bt=new Button("点我开始"); upp.setBackground(Color.CYAN); //upp.add(bt); //bt.addActionListener(this); setBounds(100, 100, 500, 530); setLayout(new BorderLayout()); add(upp, BorderLayout.NORTH); add(rm,BorderLayout.CENTER); validate(); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { dispose(); System.exit(0); }});
setVisible(true); } public static void main(String []args) { new CarRace(); }}class myActionPerformed implements ActionListener
{ TextField tf; RaceMap rm; myActionPerformed(TextField tf,RaceMap rm) //此必须加上参数RaceMap { //要不会抛出异常 NullPointerException this.tf=tf; this.rm=rm; } myActionPerformed(RaceMap rm) { this.rm=rm; } public void actionPerformed(ActionEvent e) { JButton bt=(JButton)e.getSource(); if(bt.getText().equals("提交速度"))//判断 { String speed=tf.getText(); if(!(speed.equals(""))) { try { rm.setSpeed(Double.valueOf(speed)); } catch(NumberFormatException ee) { JOptionPane.showMessageDialog(rm,"输入的速度值非数字!"); } } else JOptionPane.showMessageDialog(rm,"没有输入速度值!"); } else if(bt.getText().equals("点我开始"))//判断 { try//点击一次按钮后再点会出现IllegalThreadStateException异常 { rm.th.start(); rm.validate(); } catch(IllegalThreadStateException ee) { rm.makeRun(); } } }}class myItemListener implements ItemListener
{ RaceMap rm; Choice ch; Checkbox cb; public myItemListener(RaceMap rm,Choice ch) { this.rm=rm; this.ch=ch; } public myItemListener(RaceMap rm,Checkbox cb) { this.rm=rm; this.cb=cb; } public void itemStateChanged(ItemEvent e) { if(e.getItemSelectable().equals(ch))//判断事件源是否为JComboBox { rm.setFillRectColor(e.getItem().toString()); //rm.setFillRectColor(ch.getSelectedItem());//这样也行 } else if(e.getItemSelectable().equals(cb))//判断事件源是否为 { //Checkbox if(e.getItem().toString().equals("小")) rm.setButtonWidthHeigth(10, 10); else if(e.getItem().toString().equals("大")) rm.setButtonWidthHeigth(20, 20); else if(e.getItem().toString().equals("中")) rm.setButtonWidthHeigth(15, 15); } }}