GUI编程
1、简介
Gui的核心技术:Swing、AWT
界面不美观
需要jre环境
为什么要学习?
可以写出自己想要的小工具
工作时候,也可能需要维护到swing界面
了解MVC架构,了解监听
(小游戏贪吃蛇代码在最底下,可直接拉到最后)
2、AWT
2.1AWT介绍
包含了很多类和接口! GUI:界面图形
元素:窗口、按钮、文本框
2.2组件和容器
1、Frame
public class TestFrame {public static void main(String[] args) {Frame frame = new Frame("java图像窗口");//设置窗口界面大小frame.setSize(200,200);//设置窗口可见性frame.setVisible(true);//设置窗口初始坐标 左上角原始坐标(0,0)frame.setLocation(100,100);//设置背景颜色frame.setBackground(new Color(191, 34, 191));//设置窗口固定frame.setResizable(false);}}
创建多个窗口,自己创建对象
public class MyFrame {public static void main(String[] args) {TestFrame1 testFrame1 = new TestFrame1(100,100,200,200,Color.blue);TestFrame1 testFrame2 = new TestFrame1(300,100,200,200,Color.yellow);TestFrame1 testFrame3 = new TestFrame1(100,300,200,200,Color.green);TestFrame1 testFrame4 = new TestFrame1(300,300,200,200,Color.darkGray);}}class TestFrame1 extends Frame{//继承Frame父类所有方法static int id =0;//可能存在多个窗口,创建一个计数器变量public TestFrame1(int x,int y,int w,int h,Color color){//构造一个有参构造器,让对象可以实例化super("Myframe"+(++id));//直接调用父类方法 super() ,++id计数器,每增加一个窗口名字都不同setBackground(color);//设置窗口颜色setVisible(true);//设置窗口可见性setBounds(x,y,w,h);//设置窗口大小和初始位置setResizable(false);//设置窗口固定}}
2、面板Panel
//Panel可以看成是一个空间,但是不能单独存在public class TestPanel {public static void main(String[] args) {Frame frame = new Frame();//布局的概念Panel panel = new Panel();//设置布局frame.setLayout(null);//设置大小、坐标和颜色frame.setBounds(300,300,300,300);frame.setBackground(new Color(222, 22, 22));//设置窗口可见性frame.setVisible(true);//panel设置坐标,相对于framepanel.setBounds(50,50,200,200);panel.setBackground(new Color(24, 220, 104));//frame.add(panel)frame.add(panel);//关闭窗口,设定一个监听窗口关闭事件 相当于System.exit(0)frame.addWindowListener(new WindowAdapter(){//窗口点击关闭的时候需要做得事情@Overridepublic void windowClosing(WindowEvent e) {//结束程序System.exit(0);}});}}
2.3、布局管理器
流式布局
public class TestFlowLayout {public static void main(String[] args) {Frame frame = new Frame();//组件-按钮Button button1 = new Button("button1");Button button2 = new Button("button2");Button button3 = new Button("button3");//设置为流式布局//frame.setLayout(new FlowLayout());//center居中frame.setLayout(new FlowLayout(FlowLayout.LEFT));//靠左frame.setSize(200,200);frame.setVisible(true);//把按钮添加进去frame.add(button1);frame.add(button2);frame.add(button3);}}
东西南北中
public class TestBordeLayout {public static void main(String[] args) {Frame frame = new Frame();frame.setVisible(true);frame.setSize(300,300);Button east = new Button("East");Button west = new Button("West");Button south = new Button("South");Button north = new Button("North");Button center = new Button("Center");frame.add(east,BorderLayout.EAST);frame.add(west,BorderLayout.WEST);frame.add(south,BorderLayout.SOUTH);frame.add(north,BorderLayout.NORTH);frame.add(center,BorderLayout.CENTER);}}
表格布局
public class TestGridLayout {public static void main(String[] args) {Frame frame = new Frame();frame.setVisible(true);frame.setSize(300,300);Button btn1 = new Button("btn1");Button btn2 = new Button("btn2");Button btn3 = new Button("btn3");Button btn4 = new Button("btn4");Button btn5 = new Button("btn5");Button btn6 = new Button("btn6");frame.setLayout(new GridLayout(3,2));frame.add(btn1);frame.add(btn2);frame.add(btn3);frame.add(btn4);frame.add(btn5);frame.add(btn6);frame.pack();//自动填充,JAVA函数,可写可不写}}
2.4、练习
public class TestLayout {public static void main(String[] args) {Frame frame = new Frame();//创建窗口frame.setVisible(true);frame.setSize(400,400);frame.setBackground(Color.blue);//先将窗口分为上下两部分frame.setLayout(new GridLayout(2,1));//再创建四个面板,总体上下两个面板,中间上下两个面板Panel p1 = new Panel(new BorderLayout());Panel p2 = new Panel(new GridLayout(2,1));//上面,构造一个两行一列的面板Panel p3 = new Panel(new BorderLayout());Panel p4 = new Panel(new GridLayout(2,2));//下面,构造一个两行两列的面板//创建所需要的按钮,可优化进面板里面Button east1 = new Button("east1");Button east2 = new Button("east2");Button west1 = new Button("west1");Button west2 = new Button("west2");Button b1 = new Button("button1");Button b2 = new Button("button2");Button b3 = new Button("button3");Button b4 = new Button("button4");Button b5 = new Button("button5");Button b6 = new Button("button6");//上面部分frame.add (p1);//东边p1.add(east1, BorderLayout.EAST);//西边p1.add(west1, BorderLayout.WEST);p2.add(b1);p2.add(b2);p1.add(p2);//下面部分frame.add (p3);p3.add(east2, BorderLayout.EAST);p3.add(west2, BorderLayout.WEST);p4.add(b3);p4.add(b4);p4.add(b5);p4.add(b6);p3.add(p4);}}
2.5、事件监听
public class TestActionEvent {public static void main(String[] args) {//按下按钮,触发一些事件Frame frame = new Frame("ActionEventListener");frame.setSize(400, 400);frame.setVisible(true);Button b1 = new Button("button");frame.add(b1, BorderLayout.CENTER);//因为addActionListener()需要一个ActionListener,所以需要构造一个ActionListenerMyActinonListener myActinonListener = new MyActinonListener();//将构造的MyActinon实例化b1.addActionListener(myActinonListener);windowclose(frame);//调用关闭窗口方法}//关闭窗口事件private static void windowclose(Frame frame){frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}}//事件监听class MyActinonListener implements ActionListener{//接口实现类,必须重写方法@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("aaa");;}}
多个按钮实现一个监听事件
public class TestActionEvent02 {public static void main(String[] args) {Frame frame = new Frame();frame.setSize(400,400);frame.setVisible(true);windowclose(frame);//多个按钮实现一个监听事件Button b1 = new Button("button1");Button b2 = new Button("button2");frame.add(b1,BorderLayout.NORTH);frame.add(b2,BorderLayout.SOUTH);MyActionListener myActionListener = new MyActionListener();b1.addActionListener(myActionListener);b2.addActionListener(myActionListener);//可以显示的定义触发会返回的命令,如果不显示定义,则会走默认值 b1输出button1,b2输出stopb2.setActionCommand("stop");}//窗口关闭事件private static void windowclose(Frame frame){frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);}});}}class MyActionListener implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {//e.getActionCommand()获得按钮信息System.out.println("按钮被点击了=>"+e.getActionCommand());}}
2.6、输入框TextField监听
public class TestTextEvent {public static void main(String[] args) {//只管启动new Myframe();}}class Myframe extends Frame {public Myframe(){setVisible(true);setSize(400,400);TextField textField = new TextField();add(textField);//监听这个文本框输入的文字MyActionListener3 myActionListener3 = new MyActionListener3();//按下enter 就会触发这个输入框的事件textField.addActionListener(myActionListener3);//设置替换编码textField.setEchoChar('*');//将输入的文本替换成*,加密}}class MyActionListener3 implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {//e.getSource()默认是Object,所以需要TextField强制转换 高转低TextField field = (TextField) e.getSource();//获得一些资源,返回一个对象System.out.println(field.getText());//获得输入框文本field.setText("");//null,输入enter自动清空输入框}}
2.7、简易计算器、组合和内部类
初始代码
public class TestCaculator {public static void main(String[] args) {new MyCaculator();}}//计算器类class MyCaculator extends Frame {public MyCaculator(){//无参构造setVisible(true);pack();//自适应调整布局//3个文本框TextField num1 = new TextField(10);//10代表字符数,文本框长度TextField num2 = new TextField(10);TextField num3 = new TextField(20);//1个按钮Button button = new Button("=");//监听按钮事件button.addActionListener(new MyActionListenter(num1,num2,num3));//1个标签Label label = new Label("+");setLayout(new FlowLayout());add(num1);add(label);add(num2);add(button);add(num3);}}//监听类class MyActionListenter implements ActionListener{//获取三个变量private TextField num1,num2,num3;public MyActionListenter(TextField num1,TextField num2,TextField num3) {this.num1 =num1;this.num2 =num2;this.num3 =num3;}@Overridepublic void actionPerformed(ActionEvent e) {//1、获得加数和被加数int a = Integer.parseInt(num1.getText());//强制转换变量类型进行运算int b = Integer.parseInt(num2.getText());//2、运行加法运算并获取值num3.setText(""+(a+b));//3、按下等号后,清空第一和第二个文本框值num1.setText("");num2.setText("");}}
优化代码1:组合方法(完全面向对象)
public class TestCaculator {public static void main(String[] args) {MyCaculator myCaculator = new MyCaculator();myCaculator.method();}}//计算器类class MyCaculator extends Frame {//属性TextField num1,num2,num3;//方法public void method(){setVisible(true);pack();//自适应调整布局//3个文本框num1 = new TextField(10);//10代表字符数,文本框长度num2 = new TextField(10);num3 = new TextField(20);//1个按钮Button button = new Button("=");//监听按钮事件button.addActionListener(new MyActionListenter(this));//1个标签Label label = new Label("+");setLayout(new FlowLayout());add(num1);add(label);add(num2);add(button);add(num3);}}//监听类class MyActionListenter implements ActionListener{//获取计算器的对象,在一个类中组合另外一个类MyCaculator myCaculator = null ;public MyActionListenter(MyCaculator myCaculator) {this.myCaculator = myCaculator;}@Overridepublic void actionPerformed(ActionEvent e) {//1、获得加数和被加数int a = Integer.parseInt(myCaculator.num1.getText());//强制转换变量类型进行运算int b = Integer.parseInt(myCaculator.num2.getText());//2、运行加法运算并获取值myCaculator.num3.setText(""+(a+b));//3、按下等号后,清空第一和第二个文本框值myCaculator.num1.setText("");myCaculator.num2.setText("");}}
优化代码2:内部类:重点掌握(更简洁易懂)
public class TestCaculator {public static void main(String[] args) {MyCaculator myCaculator = new MyCaculator();myCaculator.method();}}//计算器类class MyCaculator extends Frame {//属性TextField num1,num2,num3;//方法public void method(){setVisible(true);pack();//自适应调整布局//3个文本框num1 = new TextField(10);//10代表字符数,文本框长度num2 = new TextField(10);num3 = new TextField(20);//1个按钮Button button = new Button("=");//监听按钮事件button.addActionListener(new MyActionListenter());//1个标签Label label = new Label("+");setLayout(new FlowLayout());add(num1);add(label);add(num2);add(button);add(num3);}//监听类 内部类,可直接获取外部类属性和方法private class MyActionListenter implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e) {//1、获得加数和被加数int a = Integer.parseInt(num1.getText());//强制转换变量类型进行运算int b = Integer.parseInt(num2.getText());//2、运行加法运算并获取值num3.setText(""+(a+b));//3、按下等号后,清空第一和第二个文本框值num1.setText("");num2.setText("");}}}
2.8、画笔Paint
public class TestPaint {public static void main(String[] args) {new MyPaint().method();}}class MyPaint extends Frame{public void method(){setVisible(true);setBounds(200,200,600,400);}//画笔@Overridepublic void paint(Graphics g) {//画笔颜色,用完还原到初始颜色g.setColor(Color.blue);g.drawOval(100,100,100,100);// 画圆g.setColor(Color.cyan);g.fillRect(200,200,100,50);//实心长方形}}
2.9、鼠标事件
实现:鼠标点击画笔画点
//鼠标点击画笔画点public class TestMouseEvent {public static void main(String[] args) {new MyMouse();}}class MyMouse extends Frame {//创建一个点ArrayList points;public MyMouse() {setVisible(true);setBounds(100, 100, 400, 400);//存放点的集合points=new ArrayList<>();//鼠标监听器addMouseListener(new MyMouseListener());}//画笔@Overridepublic void paint(Graphics g) {//运用迭代,能一直读取到鼠标的点并附颜色和坐标大小Iterator iterator = points.iterator();while (iterator.hasNext()){Point point =(Point)iterator.next();g.setColor(Color.blue);g.fillOval(point.x,point.y,10,10);}}//创建一个方法,让鼠标监听的点能储存到集合里public void addpoint(Point point){points.add(point);}//监听鼠标事件private class MyMouseListener extends MouseAdapter {//重写鼠标按压方法@Overridepublic void mousePressed(MouseEvent e) {MyMouse myMouse=(MyMouse)e.getSource();//创建一个点的对象,获取点的坐标,添加到界面上myMouse.addpoint(new Point(e.getX(),e.getY()));//每次点击鼠标都得重新画一遍myMouse.repaint();}}}
2.10、窗口事件
public class TestWindows {public static void main(String[] args) {new MyWindows();}}class MyWindows extends Frame {public MyWindows() {setVisible(true);setSize(500, 500);//addWindowListener(new MyWindowsListenter());addWindowListener(new WindowAdapter() {//匿名内部类@Overridepublic void windowClosing(WindowEvent e) {System.out.println("关闭窗口");System.exit(0);}@Overridepublic void windowActivated(WindowEvent e) {System.out.println("激活窗口");}});}}// 与匿名内部类效果相同// class MyWindowsListenter extends WindowAdapter{//@Override//public void windowClosing(WindowEvent e) {//// System.out.println("关闭窗口");// System.exit(0);// //setVisible(false);通过按钮隐藏窗口//}////@Override//public void windowActivated(WindowEvent e) {// System.out.println("激活窗口");//}// }
2.11、键盘事件
public class TestKey {public static void main(String[] args) {new MyKey();}}class MyKey extends Frame{public MyKey() {setVisible(true);setSize(400,400);addKeyListener(new KeyAdapter() {//重写键按压方法@Overridepublic void keyPressed(KeyEvent e) {//获取键盘的码int i = e.getKeyCode();System.out.println(i);if (i == KeyEvent.VK_UP){System.out.println("你按了上键");}}});}}
3、Swing
3.1、窗口和面板
public class JFrameDemo {public static void main(String[] args) {new JFrameDemo().init();}//初始化public void init(){//顶级窗口JFrame jf = new JFrame();jf.setTitle("JFrame");jf.setVisible(true);jf.setBounds(100,100,300,300);//jf.setBackground(Color.cyan);无法显示背景颜色//关闭窗口事件jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置文本labelJLabel label = new JLabel("这是一个测试");jf.add(label);//设置文本水平对齐label.setHorizontalAlignment(SwingConstants.CENTER);//获得一个容器,显示背景颜色Container container = jf.getContentPane();container.setBackground(Color.blue);}}
3.2、弹窗JDialog
public class JDialogDemo {public static void main(String[] args) {new JDialogDemo().init();}public void init(){JFrame jf = new JFrame();jf.setVisible(true);jf.setBounds(100,100,500,500);jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//容器,放东西Container container = jf.getContentPane();//绝对布局container.setLayout(null);//设置按钮大小和文字JButton jButton = new JButton("点击弹窗");jButton.setBounds(40,40,100,50);container.add(jButton);//点击这个按钮时,弹出一个弹窗jButton.addActionListener(new ActionListener() {//监听按钮事件@Overridepublic void actionPerformed(ActionEvent e) {//弹窗new MyJDialog();}});}}class MyJDialog extends JDialog{public MyJDialog() {this.setVisible(true);this.setBounds(200,200,300,300);//设置弹窗容器Container container = this.getContentPane();container.setLayout(null);container.setBackground(Color.cyan);//设置弹窗文本标签JLabel label = new JLabel("弹窗事件");label.setBounds(100,100,100,60);container.add(label);}}
3.3、标签
圆形图标标签
public class IconDemo extends JFrame implements Icon {private int height;private int width;public static void main(String[] args) {new IconDemo().init();}public void init(){//窗口基本设置this.setVisible(true);this.setBounds(200,200,500,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置容器Container container = this.getContentPane();IconDemo iconDemo = new IconDemo(100,100);//将图标大小变量传递进去//设置图标标签JLabel label = new JLabel("IconTest", iconDemo, SwingConstants.CENTER);//将图标标签存放容器container.add(label);}public IconDemo() {}//有参构造,传递大小public IconDemo(int height, int width) {this.height = height;this.width = width;}//重写Icon方法,获取图标的位置和从有参构造获取大小变量@Overridepublic void paintIcon(Component c, Graphics g, int x, int y) {g.fillOval(x,y,width,height);//画一个圆形图标}@Overridepublic int getIconWidth() {return width;}@Overridepublic int getIconHeight() {return height;}}
图片标签
public class ImageIconDemo extends JFrame {public static void main(String[] args) {new ImageIconDemo();}public ImageIconDemo() {setVisible(true);setBounds(200,200,500,500);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//获取图片地址JLabel label = new JLabel();URL url = ImageIconDemo.class.getResource("test.png");ImageIcon icon = new ImageIcon(url);label.setIcon(icon);label.setHorizontalAlignment(SwingConstants.CENTER);Container container = getContentPane();container.add(label);}}
3.4、面板
JPanel
public class JPanelDemo extends JFrame {public static void main(String[] args) {new JPanelDemo();}public JPanelDemo() {setVisible(true);setBounds(100,100,400,400);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置面板布局JPanel jPanel = new JPanel(new GridLayout(1,3));JPanel jPanel1 = new JPanel(new GridLayout(2,1));JPanel jPanel2 = new JPanel(new GridLayout(3,1));JPanel jPanel3 = new JPanel(new GridLayout(3,2));//将按钮添加到面板上jPanel.add(new JButton("1"));jPanel.add(new JButton("1"));jPanel.add(new JButton("1"));jPanel1.add(new JButton("2"));jPanel1.add(new JButton("2"));jPanel2.add(new JButton("3"));jPanel2.add(new JButton("3"));jPanel2.add(new JButton("3"));jPanel3.add(new JButton("4"));jPanel3.add(new JButton("4"));jPanel3.add(new JButton("4"));jPanel3.add(new JButton("4"));jPanel3.add(new JButton("4"));jPanel3.add(new JButton("4"));//设置容器布局Container container = getContentPane();container.setLayout(new GridLayout(2,1,10,10));//将面板添加到容器里container.add(jPanel);container.add(jPanel1);container.add(jPanel2);container.add(jPanel3);}}
JScroll滑动窗
public class JScrollDemo extends JFrame {public static void main(String[] args) {new JScrollDemo();}public JScrollDemo(){setVisible(true);setBounds(100,100,300,350);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置文本域TextArea textArea = new TextArea(20, 50);textArea.setText("输入数据");//Scroll面板JScrollPane jScrollPane = new JScrollPane(textArea);Container container = getContentPane();container.add(jScrollPane);}}
3.5、按钮
图片按钮
public class JButtonDemo extends JFrame {public static void main(String[] args) {new JButtonDemo();}public JButtonDemo() {setVisible(true);setBounds(200,200,500,500);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//获取图片地址URL url = JButtonDemo.class.getResource("test.png");ImageIcon icon = new ImageIcon(url);//将图片地址添加到按钮上JButton jButton = new JButton(icon);Container container = getContentPane();container.add(jButton);}}
单选框JRadioButton,分组ButtonGroup
public class JButtonDemo02 extends JFrame {public static void main(String[] args) {new JButtonDemo02();}public JButtonDemo02() {setVisible(true);setBounds(200,200,300,300);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//单选框JRadioButtonJRadioButton jRadioButton1 = new JRadioButton("jRadioButton1");JRadioButton jRadioButton2 = new JRadioButton("jRadioButton2");JRadioButton jRadioButton3 = new JRadioButton("jRadioButton3");//单选只能选择一个,将所有选择添加到一个分组下面,且只能选一个ButtonGroup group = new ButtonGroup();group.add(jRadioButton1);group.add(jRadioButton2);group.add(jRadioButton3);//添加单选按钮,并设置位置Container container = getContentPane();container.add(jRadioButton1,BorderLayout.NORTH);container.add(jRadioButton2,BorderLayout.CENTER);container.add(jRadioButton3,BorderLayout.SOUTH);}}
多选框JCheckBox
public class JButtonDemo03 extends JFrame {public static void main(String[] args) {new JButtonDemo03();}public JButtonDemo03(){setVisible(true);setBounds(200,200,400,400);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//多选框JCheckBox 不用分组JCheckBox box1 = new JCheckBox("box1");JCheckBox box2 = new JCheckBox("box2");JCheckBox box3 = new JCheckBox("box3");Container container = getContentPane();container.add(box1,BorderLayout.NORTH);container.add(box2,BorderLayout.CENTER);container.add(box3,BorderLayout.SOUTH);}}
3.6、列表
下拉框JComboBox、添加选项addItem
public class ComboBoxDemo01 extends JFrame {public static void main(String[] args) {new ComboBoxDemo01();}public ComboBoxDemo01(){setVisible(true);setBounds(200,200,300,300);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);JComboBox comboBox = new JComboBox();comboBox.addItem("null");comboBox.addItem("正在热映");comboBox.addItem("已下架");comboBox.addItem("即将上映");Container container = getContentPane();container.add(comboBox);}}
列表JList,动态扩容
public class ComboBoxDemo02 extends JFrame {public static void main(String[] args) {new ComboBoxDemo02();}public ComboBoxDemo02(){setVisible(true);setBounds(200,200,100,100);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//生成一个数组内容//String [] contains = {"1","2","3"};Vector contains =new Vector();contains.add("张三");contains.add("李四");contains.add("王五");//将数组内容放入列表中JList list = new JList(contains);Container container = getContentPane();container.add(list);}}
3.7、文本框
文本框JTextField
public class TextDemo01 extends JFrame {public static void main(String[] args) {new TextDemo01();}public TextDemo01() {setVisible(true);setBounds(200,200,200,200);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//文本框JTextField textField = new JTextField("好好学习");JTextField textField1 = new JTextField("天天向上");Container container = getContentPane();container.add(textField,BorderLayout.NORTH);container.add(textField1,BorderLayout.SOUTH);}}
密码框JPasswordField
public class TextDemo02 extends JFrame {public static void main(String[] args) {new TextDemo02();}public TextDemo02() {setVisible(true);setBounds(200,200,200,200);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//密码框JPasswordField jPasswordField = new JPasswordField();jPasswordField.setEchoChar('*');Container container = getContentPane();container.add(jPasswordField);}}
文本域TextArea
public class JScrollDemo extends JFrame {public static void main(String[] args) {new JScrollDemo();}public JScrollDemo(){setVisible(true);setBounds(100,100,300,350);setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置文本域TextArea textArea = new TextArea(20, 50);textArea.setText("输入数据");//Scroll面板JScrollPane jScrollPane = new JScrollPane(textArea);Container container = getContentPane();container.add(jScrollPane);}}
4、小游戏:贪吃蛇
分为三部分:主程序(摆放顺序很重要)、面板、图片导入(注意素材路径)
所有效果都在面板上实现(JPanel),在面板上画出来,广告栏、蛇的身体、食物、积分(画笔Panint)
监听键盘事件(KeyListener)
让蛇动起来(定时器Timer)
import javax.swing.*;//主程序,启动public class StartGame {public static void main(String[] args) {JFrame frame = new JFrame("贪吃蛇小游戏");//设置游戏窗口标题frame.setBounds(10,10,900,720);//设置窗口位置和大小frame.setResizable(false);//固定窗口,不可拉伸frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置窗口关闭事件frame.add(new PanelGame());//添加面板frame.setVisible(true);//设置窗口可见性,放在最后}}
import javax.swing.*;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.KeyListener;import java.util.Random;//面板,在面板上实现效果public class PanelGame extends JPanel implements KeyListener,ActionListener{int[] snakeX = new int[600];//定义蛇的X坐标int[] snakeY = new int[500];//定义蛇的Y坐标String direction;//定义蛇头的方向int length;//定义蛇的长度boolean isStart = false;//定义游戏是否开始Timer timer = new Timer(100,this);//定时器,帧概念:数值越小,帧数越多;画面更快int foodX;int foodY;//定义食物坐标Random random = new Random();//实例一个随机对象int score;//定义积分boolean isFail = false;//定义游戏是否失败//构造器public PanelGame() {init();//游戏初始化this.setFocusable(true);//聚焦在游戏界面上this.addKeyListener(this);//获取键盘监听事件}//初始化方法public void init() {//初始化蛇的坐标,以25为一格snakeX[0] = 100; snakeY[0] = 100;//蛇头snakeX[1] = 75; snakeY[1] = 100;//蛇的第一节身体snakeX[2] = 50; snakeY[2] = 100;//蛇的第二节身体length = 3;//初始化蛇的长度direction = "R";//初始化蛇头方向//初始化食物坐标foodX=25+25*random.nextInt(33);foodY=75+25*random.nextInt(23);score=0;//初始化积分timer.start();//启动定时器}//画笔,将所有图案在面板上画出来@Overrideprotected void paintComponent(Graphics g) {super.paintComponent(g);//清屏this.setBackground(Color.white);//背景颜色Data.header.paintIcon(this, g, 25, 11);//将广告栏画在面板上g.fillRect(25, 75, 850, 600);//画一个实心长方形//画出蛇头方向if (direction.equals( "R")) {Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);} else if (direction.equals("L")) {Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);} else if (direction.equals("U")) {Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);} else if (direction.equals("D")) {Data.down.paintIcon(this, g, snakeX[0], snakeY[0]);}//画出蛇的身体for (int i = 1; i < length; i++) {Data.body.paintIcon(this, g, snakeX[i], snakeY[i]);//蛇的身体通过length控制}//画食物Data.food.paintIcon(this,g,foodX,foodY);//画积分和蛇的长度g.setColor(Color.black);//设置文字颜色g.setFont(new Font("微软雅黑",Font.BOLD,20));//设置文字大小g.drawString("长度:"+length,750,35);g.drawString("积分:"+score,750,55);//设置停止游戏的文字if (isStart == false) {g.setColor(Color.white);//设置文字颜色g.setFont(new Font("微软雅黑", Font.BOLD, 40));//设置文字大小g.drawString("按下空格键开始游戏", 300, 300);}//设置游戏失败的文字if (isFail == true){g.setColor(Color.white);//设置文字颜色g.setFont(new Font("微软雅黑", Font.BOLD, 40));//设置文字大小g.drawString("游戏失败,按空格键重新游戏", 200, 300);}}//监听键盘输入@Overridepublic void keyPressed(KeyEvent e) {//获取按下的键int keyCode = e.getKeyCode();if (keyCode == KeyEvent.VK_SPACE){if(isFail){//游戏失败,重新开始isFail=false;init();//游戏初始化} else {isStart = !isStart;//取反操作,按空格开始,再按一下停止}repaint();//刷新界面}//蛇头向右的时候,不能向左if (keyCode == KeyEvent.VK_RIGHT){if (direction.equals("L")==false){direction="R";}}//蛇头向左的时候,不能向右else if (keyCode == KeyEvent.VK_LEFT){if (direction.equals("R")==false){direction="L";}}//蛇头向上的时候,不能向下else if (keyCode == KeyEvent.VK_UP){if (direction.equals("D")==false){direction="U";}}//蛇头向下的时候,不能向上else if (keyCode == KeyEvent.VK_DOWN){if (direction.equals("U")==false){direction="D";}}}//定时器,让蛇动起来@Overridepublic void actionPerformed(ActionEvent e) {//判断游戏开始并且没有失败if (isStart==true && isFail==false) {//身体移动for (int i = length-1; i >0; i--) {snakeX[i] = snakeX[i-1];snakeY[i] = snakeY[i-1];}//头部移动if (direction.equals("R")) {snakeX[0] = snakeX[0] + 25;if (snakeX[0] > 850) {snakeX[0] = 25;}//判断边界条件} else if (direction.equals("L")) {snakeX[0] = snakeX[0] - 25;if (snakeX[0] < 25) {snakeX[0] = 850;}//判断边界条件} else if (direction.equals("U")) {snakeY[0] = snakeY[0] - 25;if (snakeY[0] < 75) {snakeY[0] = 650;}//判断边界条件} else if (direction.equals("D")) {snakeY[0] = snakeY[0] + 25;if (snakeY[0] > 650) {snakeY[0] = 75;}//判断边界条件}//判断吃到食物if(snakeX[0]==foodX && snakeY[0]==foodY){length++;//长度+1score+=10;//积分加10//重新画食物坐标,等于吃到食物,食物消失foodX=25+25*random.nextInt(33);foodY=75+25*random.nextInt(23);}//判断失败条件,蛇头碰到身体就失败for (int i = 1; i <length ; i++) {if (snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){isFail=true;}}repaint();//刷新界面}timer.start();//定时器启动}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void keyTyped(KeyEvent e) {}}
import javax.swing.*;import .URL;//图片素材导入,素材放到同级目录下public class Data {//广告栏public static URL urlheader =Data.class.getResource("static/header.png");public static ImageIcon header = new ImageIcon(urlheader);//蛇的头部和身体public static URL urlright =Data.class.getResource("static/right.png");public static ImageIcon right = new ImageIcon(urlright);public static URL urlleft =Data.class.getResource("static/left.png");public static ImageIcon left = new ImageIcon(urlleft);public static URL urlup =Data.class.getResource("static/up.png");public static ImageIcon up = new ImageIcon(urlup);public static URL urldown =Data.class.getResource("static/down.png");public static ImageIcon down = new ImageIcon(urldown);public static URL urlbody =Data.class.getResource("static/body.png");public static ImageIcon body = new ImageIcon(urlbody);//食物public static URL urlfood =Data.class.getResource("static/food.png");public static ImageIcon food = new ImageIcon(urlfood);}