GUI编程
组件:
-
窗口
-
弹窗
-
面板
-
文本框
-
列表框
-
按钮
-
图片
-
监听事件
-
鼠标
-
键盘事件
-
破解工具
1、简介
GUI核心开发技术: Swing AWT(不流行的原因)
-
界面不美观
-
需要jre环境
为什么我们还要学习?
-
可以写出自己心中想要的一些小工具
-
工作的时候,可能需要维护到Swing界面,(这个方面比较老了,一般用不到)
-
了解MVC架构,了解监听
2、AWT
2.1、AWT介绍
-
包含了很多类和接口
-
元素:窗口、按钮、文本框...
-
java.awt
-
2.2、组件和容器
1、窗口Frame
//Frame,JDK 看源码 Frame frame = new Frame("我的第一个Java图形界面窗口"); //需要设置可见性 frame.setVisible(true); //设置窗口大小 w h frame.setSize(400,400); //设置背景颜色 Color frame.setBackground(new Color(4, 153, 69)); //弹出的初始位置 frame.setLocation(200,200); //设置大小固定 frame.setResizable(false);
问题:发现窗口关闭不掉,终止程序运行就可以
封装:创建多个窗口
public class TestFrame02 { public static void main(String[] args) { //展示多个窗口 MyFrame myFrame1 = new MyFrame(100,100,200,200,Color.red); MyFrame myFrame2 = new MyFrame(300,100,200,200,Color.yellow); MyFrame myFrame3 = new MyFrame(100,300,200,200,Color.blue); MyFrame myFrame4 = new MyFrame(300,300,200,200,Color.green); } } class MyFrame extends Frame { static int id = 0; //可能存在多个窗口,我们需要一个计数器 public MyFrame(int x,int y,int w,int h,Color color) throws HeadlessException { super("Myframe+"+(++id)); setBackground(color); setBounds(x,y,w,h); setVisible(true); } }
2、面板Panel
解决了窗口关闭事件
package com.fy.lesson01; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; //Panel面板 可以看成是一个空间,但是不能单独存在,需要放在Frame上 public class TestPanel { public static void main(String[] args) { Frame frame = new Frame(); //布局的概念 Panel panel = new Panel(); //设置布局 frame.setLayout(null); //坐标 frame.setBounds(200,200,300,300); //背景颜色 frame.setBackground(new Color(12, 175, 12)); //panel 设置坐标,相对于frame panel.setBounds(50,50,200,200); //背景颜色 panel.setBackground(new Color(163, 9, 32)); //frame.add(panel)添加面板到窗口 frame.add(panel); //设置可见性 frame.setVisible(true); //监听事件,监听窗口关闭事件 System.exit(0) //这种关闭方法需要写很多东西,很麻烦 // frame.addWindowListener(new WindowListener() { // @Override // public void windowOpened(WindowEvent e) { } // @Override // public void windowClosing(WindowEvent e) { } // @Override // public void windowClosed(WindowEvent e) { } // @Override // public void windowIconified(WindowEvent e) { } // @Override // public void windowDeiconified(WindowEvent e) { } // @Override // public void windowActivated(WindowEvent e) { } // @Override // public void windowDeactivated(WindowEvent e) { } // }); //适配器模式: frame.addWindowListener(new WindowAdapter() { //窗口点击关闭的时候需要做的事情 @Override public void windowClosing(WindowEvent e) { //结束程序 System.exit(0); } }) ; } }
2.3、布局管理器
2.3.1、流式布局:FlowLayout
package com.fy.lesson01; import java.awt.*; public class TestFlowLayout { public static void main(String[] args) { Frame frame = new Frame(); //设置可见 frame.setVisible(true); //组件---按钮组件 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.setLayout(new FlowLayout(FlowLayout.RIGHT)); //设置大小 frame.setSize(400,400); //把按钮添加上去 frame.add(button1); frame.add(button2); frame.add(button3); } }
2.3.2、东西南北中:BorderLayout
package com.fy.lesson01; import java.awt.*; public class TestBorderLayout { public static void main(String[] args) { Frame frame = new Frame(); 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); frame.setSize(400,400); frame.setVisible(true); } }
2.3.3、表格布局:GridLayout
package com.fy.lesson01; import java.awt.*; public class TestGridLayout { public static void main(String[] args) { Frame frame = new Frame(); 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函数,自动选择最优秀的位置确立 frame.setVisible(true); frame.setSize(400,400); } }
总结
-
Frame是一个顶级窗口
-
Panel无法单独显示,必须添加到某个容器中
-
布局管理器
-
流式布局
-
东西南北中
-
表格布局
-
-
大小、定位、背景颜色、可见性、监听
练习
package com.fy.lesson01; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class Exercise { public static void main(String[] args) { //1.创建窗口 Frame frame = new Frame(); frame.setVisible(true); frame.setBounds(200,200,500,400); frame.setLayout(new GridLayout(2,1)); //2.创建面板 Panel panel1 = new Panel(new BorderLayout()); Panel panel2 = new Panel(new GridLayout(2,1)); Panel panel3 = new Panel(new BorderLayout()); Panel panel4 = new Panel(new GridLayout(2,2)); //3. 添加按钮 //上面 panel1.add(new Button("Button-1"),BorderLayout.EAST); panel1.add(new Button("Button-2"),BorderLayout.WEST); panel2.add(new Button("Button-3")); panel2.add(new Button("Button-4")); panel1.add(panel2,BorderLayout.CENTER); //下面 panel3.add(new Button("Button-5"),BorderLayout.EAST); panel3.add(new Button("Button-6"),BorderLayout.WEST); for (int i = 7; i < 11; i++) { panel4.add(new Button("Button-"+i)); } panel3.add(panel4,BorderLayout.CENTER); //4.窗口添加面板 frame.add(panel1); frame.add(panel3); //5.监听关闭 frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } }
2.4、事件监听
-
事件监听:当某个事情发生时,需要干什么?
package com.fy.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 TestActionEvent { public static void main(String[] args) { //按下按钮,触发一些事件 Frame frame = new Frame(); Button button = new Button(); //因为addActionListener() 需要一个ActionListener,所以我们需要构造一个ActionListener MyActionListener myActionListener = new MyActionListener(); button.addActionListener(myActionListener); frame.add(button,BorderLayout.CENTER); frame.pack(); frame.setVisible(true); frame.setSize(400,400); windowClose(frame);//关闭窗口 } //关闭窗口事件 private static void windowClose(Frame frame) { frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } } //事件监听,当按下按钮,需要干什么(这里按下按钮输出"aaa") class MyActionListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { System.out.println("aaa"); } }
2. 多个按钮,共用一个监听事件:
package com.fy.lesson02; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class TestActionEvent02 { public static void main(String[] args) { //两个按钮,实现同一个监听 //开始 停止 Frame frame = new Frame("开始-停止"); Button button1 = new Button("start"); Button button2 = new Button("stop"); //可以显示的定义触发会返回的命令,如果不显示定义,则会走默认的值 //可以多个按钮只写一个监听类 button2.setActionCommand("button2-stop"); MyMonitor myMonitor = new MyMonitor(); button1.addActionListener(myMonitor); button2.addActionListener(myMonitor); frame.add(button1,BorderLayout.NORTH); frame.add(button2,BorderLayout.SOUTH); frame.setVisible(true); frame.pack(); frame.setSize(400,400); } } class MyMonitor implements ActionListener { @Override public void actionPerformed(ActionEvent e) { System.out.println("按钮被点击了:msg-"+e.getActionCommand()); } }
2.5、输入框 TextField 监听
package com.fy.lesson02; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.FileReader; public class TestText01 { public static void main(String[] args) { //启动 new MyFrame(); } } class MyFrame extends Frame { public MyFrame() { //创建一个文本框 TextField textField = new TextField(); //添加文本框 add(textField); //监听这个文本框输入的文字 MyActionListener2 myActionListener2 = new MyActionListener2(); //按下enter,就会触发这个输入框的事件 textField.addActionListener(myActionListener2); //设置替换编码 textField.setEchoChar('*'); setVisible(true); pack(); } } class MyActionListener2 implements ActionListener { @Override public void actionPerformed(ActionEvent e) { TextField field = (TextField) e.getSource();//获取一些资源,返回的一个对象 System.out.println(field.getText()); //获得输入框的文本 //enter 清空 field.setText(""); } }
2.6、简易计算器,组合+内部类回顾复习
oop原则:组合 大于 继承
目前代码:
package com.fy.lesson02; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; //简易计算器 public class TestCalc { public static void main(String[] args) { new Calculator(); } } //计算机类 class Calculator extends Frame { public Calculator() { //3 个文本框 TextField field1 = new TextField(10); TextField field2 = new TextField(10); TextField field3 = new TextField(20); //1 个按钮 Button button = new Button("="); button.addActionListener(new MyCalculatorListener(field1,field2,field3)); //1 个标签 Label label = new Label("+"); //流式布局 setLayout(new FlowLayout()); add(field1); add(label); add(field2); add(button); add(field3); pack(); setVisible(true); } } //监听器类 class MyCalculatorListener implements ActionListener { private TextField field1; private TextField field2; private TextField field3; //获取三个变量 public MyCalculatorListener(TextField field1,TextField field2,TextField field3) { this.field1 = field1; this.field2 = field2; this.field3 = field3; } @Override public void actionPerformed(ActionEvent e) { //1.获得加数和被加数 int n1 = Integer.parseInt(field1.getText()); int n2 = Integer.parseInt(field2.getText()); //2.将这个值 + 法运算后,放在第三个框 field3.setText(""+(n1+n2)); //3.删除前两个框 field1.setText(""); field2.setText(""); } }
完全改造为面向对象写法:
package com.fy.lesson02; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; //简易计算器 public class TestCalc { public static void main(String[] args) { new Calculator().loadFrame(); } } //计算机类 class Calculator extends Frame { //属性 TextField field1,field2,field3; //方法 public void loadFrame() { //3 个文本框 //1 个按钮 //1 个标签 field1 = new TextField(10); //字符数 field2 = new TextField(10); field3 = new TextField(20); Button button = new Button("="); Label label = new Label("+"); //按下按钮需要发生的事件 button.addActionListener(new MyCalculatorListener(this)); //流式布局 setLayout(new FlowLayout()); add(field1); add(label); add(field2); add(button); add(field3); pack(); setVisible(true); } } //监听器类 class MyCalculatorListener implements ActionListener { //获取计算器这个对象,在一个类中组合另外一个类 Calculator calculator = null; public MyCalculatorListener(Calculator calculator) { this.calculator = calculator; } @Override public void actionPerformed(ActionEvent e) { //1.获得加数和被加数 //2.将这个值 + 法运算后,放在第三个框 //3.删除前两个框 int n1 = Integer.parseInt(calculator.field1.getText()); int n2 = Integer.parseInt(calculator.field2.getText()); calculator.field3.setText(""+(n1+n2)); calculator.field1.setText(""); calculator.field2.setText(""); } }
内部类(更好的包装):
package com.fy.lesson02; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; //简易计算器 public class TestCalc { public static void main(String[] args) { new Calculator().loadFrame(); } } //计算机类 class Calculator extends Frame { //属性 TextField field1,field2,field3; //方法 public void loadFrame() { //3 个文本框 //1 个按钮 //1 个标签 field1 = new TextField(10); //字符数 field2 = new TextField(10); field3 = new TextField(20); Button button = new Button("="); Label label = new Label("+"); //按下按钮需要发生的事件 button.addActionListener(new MyCalculatorListener()); //流式布局 setLayout(new FlowLayout()); add(field1); add(label); add(field2); add(button); add(field3); pack(); setVisible(true); } //监听器类 //内部类最大的好处,就是可以畅通无阻的访问外部的属性和方法! private class MyCalculatorListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { //1.获得加数和被加数 //2.将这个值 + 法运算后,放在第三个框 //3.删除前两个框 int n1 = Integer.parseInt(field1.getText()); int n2 = Integer.parseInt(field2.getText()); field3.setText(""+(n1+n2)); field1.setText(""); field2.setText(""); } } }
2.7、画笔
package com.fy.lesson03; import java.awt.*; public class TestPaint { public static void main(String[] args) { new MyPaint().loadFrame(); } } class MyPaint extends Frame { public void loadFrame() { setBounds(200,200,500,400); setVisible(true); } //画笔 @Override public void paint(Graphics g) { //画笔,需要颜色,可以画画 g.setColor(Color.red); //g.drawOval(100,100,100,100); //圆 g.fillOval(100,100,100,100); //实心的圆 g.setColor(Color.GREEN); g.fillRect(150,200,200,200); //矩形 //养成习惯,画笔用完,将它还原到最初的颜色 } }
2.8、鼠标监听
目的:想要实现鼠标画画
package com.fy.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 TestMouseListener { public static void main(String[] args) { new MyFrame("画图"); } } //鼠标类 class MyFrame extends Frame { //画画需要画笔,需要监听鼠标当前的位置,需要集合来存储这个点 ArrayList points; //画板,窗口 public MyFrame(String title){ //画板的标题,画板的位置、大小 super(title); setBounds(200,200,400,300); //存鼠标的点 points = new ArrayList<>(); //鼠标监听器 this.addMouseListener(new MyMouseListener()); setVisible(true); } @Override public 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); } } //监听类,适配器模式---继承它的实现类 private class MyMouseListener extends MouseAdapter { //鼠标 按下、弹起、按住不放 @Override public void mousePressed(MouseEvent e) { //e.getSource();返回当前对象,这里返回鼠标对象 MyFrame frame = (MyFrame) e.getSource(); //这里,我们点击的时候,就会在界面上产生一个点! //这个点就是鼠标的点 //把鼠标点击的点的位置添加到集合中 points.add(new Point(e.getX(),e.getY())); //每次点击鼠标都需要重新画一遍 frame.repaint(); //执行完一次就会刷新一下 } } }
逻辑关系:
2.9、窗口监听
package com.fy.lesson03; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; //窗口监听 public class TestWindow { public static void main(String[] args) { new WindowFrame(); } } //窗口类 class WindowFrame extends Frame { public WindowFrame() { setVisible(true); setBackground(Color.MAGENTA); setBounds(100,100,200,200); //addWindowListener(new MyWindowListener()); this.addWindowListener( //匿名内部类 new WindowAdapter() { @Override public void windowOpened(WindowEvent e) { System.out.println("windowOpened--窗口已打开"); } //关闭窗口 @Override public void windowClosing(WindowEvent e) { System.out.println("windowClosing--正在关闭"); System.exit(0); } //激活窗口 @Override public void windowActivated(WindowEvent e) { WindowFrame source = (WindowFrame) e.getSource(); source.setTitle("窗口被激活了"); System.out.println("windowActivated--窗口激活"); } } ); } }
2.10、键盘监听
package com.fy.lesson03; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; //键盘监听 public class TestKeyListener { public static void main(String[] args) { new KeyFrame(); } } class KeyFrame extends Frame { public KeyFrame() { setBounds(1,2,300,400); setVisible(true); this.addKeyListener(new KeyAdapter() { //键盘按下 @Override public void keyReleased(KeyEvent e) { //获取键盘按下的键是哪一个,当前的码 int keyCode = e.getKeyCode(); //不需要记这个数值,直接使用静态属性VK_XXX System.out.println(keyCode); if(keyCode == KeyEvent.VK_UP) { System.out.println("你按下了上键"); } //根据按下不同的操作,产生不同的结果!! } }); } }
3、Swing
3.1、窗口、面板
package com.fy.lesson04; import javax.swing.*; import java.awt.*; public class JFrameDemo { //init(); 初始化 public void init() { //顶级窗口 JFrame jFrame = new JFrame("这是一个JFrame窗口"); jFrame.setVisible(true); jFrame.setBounds(200,200,400,400); //设置文字 JLabel JLabel jLabel = new JLabel("JFrame学习"); jFrame.add(jLabel); //让文本标签居中 setHorizontalAlignment:设置水平对齐 jLabel.setHorizontalAlignment(SwingConstants.CENTER); //容器实例化:JFrame是窗口,也是一个容器,实例化才能看得见,才能设置 Container contentPane = jFrame.getContentPane(); contentPane.setBackground(Color.CYAN); contentPane.setVisible(true); //contentPane.setBounds(10,10,200,200); //关闭事件 jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { //建立一个窗口 new JFrameDemo().init(); } }
3.2、弹窗
JDialog,用来被弹出,默认具有关闭事件
package com.fy.lesson04; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; //主窗口 public class DialogDemo extends JFrame { public DialogDemo() { this.setVisible(true); this.setSize(700,500); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //JFrame 放东西,容器 Container contentPane = this.getContentPane(); //绝对布局 contentPane.setLayout(null); //按钮 JButton button = new JButton("点击弹出一个对话框"); //创建 button.setBounds(30,30,200,200); //点击这个按钮的时候弹出一个弹窗,需要一个监听事件 button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //弹窗 new MyDialogDemo(); } }); contentPane.add(button); } public static void main(String[] args) { new DialogDemo(); } } //弹窗的窗口 class MyDialogDemo extends JDialog{ public MyDialogDemo() { this.setVisible(true); this.setBounds(100,100,500,500); //弹窗默认有关闭功能 //this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); Container contentPane = this.getContentPane(); contentPane.setLayout(null); Label label = new Label("学习GUI"); label.setBounds(100,100,200,200); contentPane.add(label); } }
3.3、标签
3.3.1、label
new JLabel("XXX");
3.3.2、图标 ICON
package com.fy.lesson04; import javax.swing.*; import java.awt.*; //图标是一个接口,需要实现类,Frame继承 public class IconDemo extends JFrame implements Icon { public int width; public int height; public IconDemo() { } public IconDemo(int width, int height) { this.width = width; this.height = height; } public void init() { IconDemo iconDemo = new IconDemo(15,15); //图标放在标签,也可以放在按钮上 JLabel Label = new JLabel("iconDemo",iconDemo,SwingConstants.CENTER); Container contentPane = getContentPane(); contentPane.add(Label); this.setVisible(true); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); this.setBounds(100,100,200,200); } public static void main(String[] args) { new IconDemo().init(); } @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; } }
3.3.3、图片Icon
package com.fy.lesson04; import javax.swing.*; import java.awt.*; import java.net.URL; public class ImageIconDemo extends JFrame { public ImageIconDemo() { //获取图片的地址,getResource:通过class这个类获取当前class这个类下的同级资源 JLabel label = new JLabel("ImageIcon"); URL url = ImageIconDemo.class.getResource("java.jpg"); ImageIcon imageIcon = new ImageIcon(url); label.setIcon(imageIcon); label.setHorizontalAlignment(SwingConstants.CENTER); Container contentPane = getContentPane(); contentPane.add(label); setVisible(true); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); setBounds(100,100,300,300); } public static void main(String[] args) { new ImageIconDemo(); } }
3.4、面板
3.3.1、JPanel
package com.fy.lesson05; import javax.swing.*; import java.awt.*; public class JPanelDemo extends JFrame { public JPanelDemo() { Container contentPane = this.getContentPane(); //添加文本,表格布局两行一列,间距10 contentPane.setLayout(new GridLayout(2,1,10,10)); JPanel jPanel1 = new JPanel(new GridLayout(1,3)); JPanel jPanel2 = new JPanel(new GridLayout(1,2)); JPanel jPanel3 = new JPanel(new GridLayout(2,1)); JPanel jPanel4 = new JPanel(new GridLayout(3,2)); jPanel1.add(new JButton("1")); jPanel1.add(new JButton("1")); jPanel1.add(new JButton("1")); jPanel2.add(new JButton("2")); jPanel2.add(new JButton("2")); jPanel3.add(new JButton("3")); jPanel3.add(new JButton("3")); jPanel4.add(new JButton("4")); jPanel4.add(new JButton("4")); jPanel4.add(new JButton("4")); jPanel4.add(new JButton("4")); jPanel4.add(new JButton("4")); jPanel4.add(new JButton("4")); contentPane.add(jPanel1); contentPane.add(jPanel2); contentPane.add(jPanel3); contentPane.add(jPanel4); this.setVisible(true); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); this.pack(); this.setSize(500,500); } public static void main(String[] args) { new JPanelDemo(); } }
3.3.2、JScrollPanel(滚动条)
package com.fy.lesson05; import javax.swing.*; import java.awt.*; public class JScrollDemo extends JFrame { public JScrollDemo() { Container contentPane = this.getContentPane(); //文本域 JTextArea jTextArea = new JTextArea(20,20); jTextArea.setText("学习中"); //Scroll面板 JScrollPane jScrollPane = new JScrollPane(jTextArea); contentPane.add(jScrollPane); this.setVisible(true); this.setBounds(100,100,500,300); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JScrollDemo(); } }
3.5、按钮
3.5.1、图片按钮
package com.fy.lesson05; import javax.swing.*; import java.awt.*; import java.net.URL; public class JButtonDemo01 extends JFrame { public JButtonDemo01() { Container container = this.getContentPane(); //将一个图片变成图标 URL url = JButtonDemo01.class.getResource("java.jpg"); Icon icon = new ImageIcon(url); //把这个图标加在按钮上 JButton button = new JButton(); button.setIcon(icon); button.setToolTipText("图片按钮"); container.add(button); this.setVisible(true); this.setSize(300,300); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JButtonDemo01(); } }
3.5.2、单选按钮
package com.fy.lesson05; import javax.swing.*; import java.awt.*; import java.net.URL; public class JButtonDemo02 extends JFrame { public JButtonDemo02() { Container container = this.getContentPane(); //将图片变成图标 URL url = JButtonDemo02.class.getResource("java.jpg"); Icon icon = new ImageIcon(url); //单选框 JRadioButton radioButton1 = new JRadioButton("JRadioButton01"); JRadioButton radioButton2 = new JRadioButton("JRadioButton02"); JRadioButton radioButton3 = new JRadioButton("JRadioButton03"); //由于单选框只能选择一个,分组(三个分在一个组里,这个组只能选择一个) ButtonGroup group = new ButtonGroup(); group.add(radioButton1); group.add(radioButton2); group.add(radioButton3); container.add(radioButton1,BorderLayout.CENTER); container.add(radioButton2,BorderLayout.NORTH); container.add(radioButton3,BorderLayout.SOUTH); this.setVisible(true); this.setSize(500,500); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JButtonDemo02(); } }
3.5.3、复选按钮
package com.fy.lesson05; import javax.swing.*; import java.awt.*; import java.net.URL; public class JButtonDemo03 extends JFrame { public JButtonDemo03(){ Container container = this.getContentPane(); URL url = JButtonDemo03.class.getResource("java.jpg"); Icon icon = new ImageIcon(url); //多选框 JCheckBox checkBox01 = new JCheckBox("checkBox01"); JCheckBox checkBox02 = new JCheckBox("checkBox02"); JCheckBox checkBox03 = new JCheckBox("checkBox03"); container.add(checkBox01,BorderLayout.CENTER); container.add(checkBox02,BorderLayout.NORTH); container.add(checkBox03,BorderLayout.SOUTH); this.setVisible(true); this.setSize(300,300); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JButtonDemo03(); } }
3.6、列表
3.6.1、下拉框
package com.fy.lesson06; import javax.swing.*; import java.awt.*; //下拉框 public class TestComboboxDemo01 extends JFrame { public TestComboboxDemo01() { Container container = this.getContentPane(); JComboBox status = new JComboBox(); status.addItem(null); status.addItem("正在上映"); status.addItem("已下架"); status.addItem("即将上映"); container.add(status); this.setVisible(true); this.setSize(500,300); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new TestComboboxDemo01(); } }
3.6.2、列表框
package com.fy.lesson06; import javax.swing.*; import java.awt.*; import java.util.Vector; //列表框 public class TestComboboxDemo02 extends JFrame { public TestComboboxDemo02() { Container container = this.getContentPane(); //生成列表的内容 //String[] contents = {"1","2","3"}; Vector contents = new Vector(); //列表中需要放内容 JList JList = new JList(contents); contents.add("张三"); contents.add("李四"); contents.add("王五"); container.add(JList); this.setVisible(true); this.setSize(500,300); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new TestComboboxDemo02(); } }
-
应用场景:
-
选择地区,或者一些单个选项
-
列表,展示信息,一般是动态扩容
-
3.7、文本框
3.7.1、文本框
package com.fy.lesson06; import javax.swing.*; import java.awt.*; public class TestTextDemo01 extends JFrame { public TestTextDemo01() { Container container = this.getContentPane(); JTextField textField01 = new JTextField("hello"); JTextField textField02 = new JTextField("world",20); container.add(textField01,BorderLayout.NORTH); container.add(textField02,BorderLayout.SOUTH); this.setVisible(true); this.setSize(500,300); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new TestTextDemo01(); } }
3.7.2、密码框
package com.fy.lesson06; import javax.swing.*; import java.awt.*; public class TestTextDemo02 extends JFrame { public TestTextDemo02() { Container container = this.getContentPane(); JPasswordField passwordField = new JPasswordField(); //***** passwordField.setEchoChar('*'); container.add(passwordField); this.setVisible(true); this.setSize(500,300); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new TestTextDemo02(); } }
3.7.3、文本域
package com.fy.lesson05; import javax.swing.*; import java.awt.*; public class JScrollDemo extends JFrame { public JScrollDemo() { Container contentPane = this.getContentPane(); //文本域 JTextArea jTextArea = new JTextArea(20,20); jTextArea.setText("学习中"); //Scroll面板 JScrollPane jScrollPane = new JScrollPane(jTextArea); contentPane.add(jScrollPane); this.setVisible(true); this.setBounds(100,100,500,300); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JScrollDemo(); } }
贪吃蛇
帧,如果时间片足够小,就是动画,一秒30帧,连起来就是动画,拆开就是静态的图片!
键盘监听
定时器Timer
package com.fy.snake; 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 GamePanel()); frame.setVisible(true); } }
package com.fy.snake; import javax.swing.*; import java.net.URL; //数据中心 public class Date { //相对路径 Java.jpg //绝对路径 / 相当于当前的项目 public static URL headerURL = Date.class.getResource("statics/header.png"); public static ImageIcon header = new ImageIcon(headerURL); public static URL upURL = Date.class.getResource("statics/up.png"); public static URL downURL = Date.class.getResource("statics/down.png"); public static URL leftURL = Date.class.getResource("statics/left.png"); public static URL rightURL = Date.class.getResource("statics/right.png"); public static ImageIcon up = new ImageIcon(upURL); public static ImageIcon down = new ImageIcon(downURL); public static ImageIcon left = new ImageIcon(leftURL); public static ImageIcon right = new ImageIcon(rightURL); public static URL bodyURL = Date.class.getResource("statics/body.png"); public static ImageIcon body = new ImageIcon(bodyURL); public static URL foodURL = Date.class.getResource("statics/food.png"); public static ImageIcon food = new ImageIcon(foodURL); }
package com.fy.snake; 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 GamePanel extends JPanel implements KeyListener, ActionListener { //定义蛇的数据结构 int length; //蛇的长度 int[] snakeX = new int[600]; //蛇的X坐标25*25 int[] snakeY = new int[500]; //蛇的Y坐标25*25 String fx; //初始方向向右 //食物的坐标 int foodx; int foody; Random random = new Random(); int score; //成绩 //游戏当前的状态 boolean isStart = false; //默认是不开始 boolean isFail = false; //游戏失败状态 //定时器 以毫秒为单位 1000ms = 1s Timer timer = new Timer(100,this); //监听这个对象,100毫秒刷新一次 //构造器 public GamePanel() { init(); //获得焦点和键盘事件 this.setFocusable(true); //获得焦点事件 this.addKeyListener(this); //获得当前键盘监听事件,如果写在别的类,那就new一个 timer.start(); //游戏一开始,定时器就启动 } //初始化方法 public void init(){ 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); score = 0; } //绘制面板,我们游戏中的所有东西,都是用这个画笔来画 @Override protected void paintComponent(Graphics g) { super.paintComponent(g); //清屏:不会出现闪烁,不用的话会出现闪烁 //绘制静态的面板 this.setBackground(Color.WHITE); Date.header.paintIcon(this,g,25,0); //头部广告栏画上去 g.fillRect(25,75,850,600); //默认的游戏界面 //画积分 g.setColor(Color.WHITE); g.setFont(new Font("微软雅黑",Font.BOLD,18)); //Font.BOLD:粗体 g.drawString("长度:"+length,750,35); g.drawString("分数:"+score,750,50); //画食物 Date.food.paintIcon(this,g,foodx,foody); //把小蛇画上去 if (fx.equals("R")) { Date.right.paintIcon(this,g,snakeX[0],snakeY[0]); //蛇头初始化向右,需要通过方向来判断 }else if (fx.equals("L")){ Date.left.paintIcon(this,g,snakeX[0],snakeY[0]); //蛇头初始化向右,需要通过方向来判断 }else if (fx.equals("U")) { Date.up.paintIcon(this,g,snakeX[0],snakeY[0]); //蛇头初始化向右,需要通过方向来判断 }else if (fx.equals("D")) { Date.down.paintIcon(this,g,snakeX[0],snakeY[0]); //蛇头初始化向右,需要通过方向来判断 } //蛇的身体增加,用动态表示 for (int i = 1; i < length; i++) { Date.body.paintIcon(this,g,snakeX[i],snakeY[i]); } //游戏状态 if (isStart == false) { g.setColor(Color.WHITE); g.setFont(new Font("微软雅黑",Font.BOLD,40)); //Font.BOLD:粗体 g.drawString("按下空格开始游戏",300,300); } //失败判断 if (isFail) { g.setColor(Color.RED); g.setFont(new Font("微软雅黑",Font.BOLD,40)); //Font.BOLD:粗体 g.drawString("失败,按下空格重新开始",300,300); } } //键盘监听事件 @Override public 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_UP) { fx = "U"; }else if (keyCode == KeyEvent.VK_DOWN) { fx = "D"; }else if (keyCode == KeyEvent.VK_LEFT) { fx = "L"; }else if (keyCode == KeyEvent.VK_RIGHT) { fx = "R"; } } //事件监听---需要通过固定时间来刷新,1s=10次 @Override public void actionPerformed(ActionEvent e) { if (isStart && isFail==false) { //如果游戏是开始状态,就让小蛇动起来 //吃食物 if (snakeX[0] == foodx && snakeY[0] == foody) { length++; //长度 + 1 //分数+10 score += 10; //再次随机生成食物 foodx = 25 + 25*random.nextInt(34); foody = 75 + 25*random.nextInt(24); } //移动 for (int i = length-1; i > 0; i--) { //后一节移到前一节的位置,snake[1] = snake[0]; snakeX[i] = snakeX[i-1]; //向前移动一节 snakeY[i] = snakeY[i-1]; } //走向 if (fx.equals("R")) { snakeX[0] = snakeX[0] + 25; if (snakeX[0]>850) { snakeX[0] = 25; } //边界判断 }else if (fx.equals("L")) { snakeX[0] = snakeX[0] - 25; if (snakeX[0]<25) { snakeX[0] = 850; } //边界判断 }else if (fx.equals("U")) { snakeY[0] = snakeY[0] - 25; if (snakeY[0]<75) { snakeY[0] = 650; } //边界判断 }else if (fx.equals("D")) { snakeY[0] = snakeY[0] + 25; if (snakeY[0]>650) { snakeY[0] = 75; } //边界判断 } //失败判定,撞到自己就算失败 for (int i = 1; i < length; i++) { if (snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]) { isFail = true; } } repaint(); //重画页面 } timer.start(); //定时器开始 } @Override public void keyTyped(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { } }