GUI编程
如何学习?
- 这是什么?
- 它怎么玩?
- 该如何去平时运用?
组件
- 窗口
- 弹窗
- 面板
- 文本框
- 列表框
- 按钮
- 图片
- 监听事件
- 鼠标
- 键盘
- 破解工具
1. 简介
Gui的核心技术:Swing AWT,不流行,快被淘汰了,
- 因为界面不美观
- 需要jre环境
为什么我们要学习?
- 可以写出自己心中想要的一些小工具
- 工作时候可能需要维护到swing界面(概率小)
- 了解MVC架构,了解监听器的概念
2. AWT
1. 介绍
-
abstract window toolkit抽象窗口工具箱,包含了很多类和接口
-
GUI:Graphics User Interface图形用户界面
-
包含了窗口,按钮,文本框等元素
2. 组件和容器
1. Frame
package com.tyrant.lesson01; import java.awt.*; public class FrameDemo01 { //GUI第一个界面 public static void main(String[] args) { Frame frame = new Frame("我的第一个Java图像界面窗口"); //需要设置可见性 frame.setVisible(true); //设置窗口大小 frame.setSize(1920,1080); //设置窗口背景颜色 frame.setBackground(new Color(240, 0, 255)); //弹出的基本位置 frame.setLocation(0,0); //设置大小固定 frame.setResizable(false); } }
问题:不能关闭?答:关闭java程序运行
尝试:回顾封装
package com.tyrant.lesson01; import java.awt.*; public class FrameDemo02 { //展示多个窗口 public static void main(String[] args) { //创建多个Frame对象 MyFrame mf1 = new MyFrame(0, 0, 400, 400, Color.blue); MyFrame mf2 = new MyFrame(100, 100, 400, 400, Color.yellow); MyFrame mf3 = new MyFrame(200, 200, 400, 400, Color.red); MyFrame mf4 = new MyFrame(300, 300, 400, 400, Color.blue); } } class MyFrame extends Frame{ private static int id = 0; //可能存在多个窗口 public MyFrame(int x, int y, int w, int h, Color color ){ super("MyFrame" + (++id));//每次调用id+1 //设置界面可见性 setVisible(true); //设置界面宽高 setBounds(x,y,w,h); //设置界面颜色 setBackground(color); } }
2. 面板Panel
使用触发器解决了关闭问题(适配器模式)
package com.tyrant.lesson01; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class PanelDemo01 { //Panel 可以看成是一个空间,但是不能单独存在 public static void main(String[] args) { //创建一个Frame对象 Frame frame = new Frame(); //创建一个面板对象 Panel panel = new Panel(); //设置布局 frame.setLayout(null); //坐标 frame.setBounds(0,0,1920,1080); //颜色 frame.setBackground(new Color(0,0,0)); //panel设置坐标,相对于Frame panel.setBounds(0,0,960,1080); panel.setBackground(new Color(255,255,255)); //frame.add(Panel panel) frame.add(panel); //可见性 frame.setVisible(true); //监听事件,监听窗口关闭事件 System.exit(0) frame.addWindowListener(new WindowAdapter() { //窗口点击关闭时需要做的事情 @Override public void windowClosing(WindowEvent e) { System.exit(0); } });//适配器模式 } }
3. 布局管理器
- 流式布局
package com.tyrant.lesson01; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class FlowLayoutDemo01 { public static void main(String[] args) { //创建Frame对象 Frame frame = new Frame(); //按钮组件 Button button1 = new Button("button1"); Button button2 = new Button("button2"); Button button3 = new Button("button3"); //设置为流式布局 // frame.setLayout(new FlowLayout()); frame.setLayout(new FlowLayout(FlowLayout.LEFT)); //设置位置和大小 frame.setBounds(480,270,500,500); //添加按钮 frame.add(button1); frame.add(button2); frame.add(button3); //设置可见性 frame.setVisible(true); //监听事件 frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } }
- 东西南北中
package com.tyrant.lesson01; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class BorderLayoutDemo01 { //东西南北中 public static void main(String[] args) { //创建Frame对象那个 Frame frame = new Frame("TestBorderDemo"); Button button01 = new Button("East"); Button button02 = new Button("West"); Button button03 = new Button("South"); Button button04 = new Button("North"); Button button05 = new Button("Center"); //设置东西南北中布局 frame.add(button01,BorderLayout.EAST); frame.add(button02,BorderLayout.WEST); frame.add(button03,BorderLayout.SOUTH); frame.add(button04,BorderLayout.NORTH); frame.add(button05,BorderLayout.CENTER); //大小 frame.setBounds(0,0,500,500); //设置可见性 frame.setVisible(true); //监听事件 frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } }
- 表格布局
package com.tyrant.lesson01; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class GridLayoutDemo01 { //表格布局 public static void main(String[] args) { //创建Frame对象 Frame frame = new Frame(); //设置表格布局 frame.setLayout(new GridLayout(3,2)); //可见性 frame.setVisible(true); //大小 frame.setBounds(0,0,500,500); //监听事件 frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); //按钮组件 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.add(btn1); frame.add(btn2); frame.add(btn3); frame.add(btn4); frame.add(btn5); frame.add(btn6); //Java函数,自动填充 //frame.pack(); } }
练习:设计如下布局
package com.tyrant.lesson01; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class LayoutDemo01 { //实现上图八个按钮布局 public static void main(String[] args) { //创建frame对象 Frame frame = new Frame(); //创建Button组件 Button btn1 = new Button("1"); Button btn2 = new Button("2"); Button btn3 = new Button("3"); Button btn4 = new Button("4"); Button btn5 = new Button("5"); Button btn6 = new Button("6"); Button btn7 = new Button("7"); Button btn8 = new Button("8"); Button btn9 = new Button("9"); Button btn10 = new Button("10"); //设置表格布局 frame.setLayout(new GridLayout(1,3)); //添加面板组件 Panel panel1 = new Panel(); //panel1中添加按钮 panel1.setLayout(new GridLayout(2,1)); panel1.add(btn2); panel1.add(btn3); Panel panel2 = new Panel(); panel2.setLayout(new GridLayout(2,2)); panel2.add(btn6); panel2.add(btn7); panel2.add(btn8); panel2.add(btn9); Panel panel3 = new Panel(); panel3.setLayout(new GridLayout(2,1)); panel3.add(btn1); panel3.add(btn5); Panel panel4 = new Panel(); panel4.setLayout(new GridLayout(2,1)); panel4.add(btn4); panel4.add(btn10); Panel panel5 = new Panel(); panel5.setLayout(new GridLayout(2,1)); panel5.add(panel1); panel5.add(panel2); //添加组件 frame.add(panel3); frame.add(panel5); frame.add(panel4); //位置大小 frame.setBounds(0,0,500,400); panel1.setBounds(0,0,300,200); panel2.setBounds(0,200,300,200); panel3.setBounds(0,0,100,400); panel4.setBounds(400,0,100,400); panel5.setBounds(100,0,300,400); //可见性 frame.setVisible(true); //监听事件关闭 frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } }
结果图:
总结:
- Frame是一个顶级窗口
- Panel无法单独显示,必须添加到某个容器中
- 布局管理器
- 流式布局
- 东西南北中
- 表格布局
- 大小,定位,背景颜色,可见性,监听等
4. 事件监听
事件监听:当某个事情发生的时候,干什么
package com.tyrant.lesson02; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class ActionEventDemo01 { //按钮触发一些事件 public static void main(String[] args) { Frame frame = new Frame(); Button button = new Button("按下我"); button.addActionListener(new MyActionListener()); //布局 frame.setLayout(new FlowLayout(FlowLayout.CENTER)); frame.add(button); //自适应 frame.pack(); //可视 frame.setVisible(true); //关闭窗口 windowClosing(frame); } private static void windowClosing(Frame frame){ frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } } class MyActionListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("AAAA"); } }
多个按钮共享一个事件
package com.tyrant.lesson02; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class ActionEventDemo02 { // 两个按钮,实现同一个监听 // 开始 停止 public static void main(String[] args) { //创建Frame对象 Frame actionEvent02 = new Frame("ActionEvent02"); //创建Button组件 Button btn1 = new Button("start"); Button btn2 = new Button("stop"); //可以显示定义触发会返回的命令,如果不显示定义,则会走默认的值 //可以多个按钮只写一个监听类 btn1.setActionCommand("出来了"); btn2.setActionCommand("收回去"); //监听事件 btn1.addActionListener(new MyMonitor()); btn2.addActionListener(new MyMonitor()); actionEvent02.add(btn1); actionEvent02.add(btn2); //大小 actionEvent02.setBounds(0,0,500,500); //布局 actionEvent02.setLayout(new FlowLayout(FlowLayout.CENTER)); //可视 actionEvent02.setVisible(true); //关闭窗口 windowClosing(actionEvent02); } private static void windowClosing(Frame frame){ frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } } class MyMonitor implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("获得的信息:" + e.getActionCommand()); } }
5. 输入框TextFild监听
package com.tyrant.lesson02; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class TextDemo01 { public static void main(String[] args) { start(); } public static void start(){ MyFrame myFrame = new MyFrame(); } } class MyFrame extends Frame { public MyFrame(){ TextField textField = new TextField(); add(textField); textField.setEchoChar('*'); //监听这个文本框输入的文字 MyActionListener2 myActionListener2 = new MyActionListener2(); textField.addActionListener(myActionListener2); //可视性 setVisible(true); pack(); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } } class MyActionListener2 implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { TextField text = (TextField)e.getSource();//获得一些资源,返回一个对象 System.out.println("你输入了:" + text.getText());//获得输入框的文本 text.setText("");//null 是一个对象 ""是一个字符串 } }
6. 简易计算器,组合+内部类回顾复习
oop原则:组合大于继承
package com.tyrant.lesson02; import javax.xml.soap.Text; 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.SplittableRandom; public class CalcDemo01 { public static void main(String[] args) { start(); } public static void start(){ CalculatorFrame01 calculatorFrame01 = new CalculatorFrame01(); } } //计算器类 class CalculatorFrame01 extends Frame { public CalculatorFrame01(){ //3个文本框 TextField t1 = new TextField(12); TextField t2 = new TextField(12); TextField t3 = new TextField(24); //一个按钮 Button button = new Button("="); //一个标签 Label label = new Label("+"); //布局 setLayout(new FlowLayout(FlowLayout.LEFT)); add(t1); add(label); add(t2); add(button); add(t3); pack(); setVisible(true); //监听 CalculatorActionListener01 cal = new CalculatorActionListener01(t1,t2,t3); button.addActionListener(cal); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } } //监听器类 class CalculatorActionListener01 implements ActionListener{ private TextField num1,num2,num3; public CalculatorActionListener01(TextField num1, TextField num2, TextField num3) { this.num1 = num1; this.num2 = num2; this.num3 = num3; } @Override public void actionPerformed(ActionEvent e) { //两个框相加 Integer i = Integer.parseInt(num1.getText()) + Integer.parseInt(num2.getText()); //放进第三个框 num3.setText("" + i); //清除前两个框 num1.setText(""); num2.setText(""); } }
面向对象的组合优化写法:
package com.tyrant.lesson02; import javax.xml.soap.Text; 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.SplittableRandom; public class CalcDemo01 { public static void main(String[] args) { new CalculatorFrame01().loadCalculator01(); } } //计算器类 class CalculatorFrame01 extends Frame { //3个文本框 TextField t1; TextField t2; TextField t3; //一个按钮 Button button; //一个标签 Label label; public void loadCalculator01(){ //3个文本框 t1 = new TextField(12); t2 = new TextField(12); t3 = new TextField(24); //一个按钮 button = new Button("="); //一个标签 label = new Label("+"); //监听 CalculatorActionListener01 cal = new CalculatorActionListener01(this); button.addActionListener(cal); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); //布局 setLayout(new FlowLayout(FlowLayout.LEFT)); add(t1); add(label); add(t2); add(button); add(t3); pack(); setVisible(true); } } //监听器类 class CalculatorActionListener01 implements ActionListener{ CalculatorFrame01 calculatorFrame01 = null; public CalculatorActionListener01(CalculatorFrame01 calculatorFrame01) { this.calculatorFrame01 = calculatorFrame01; } @Override public void actionPerformed(ActionEvent e) { //两个框相加 Integer i = Integer.parseInt(calculatorFrame01.t1.getText()) + Integer.parseInt(calculatorFrame01.t2.getText()); //放进第三个框 calculatorFrame01.t3.setText("" + i); //清除前两个框 calculatorFrame01.t1.setText(""); calculatorFrame01.t2.setText(""); } }
再进行内部类优化:
package com.tyrant.lesson02; import javax.xml.soap.Text; 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.SplittableRandom; public class CalcDemo01 { public static void main(String[] args) { new CalculatorFrame01().loadCalculator01(); } } //计算器类 class CalculatorFrame01 extends Frame { //3个文本框 TextField t1; TextField t2; TextField t3; //一个按钮 Button button; //一个标签 Label label; public void loadCalculator01(){ //3个文本框 t1 = new TextField(12); t2 = new TextField(12); t3 = new TextField(24); //一个按钮 button = new Button("="); //一个标签 label = new Label("+"); //监听 CalculatorActionListener01 cal = new CalculatorActionListener01(); button.addActionListener(cal); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); //布局 setLayout(new FlowLayout(FlowLayout.LEFT)); add(t1); add(label); add(t2); add(button); add(t3); pack(); setVisible(true); } //监听器类 //内部类最大的好处,就是可以畅通无阻地访问外部类 private class CalculatorActionListener01 implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { //两个框相加 int i = Integer.parseInt(t1.getText()) + Integer.parseInt(t2.getText()); //放进第三个框 t3.setText("" + i); //清除前两个框 t1.setText(""); t2.setText(""); } } }
7. 画笔
package com.tyrant.lesson03; import java.awt.*; public class PaintDemo01 { public static void main(String[] args) { new MyPaint().Load(); } } class MyPaint extends Frame { public void Load(){ setBounds(400,400,500,500); setVisible(true); setBackground(new Color(0,0,0)); } @Override public void paint(Graphics g) { //super.paint(g); //画笔需要有颜色,可以画画 g.setColor(new Color(255,255,255)); g.drawOval(100,100,100,100);//空心的圆 g.fillOval(200,100,100,100);//实心的圆 g.setColor(new Color(255,0,255)); g.fillRect(100,200,100,100);//矩形 } }
8. 鼠标监听
目的:实现鼠标画画
思路:如下图
代码实现:
package com.tyrant.lesson03; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.Iterator; //鼠标监听事件 public class MouseListenerDemo01 { public static void main(String[] args) { new MyFrame().load("画笔"); } } //自己的类 class MyFrame extends Frame { //画画需要画笔,需要监听鼠标当前的位置,需要集合来存储这个点 private ArrayList<Point> points ; public void load(String title){ //设置和组件 setTitle(title); setBounds(200,200,500,500); setVisible(true); //存点 points = new ArrayList<Point>(); //鼠标监听器,正对这个窗口 addMouseListener(new MyMouseListener()); //布局 } //画笔方法 @Override public void paint(Graphics g) { //根据点使用画笔 Iterator<Point> it = points.iterator(); while(it.hasNext()){ Point next = it.next(); g.setColor(Color.BLACK); g.fillOval(next.x,next.y,10,10); } } //监听类(内部类) //适配器模式 private class MyMouseListener extends MouseAdapter{ @Override public void mouseClicked(MouseEvent e) { MyFrame myFrame = (MyFrame) e.getSource(); //点击的时候加一个点 Point point = new Point(e.getX(), e.getY()); points.add(point); //每次点击重新画 myFrame.repaint();//刷新 帧 } } }
9. 窗口监听
package com.tyrant.lesson03; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class WindowListenerDemo01 { //窗口监听 public static void main(String[] args) { new MyWindowFrame01().load(); } } //自己的窗口类 class MyWindowFrame01 extends Frame{ //属性 //方法 public void load(){ //设置 setBounds(300,300,500,500); setVisible(true); //组件 Button disVisible = new Button("disVisible"); //监听(建议用匿名内部类写) //disVisible.addActionListener(new MyActionListener01());//内部类写法 disVisible.addActionListener(new ActionListener() {//匿名内部类写法 @Override public void actionPerformed(ActionEvent e) { setVisible(false);//隐藏窗口 } }); //addWindowListener(new MyWindowListener01()); addWindowListener(new WindowAdapter() { /* @Override public void windowClosed(WindowEvent e) { //setVisible(false); System.out.println("closed");//不好监听 System.exit(0);//正常退出 } */ /* @Override public void windowOpened(WindowEvent e) { System.out.println("opened");//不好监听 } */ @Override public void windowActivated(WindowEvent e) { System.out.println("activated"); setTitle("被激活了"); } @Override public void windowClosing(WindowEvent e) { System.out.println("closing"); System.exit(0); } }); //布局 setLayout(new FlowLayout(FlowLayout.CENTER)); add(disVisible); } //内部类 private class MyWindowListener01 extends WindowAdapter{ @Override public void windowClosed(WindowEvent e) { //setVisible(false); System.exit(0);//正常退出 } } private class MyActionListener01 implements ActionListener { @Override public void actionPerformed(ActionEvent e) { setVisible(false);//隐藏窗口 } } }
10. 键盘监听
package com.tyrant.lesson03; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; public class KeyListenerDemo01 { public static void main(String[] args) { new MyKeyFrame01().load(); } } class MyKeyFrame01 extends Frame { //属性 //方法 public void load(){ //设置 setBounds(300,300,500,500); setVisible(true); //组件 //监听 addKeyListener(new KeyAdapter() { //键盘按下 @Override public void keyPressed(KeyEvent e) { //获得按下的键是哪一个 int keyCode = e.getKeyCode();//获得键盘的码 if (keyCode == KeyEvent.VK_UP ){ System.out.println("你按了上键"); } } }); //布局 } }
3. Swing
1. 窗口、面板
package com.tyrant.lesson04; import javax.swing.*; import java.awt.*; public class JFrameDemo01 { public static void main(String[] args) { new JFrameDemo01().init(); } //init(); 初始化 public void init(){ JFrame jf = new JFrame(); jf.setVisible(true); jf.setBackground(Color.red); jf.setBounds(300,300,400,400); //设置文字 JLabel jl = new JLabel("tyrantblue"); jl.setHorizontalAlignment(SwingConstants.CENTER); jf.add(jl); //要实例化容器 Container contentPane = jf.getContentPane(); contentPane.setBackground(Color.red); //关闭事件 jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } }
2. 弹窗
package com.tyrant.lesson04; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class DialogDemo01 extends JFrame { //属性 //方法 public void init(){ setVisible(true); setBounds(300,300,500,500); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //JFrame 放东西在容器上 Container container = getContentPane(); //绝对布局 container.setLayout(null); //按钮 JButton button = new JButton("弹窗按钮"); button.setBounds(20,20,100,50); container.add(button); //监听 button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //弹出一个弹窗 new MyDialog01().load(); } }); } public static void main(String[] args) { new DialogDemo01().init(); } } class MyDialog01 extends JDialog{ //属性 //方法 public void load(){ this.setVisible(true); this.setBounds(100,100,200,100); //实例化容器 Container container = this.getContentPane(); container.setLayout(new FlowLayout(FlowLayout.CENTER)); JLabel jl = new JLabel("你打开了弹窗"); // jl.setBounds(0,0,200,100); container.add(jl); } }
3. 标签
label
new Lable();
图标
package com.tyrant.lesson04; import javax.swing.*; import java.awt.*; public class IconDemo01 extends JFrame implements Icon { private int width; private int height; public IconDemo01(){ } public IconDemo01(int width,int height){ this.height = height; this.width = width; } public void init(){ setVisible(true); setBounds(200,200,500,500); JLabel icon = new JLabel("Icon", new IconDemo01(20, 20), SwingConstants.CENTER); Container container = getContentPane(); container.add(icon); // container.setVisible(true); // container.setBounds(200,200,500,500); } @Override public void paintIcon(Component c, Graphics g, int x, int y) { g.fillOval(x,y,width,height); } @Override public int getIconWidth() { return this.width; } @Override public int getIconHeight() { return this.height; } public static void main(String[] args) { new IconDemo01().init(); } }
package com.tyrant.lesson04; import javax.swing.*; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.net.URL; public class ImageIconDemo01 extends JFrame { public void init(){ JLabel jl = new JLabel("ImageIcon"); //获取图片地址 URL url = ImageIconDemo01.class.getResource("home-line.png"); ImageIcon imageIcon = new ImageIcon(url); jl.setIcon(imageIcon); jl.setHorizontalAlignment(SwingConstants.CENTER); add(jl); setBounds(200,200,500,500); setVisible(true); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new ImageIconDemo01().init(); } }
4. 面板
JPanel
package com.tyrant.lesson05; import javax.swing.*; import java.awt.*; public class JPanelDemo01 extends JFrame { JButton btn1; JPanel jp1 ; JPanel jp2 ; public void init(){ Container container = getContentPane(); container.setLayout(new GridLayout(2,1,20,10));//后面的是间距 jp1 = new JPanel(new GridLayout(1,3)); jp2 = new JPanel(new GridLayout(1,3)); for (int i = 0; i < 3; i++) { jp1.add(new JButton("AAA")); jp2.add(new JButton("BBB")); } add(jp1); add(jp2); setVisible(true); setSize(500,600); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JPanelDemo01().init(); } }
JScroll
package com.tyrant.lesson05; import javax.swing.*; import java.awt.*; public class JScrollDemo01 extends JFrame { public void init(){ Container container = getContentPane(); TextArea text01 = new TextArea(10,50);;//文本域 text01.setText("Hello"); container.add(text01); JButton btn = new JButton("Hello"); // JScrollPane jScrollPane = new JScrollPane(text01); // container.add(jScrollPane); container.add(btn); container.setLayout(new FlowLayout(FlowLayout.CENTER)); setVisible(true); setSize(500,500); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JScrollDemo01().init(); } }
5. 按钮
图片按钮,单选框,复选框
package com.tyrant.lesson05; import javax.swing.*; import java.awt.*; import java.net.URL; public class JButtonDemo01 extends JFrame { public void init(){ Container container = getContentPane(); //图片按钮 URL url = JButtonDemo01.class.getResource("home1.png");//这里的名字不能和同项目下的重名 ImageIcon imageIcon = new ImageIcon(url); JButton btn = new JButton("home"); btn.setIcon(imageIcon); btn.setSize(72,24); btn.setToolTipText("返回主页"); container.add(btn); //单选框 JRadioButton jr1 = new JRadioButton("jr1"); JRadioButton jr2 = new JRadioButton("jr2"); JRadioButton jr3 = new JRadioButton("jr3"); //由于单选框只能选一个 //所以需要分组 ButtonGroup buttonGroup = new ButtonGroup(); buttonGroup.add(jr1); buttonGroup.add(jr2); buttonGroup.add(jr3); container.add(jr1,BorderLayout.NORTH); container.add(jr2,BorderLayout.CENTER); container.add(jr3,BorderLayout.SOUTH); //多选框 JCheckBox jCheckBox1 = new JCheckBox("jcb1"); JCheckBox jCheckBox2 = new JCheckBox("jcb2"); JCheckBox jCheckBox3 = new JCheckBox("jcb3"); container.add(jCheckBox1); container.add(jCheckBox2); container.add(jCheckBox3); container.setLayout(new FlowLayout(FlowLayout.CENTER)); setVisible(true); setSize(500,500); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JButtonDemo01().init(); } }
6. 列表
-
下拉框
-
列表框
package com.tyrant.lesson06; import javafx.scene.control.ComboBox; import javax.swing.*; import java.awt.*; import java.util.Vector; public class ComboBoxDemo01 extends JFrame { public void init(){ Container container = getContentPane(); //复选框 JComboBox jComboBox = new JComboBox(); jComboBox.addItem(null); jComboBox.addItem("上海"); jComboBox.addItem("深圳"); jComboBox.addItem("北京"); container.add(jComboBox); //生成列表的内容 String[] strings = {"1","2","3"}; JList<String> stringJList = new JList<>(strings); container.add(stringJList); //动态 Vector<String> strings1 = new Vector<>(); strings1.add("张三"); strings1.add("李四"); strings1.add("王五"); JList<String> stringJList1 = new JList<>(strings1); container.add(stringJList1); container.setLayout(new FlowLayout(FlowLayout.CENTER)); setVisible(true); setSize(500,500); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new ComboBoxDemo01().init(); } }
7. 文本
package com.tyrant.lesson06; import javax.swing.*; import java.awt.*; public class TextDemo01 extends JFrame { public void init() { Container container = getContentPane(); //文本框 JTextField jTextField = new JTextField("hello"); JTextField jTextField2 = new JTextField("world",40); container.add(jTextField); container.add(jTextField2); //密码框 JPasswordField jPasswordField = new JPasswordField(30); container.add(jPasswordField); container.setLayout(new FlowLayout(FlowLayout.CENTER)); setVisible(true); setSize(500,500); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new TextDemo01().init(); } }
4. 贪吃蛇
键盘监听
定时器
步骤:
- 定义数据
- 画上去
- 监听事件
代码实现
Data.java
package com.tyrant.snake; import javax.swing.*; import java.net.URL; public class Data { //标题 public static ImageIcon headerIcon = new ImageIcon("static/header.png"); //头 //使用getResource()方法不好获取包外的资源 public static ImageIcon upIcon = new ImageIcon("static/up.png"); public static ImageIcon downIcon = new ImageIcon("static/down.png"); public static ImageIcon leftIcon = new ImageIcon("static/left.png"); public static ImageIcon rightIcon = new ImageIcon("static/right.png"); //身体 public static ImageIcon bodyIcon = new ImageIcon("static/body.png"); //食物 public static ImageIcon foodIcon = new ImageIcon("static/food.png"); }
GamePanel.java
package com.tyrant.snake; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Random; public class GamePanel extends JPanel { //定义蛇的数据结构 private int length;//蛇的长度 private int[] snakeX = new int[600]; //蛇的x坐标 25*25 private int[] snakeY = new int[500]; //蛇的y坐标 25*25 private String fx ; //食物的坐标 private int foodX ; private int foodY ; Random random = new Random(); //游戏当前的状态: private boolean isStart;//开始,停止 private boolean isFail;//是否失败 //定时器 Timer timer = new Timer(100,new MyActionListener()); //构造器 public GamePanel(){ init(); gameListener(); } //初始化方法 public void init(){ setBounds(0,0,900,720); //默认蛇三节 length = 3; snakeX[0] = 100;snakeY[0] = 100; snakeX[1] = 75;snakeY[1] = 100; snakeX[2] = 50;snakeY[2] = 100; //默认头方向朝右 fx = "r"; //默认食物位置 foodX = 25 + 25 * random.nextInt(34); foodY = 75 + 25 * random.nextInt(24); //默认不开始 isStart = false; isFail = false; } //监听方法 public void gameListener() { //获取焦点事件 setFocusable(true); //获得键盘监听事件 addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode();//获得按键码 if (keyCode == KeyEvent.VK_SPACE){//空格则取反 if (isFail){ init(); }else { isStart = !isStart; } repaint(); } //小蛇移动 if (keyCode == KeyEvent.VK_LEFT ||keyCode == KeyEvent.VK_A){ fx = "l"; } if (keyCode == KeyEvent.VK_RIGHT ||keyCode == KeyEvent.VK_D){ fx = "r"; } if (keyCode == KeyEvent.VK_UP ||keyCode == KeyEvent.VK_W){ fx = "u"; } if (keyCode == KeyEvent.VK_DOWN ||keyCode == KeyEvent.VK_S){ fx = "d"; } } }); //事件监听,定时器 timer.start(); } //绘制面板,游戏中的所有面板都使用这个画笔来画 @Override protected void paintComponent(Graphics g) { super.paintComponent(g);//清屏 setBackground(Color.WHITE); //绘制框架 Data.headerIcon.paintIcon(this,g,25,10); g.fillRect(25,75,850,600); //把小蛇画上去 //Data.rightIcon.paintIcon(this,g,snakeX[0],snakeY[0] );//头的坐标 //判断头朝向 if (fx.equals("r")){ Data.rightIcon.paintIcon(this,g,snakeX[0],snakeY[0] );//右 } else if (fx.equals("l")){ Data.leftIcon.paintIcon(this,g,snakeX[0],snakeY[0] );//左 } else if (fx.equals("u")){ Data.upIcon.paintIcon(this,g,snakeX[0],snakeY[0] );//上 } else if (fx.equals("d")){ Data.downIcon.paintIcon(this,g,snakeX[0],snakeY[0] );//下 } //根据小蛇的长度画身体 for (int i = 1; i < length; i++) { Data.bodyIcon.paintIcon(this,g,snakeX[i],snakeY[i] ); } //积分和长度 g.setColor(Color.WHITE); g.setFont(new Font("楷体_GB2312",Font.BOLD,15)); g.drawString("长度:" + length,750,35); g.drawString("积分:" + ((length-3)*10),750,50); //Data.bodyIcon.paintIcon(this,g,snakeX[1],snakeY[1] );//第一个身体 //Data.bodyIcon.paintIcon(this,g,snakeX[2],snakeY[2] );//第二个身体 //画食物 Data.foodIcon.paintIcon(this,g,foodX,foodY); //游戏状态 if (!isStart){ g.setColor(Color.yellow); g.setFont(new Font("楷体_GB2312",Font.BOLD,40)); g.drawString("按空格开始游戏",300,300); } if (isFail){ g.setColor(Color.RED); g.setFont(new Font("楷体_GB2312",Font.BOLD,30)); g.drawString("失败了,空格重新开始",300,300); } } //事件监听 public class MyActionListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { if (isStart&&!isFail){ //吃食物 if (snakeX[0] == foodX && snakeY[0] == foodY){ length++;//长度加一 foodX = 25 + 25 *random.nextInt(34); foodY = 75 + 25 *random.nextInt(24); } //每一节都到前一节的位置 for (int i = length-1; i>0 ;i--){ snakeX[i] = snakeX[i-1]; snakeY[i] = snakeY[i-1]; } ////小蛇头的方向 if (fx.equals("r")){ snakeX[0] += 25; } if (fx.equals("l")){ snakeX[0] -= 25; } if (fx.equals("u")){ snakeY[0] -= 25; } if (fx.equals("d")){ snakeY[0] += 25; } //设置边界 if (snakeX[0] > 850){ snakeX[0] = 25; } if (snakeY[0] > 650){ snakeY[0] = 75; } if (snakeX[0] < 25){ snakeX[0] = 850; } if (snakeY[0] < 75){ snakeY[0] = 650; } //失败 for (int i = 1; i < length ; i++) { if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]){ isFail=true; } } repaint(); } } } }
StartGame.java
package com.tyrant.snake; import com.sun.deploy.panel.ControlPanel; import javax.swing.*; import java.awt.*; //游戏的主启动类 public class StartGame extends JFrame { public void init(){ add(new GamePanel()); Container container = getContentPane(); // container.setLayout(null); setResizable(false); setBounds(400,400,900,720); setVisible(true); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } }
test.java
package com.tyrant.snake; public class test { public static void main(String[] args) { new StartGame().init(); } }
效果如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步