java GUI编程
一、GUI编程简介
- GUI:图形用户界面,Graphical User Interface,简称 GUI,又称图形用户接口
- 组件
- 窗口
- 弹窗
- 面板
- 文本框
- 列表框
- 按钮
- 图片
- 监听事件
- 鼠标事件
- 键盘事件
- 外挂:因为Java是基于JVM运行的,所以不会被检测出来
- 破解工具
- 简介
- GUI的核心技术:Swing AWT
- 不流行的原因:
- 因为界面不美观
- 需要jre环境
- 学习原因:
- MVC架构的基础,后期需要了解MVC架构,了解监听
- 可以写出自己心中想要的一些小工具
- 工作时,可能需要维护到swing界面,概率很小,因为这个技术已经很老了
二、AWT
1、AWT介绍
- AWT(抽象窗口工具)介绍
-
包含了很多类和接口
-
Eclipse:就是java写的
-
元素:窗口、按钮、文本框
-
java.awt包中
-
awt包总体框架:
-
补充知识:java用的包都在rt.jar中,可解压打开
-
2、Frame窗口程序实例
package www.xiaoxiao.com;
import java.awt.*;
public class FrameDemo {
public static void main(String[] args) {
Frame frame = new Frame("myFist window program");
//设置可见性
frame.setVisible(true);
//设置长宽
frame.setSize(400,400);
//设置初使位置
frame.setLocation(100,100);
//设置背景颜色
frame.setBackground(new Color(6, 248, 190));
//设置固定大小
frame.setResizable(false);
}
}
通过封装实现多个窗口:
package www.xiaoxiao.com;
import java.awt.*;
public class FrameDemo02 {
public static void main(String[] args) {
new MyFrame(100,100,400,400).setBackground(Color.BLUE);
new MyFrame(600,100,400,400).setBackground(Color.CYAN);
new MyFrame(600,600,400,400).setBackground(Color.black);
new MyFrame(100,600,400,400).setBackground(Color.GRAY);
}
}
class MyFrame extends Frame{
static int id=0;//计数器
public MyFrame(int x,int y,int w,int h) {
super("myFrame"+(id++));
setLocation(x,y);//子类继承了父类的方法
this.setLocation(x,y);//不管是用this还是super,子类现在并没有重写父类的方法,因此都是调用父类的方法
//super.setLocation(x,y);
setResizable(false);
setSize(w,h);
setVisible(true);
}
}
3、面板Panel实例
package www.xiaoxiao.com.AWT;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
//面板
public class PanelDemo {
public static void main(String[] args) {
Frame frame=new Frame();
Panel panel=new Panel();
frame.setVisible(true);
frame.setBounds(200,200,400,400);
frame.setBackground(Color.CYAN);
panel.setBounds(100,100,200,200);//设置属性是相对于add到的容器来说的
panel.setVisible(true);
panel.setBackground(Color.BLUE);
frame.add(panel);
frame.setLayout(null);//不设置布局无效果,清空布局,默认布局是继承自Window的BorderLayout,会覆盖
//设置关闭按钮监听
//使用适配器模式,只重写窗口closeing事件
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//返回0为正常退出
}
});
}
}
- 补充:(为什么Frame要setvisible=true,而其他组件不需要设置)经调试,发现源码中:
- Window(顶级窗口)的visible初始值为false(Frame.visible为false)
- 而Component的visible的初始值为true,即按钮面板等组件的visible属性默认为true
4、Layout布局
- 流式布局:布局方式像流一样,可以指定以左中右为开始位置部件依次进行顺序排列
package www.xiaoxiao.com.AWT;
import java.awt.*;
public class LayoutDemo01 {
public static void main(String[] args) {
//流式布局:可以定义从中间、左、右来进行排列 ,add的组件按顺序依次排列
Frame frame = new Frame("流式布局");
Button btn1 = new Button("btn1");
Button btn2 = new Button("btn2");
Button btn3 = new Button("btn3");
frame.add(btn1);
frame.add(btn2);
frame.add(btn3);
frame.setVisible(true);
frame.setSize(500,500);
frame.setLayout(new FlowLayout(FlowLayout.LEFT));
frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
frame.setLayout(new FlowLayout(FlowLayout.CENTER));
frame.setLayout(new FlowLayout(FlowLayout.CENTER,50,50));//后面两个参数为组件间的间隙
}
}
- 东南西北中布局(BorderLayout,Frame的默认布局)
package www.xiaoxiao.com.AWT;
import java.awt.*;
//东南西北中布局
public class LayoutDemo02 {
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.setVisible(true);
frame.setSize(500,500);
//Frame的默认布局就是BorderLayout
//BorderLayout borderLayout = new BorderLayout(50,50);
//frame.setLayout(borderLayout);
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);
//如果add方法不指定第二个参数(容器),默认会写到BorderLayout.Center中,要注意一个组件对象只能写到一个地方,对同一个组件对象进行多次位置变化时,以最后一次变化为准
}
}
*:Frame继承自Window,window的初使化方法中默认设置为borderLayout,如下图。
- 网格布局GridLayout
package www.xiaoxiao.com.AWT;
import java.awt.*;
public class LayoutDemo03 {
public static void main(String[] args) {
Frame frame=new Frame("GridLayout");
Button bt1=new Button("bt1");
Button bt2=new Button("bt2");
Button bt3=new Button("bt3");
Button bt4=new Button("bt4");
Button bt5=new Button("bt5");
frame.setVisible(true);
frame.setSize(500,500);
frame.setLayout(new GridLayout(2,3,50,50));
frame.add(bt1);
//frame.add(bt2);重复加没用
frame.add(bt2);
frame.add(bt3);
frame.add(bt4);
frame.add(bt5);
}
}
5、布局练习:实现下图的嵌套布局
package www.xiaoxiao.com.AWT;
import javafx.scene.layout.Pane;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class LayoutTestDemo {
public static void main(String[] args) {
Frame frame = new Frame("课堂练习");
Panel panel1=new Panel();
Panel panel2=new Panel();
Panel panel3=new Panel();
Panel panel4=new Panel();
panel1.setBackground(Color.CYAN);
panel2.setBackground(Color.blue);
frame.setBounds(300,300,300,300);
frame.add(panel1);
frame.add(panel2);
panel1.setLayout(new BorderLayout());
panel1.add(new Button("no1West"),BorderLayout.WEST);
panel1.add(new Button("no1Eest"),BorderLayout.EAST);
panel1.add(panel3);//默认为添加到BorderLayout.Center
panel3.setLayout(new GridLayout(2,1));
panel3.add(new Button("no1CenterNorth"));
panel3.add(new Button("no1CenterSouth"));
panel2.setLayout(new BorderLayout());
panel2.add(new Button("no2West"),BorderLayout.WEST);
panel2.add(new Button("no2Eest"),BorderLayout.EAST);
panel2.add(panel4);
panel4.setLayout(new GridLayout(2,2));
panel4.add(new Button("btn1"));
panel4.add(new Button("btn2"));
panel4.add(new Button("btn3"));
panel4.add(new Button("btn4"));
frame.setLayout(new GridLayout(2,1));
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
6、AWT(抽象窗口工具)总结
- Frame是一个顶级窗口
- Panel无法单独显示,必须添加到某个容器中
- 布局管理器:
- 流式
- 东西南北中
- 网格式
7、事件监听
-
事件监听:当某个事情发生时,要执行什么操作
-
package www.xiaoxiao.com.AWT; 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 MonitorDemo01 { public static void main(String[] args) { //事件监听 Frame frame=new Frame(); Button button1=new Button("button"); button1.addActionListener(new MyListener()); frame.add(button1); frame.pack();//自适应 WindowClose(frame); frame.setVisible(true); } //抽取方法 private static void WindowClose(Frame frame){ frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } } class MyListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { System.out.println("aaa"); } }
-
-
多个部件共用一个监听事件
-
package www.xiaoxiao.com.AWT; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Date; //多个组件共用一个监听 public class MonitorDemo02 { public static void main(String[] args) { Frame frame = new Frame("start-stop"); Button button1 = new Button("start"); Button button2 = new Button("stop"); button1.setActionCommand("already start"); frame.setBounds(500,500,500,500); frame.setLayout(new FlowLayout()); frame.add(button1); frame.add(button2); frame.setVisible(true); MyMonitor myMonitor=new MyMonitor(); //这样做的好处是节省了代码 button1.addActionListener(myMonitor); button2.addActionListener(myMonitor); } } class MyMonitor implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("stop")){ System.out.print(new Date(e.getWhen()).toLocaleString()+": "); System.out.println(e.getActionCommand());//如果组件中设置了ActionCommand则返回设置的,否则返回标题 }else{ System.out.println("我没停止"); } } }
-
8、文本框及其监听
package www.xiaoxiao.com.AWT;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//输入框及其监听事件
public class TextFieldDemo {
public static void main(String[] args) {
//一般项目的main方法中只有一个启动方法
new MyTestFrame();
}
}
class MyTestFrame extends Frame{
public MyTestFrame() throws HeadlessException {
TextField textField=new TextField();
add(textField);//相当于this.add()
MyTestListener testListener=new MyTestListener();
//TextField的监听事件是当回车按下
textField.addActionListener(testListener);
//设置回显字符(多用于密码密码)
textField.setEchoChar('*');
setVisible(true);
pack();//自适应
setLocation(400,440);
setSize(500,500);
}
}
class MyTestListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
TextField field=(TextField) e.getSource();//获取资源
System.out.println(field.getText());
field.setText(null);//按下回车后将文本框内容置为null
}
}
9、简易计算机的实现
-
原始代码
//入口类 public class SimplyCalc { public static void main(String[] args) { //程序入口 new MyCalcFrame(); } } //窗体实现类 import java.awt.*; public class MyCalcFrame extends Frame { public MyCalcFrame(){ TextField num1 = new TextField(10);//长度 TextField num2 = new TextField(10);//长度 TextField num3 = new TextField(20);//长度 Button equal = new Button("="); Label label = new Label("+"); equal.addActionListener(new MyListener(num1,num2,num3)); setLayout(new FlowLayout()); add(num1); add(label); add(num2); add(equal); add(num3); pack();//要在加之前用,否则会出错 setLocation(500,500); setVisible(true); } } //监听实现类 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class MyListener implements ActionListener { private TextField num1; private TextField num2; private TextField num3; public MyListener(TextField num1, TextField num2, TextField num3) { this.num1=num1; this.num2=num2; this.num3=num3; } @Override public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(num1.getText()); int n2 = Integer.parseInt(num2.getText()); num3.setText(""+(n1+n2)); num1.setText(""); num2.setText(""); } }
-
使用组合的方式优化
//入口 public class SimplyCalc { public static void main(String[] args) { //程序入口 new MyCalcFrame().load(); } } //窗体实现类,将属性和方法抽离,使其更加对象化 import java.awt.*; public class MyCalcFrame extends Frame { //属性,要写在构造方法前,否则MyListener无法引用 TextField num1,num2,num3; //方法,直接调用方法 public void load(){ num1 = new TextField(10);//长度 num2 = new TextField(10);//长度 num3 = new TextField(20);//长度 Button equal = new Button("="); Label label = new Label("+"); equal.addActionListener(new MyListener(this)); setLayout(new FlowLayout()); add(num1); add(label); add(num2); add(equal); add(num3); pack();//要在加之前用,否则会出错 setLocation(500,500); setVisible(true); } } //监听实现类,使用组合的方式,直接使用MyCalcFrame当做属性,可以简化代码 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class MyListener implements ActionListener { //使用组合的方法直接调用对象就可心使用里面的属性了 private MyCalcFrame myCalcFrame=null; public MyListener(MyCalcFrame myCalcFrame) { this.myCalcFrame=myCalcFrame; } @Override public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(myCalcFrame.num1.getText()); int n2 = Integer.parseInt(myCalcFrame.num2.getText()); myCalcFrame.num3.setText(""+(n1+n2)); myCalcFrame.num1.setText(""); myCalcFrame.num2.setText(""); } }
-
使用内部类的方式(更好的包装)
//内部类最大的好处,就是可以畅通无阻的访问外部的属性和方法 //入口 public class SimplyCalc { public static void main(String[] args) { //程序入口 new MyCalcFrame().load(); } } //实现 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class MyCalcFrame extends Frame { //属性,要写在构造方法前,否则MyListener无法引用 TextField num1,num2,num3; //方法,直接调用方法 public void load(){ num1 = new TextField(10);//长度 num2 = new TextField(10);//长度 num3 = new TextField(20);//长度 Button equal = new Button("="); Label label = new Label("+"); equal.addActionListener(new MyListener()); setLayout(new FlowLayout()); add(num1); add(label); add(num2); add(equal); add(num3); pack();//要在加之前用,否则会出错 setLocation(500,500); setVisible(true); } private class MyListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(num1.getText()); int n2 = Integer.parseInt(num2.getText()); num3.setText(""+(n1+n2)); num1.setText(""); num2.setText(""); } } }
10、画笔
package www.xiaoxiao.com.AWT;
import java.awt.*;
public class PaintDemo {
public static void main(String[] args) {
new MyPaint().overLoad();
}
}
class MyPaint extends Frame{
public void overLoad(){
setBounds(300,300,600,500);
setVisible(true);//调用这个方法默认会调用repaint()方法进行重绘
}
@Override
public void paint(Graphics g) {
g.setColor(Color.CYAN);
//g.drawRect(100,200,88,99);
g.fillRect(100,200,88,99);
g.setColor(Color.BLUE);
//g.drawOval(200,200,100,100);
g.fillOval(200,200,100,100);
//一般来说在画笔使用完成后,要将其初始化为原始颜色,方便下次调用
//默认为黑色
g.setColor(Color.BLACK);
}
}
11、鼠标监听,实现单击一下鼠标画一个点
- 实现思想
package www.xiaoxiao.com.AWT;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
public class MousePaintPointDemo {
public static void main(String[] args) {
new MyMouseFrame("鼠标监听");
}
}
//首先要有个窗体
class MyMouseFrame extends Frame{
ArrayList points;
public MyMouseFrame(String title){
super(title);
points=new ArrayList();
setBounds(300,300,400,500);
addMouseListener(new MyMouseLissener());
setVisible(true);
}
@Override
public void paint(Graphics g) {
super.paint(g);
Iterator iterator = points.iterator();
while (iterator.hasNext()){
Point next = (Point) iterator.next();
g.setColor(Color.BLUE);
g.fillOval(next.x,next.y,10,10);
}
}
public void addPoint(Point point){
points.add(point);
}
//单击鼠标监听事件,适配器模式
class MyMouseLissener extends MouseAdapter{
@Override
public void mousePressed(MouseEvent e) {
//鼠标单击时获取鼠标的位置(就是点的位置),将点加到ArrayList中
//MyMouseFrame frame = (MyMouseFrame) e.getSource();//获取资源对象,为当前窗体
int x = e.getX();//获取x坐标
int y = e.getY();//获取y会标
addPoint(new Point(x,y));
repaint();
}
}
}
12、窗口监听
package www.xiaoxiao.com.AWT;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class WindowLinsenerDemo {
public static void main(String[] args) {
new MyFrame1();
}
}
class MyFrame1 extends Frame{
public MyFrame1() throws HeadlessException {
setBounds(500,400,500,500);
setBackground(Color.BLUE);
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("窗口正在关闭");
}
@Override
public void windowIconified(WindowEvent e) {
//窗口最小化
System.out.println("窗口最小化");
}
@Override
public void windowDeiconified(WindowEvent e) {
//窗口从最小化恢复
System.out.println("窗口从最小化恢复");
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println("窗口激活");
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println("窗口未激活");
}
});
}
}
13、键盘监听
package www.xiaoxiao.com.AWT;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class KeyDemo {
public static void main(String[] args) {
new MyKeyFrame();
}
}
class MyKeyFrame extends Frame{
public MyKeyFrame() throws HeadlessException {
setBounds(100,100,500,500);
setVisible(true);
addKeyListener(new KeyAdapter() {
//键入字符
@Override
public void keyTyped(KeyEvent e) {
int keyCode = e.getKeyCode();
System.out.println((char) keyCode+"typed");
}
//按下
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
System.out.println((char)keyCode+"yaxia");
}
//弹起
@Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
System.out.println((char)keyCode+"released");
}
});
}
}
三、Swing
- Swing和AWT差不多,是在AWT的基础上进行的优化,多了一些组件等
1、JFrame窗口
- 关于设置jFrame的背景
- 在直接调用setBackground(Color.red)这个方法后,的确设置了JFrame的背景颜色,而你看到的却不是直接的JFrame,而是JFrame.getContentPane()。而JFrame上的contentPane默认是Color.WHITE的,所以,无论对JFrame怎么设置背景颜色,看到的都只是contentPane.
package www.xiaoxiao.com.Swing;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.colorchooser.ColorSelectionModel;
import java.awt.*;
public class WindowDemo {
//初始化
public void init(){
JFrame jFrame = new JFrame();
jFrame.setBounds(100,100,500,500);
//不能直接设置背景
//jFrame.setBackground(Color.BLUE);无效果
//方法一:
//1.获取容器
Container contentPane = jFrame.getContentPane();
//2.设置容器的颜色
contentPane.setBackground(Color.blue);
//方法二:jFrame.getContentPane().setVisible(false)将其设置为不可见,但这种方式会导致加进来的组件不可见
//jFrame.getContentPane().setVisible(false);
//jFrame.setBackground(Color.BLUE);
contentPane.setLayout(new GridLayout(2,2));
//面板
JPanel jPanel = new JPanel();
jPanel.setSize(20,20);
//jPanel.setBounds(10,10,200,200);
jPanel.setBackground(Color.CYAN);
jFrame.add(jPanel);
JPanel jPanel2 = new JPanel();
jPanel2.setSize(20,20);
//jPanel.setBounds(10,10,200,200);
jPanel2.setBackground(Color.GRAY);
jFrame.add(jPanel2);
JLabel jLabel = new JLabel("hello world!");
//设置水平居中
jLabel.setHorizontalAlignment(SwingConstants.CENTER);
jFrame.add(jLabel);
//设置退出
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setVisible(true);
}
public static void main(String[] args) {
new WindowDemo().init();
}
}
2、JDialog
package www.xiaoxiao.com.Swing;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//弹窗
public class JDialogDemo {
public JDialogDemo() {
JFrame jFrame = new JFrame();
jFrame.setBounds(100,100,800,400);
Container contentPane = jFrame.getContentPane();
contentPane.setBackground(Color.BLUE);
JButton button = new JButton("click me");
button.setBounds(100,100,200,50);
//button监听
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new MyJDialogDemo();
}
});
jFrame.add(button);
//绝对布局
jFrame.setLayout(null);
//设置关闭退出
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setVisible(true);
}
public static void main(String[] args) {
new JDialogDemo();
}
}
//JDialog框
class MyJDialogDemo extends JDialog{
public MyJDialogDemo() {
setBounds(200,200,90,90);
setLayout(null);
JLabel jLabel = new JLabel("1234567890");
jLabel.setBounds(1,1,70,70);
add(jLabel);
this.setVisible(true);
}
}
3、Icon和ImageIcon
-
图标可以加到label和button等组件上。
-
要实现Icon的重绘,需要实现Icon。
-
Icon:
-
package www.xiaoxiao.com.Swing; import javax.swing.*; import java.awt.*; //要实现Icon的绘制需要实现Icon public class IconDemo extends JFrame implements Icon { //定义一个宽和高(图标的宽和高) private int Width; private int Height; public static void main(String[] args) { new IconDemo(20,20); } public IconDemo(int width, int height) { Width = width; Height = height; JLabel icontest = new JLabel("icontest",this,SwingConstants.CENTER); //icontest.setIcon(this); //icontest.setHorizontalAlignment(SwingConstants.CENTER); setBounds(100,100,500,500); add(icontest); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } @Override public void paintIcon(Component c, Graphics g, int x, int y) { g.fillOval(x,y,Width,Height);//x,y为位置 } @Override public int getIconWidth() { return Width; } @Override public int getIconHeight() { return Height; } }
-
-
ImageIcon:是Icon的一个实现类,不是接口
-
package www.xiaoxiao.com.Swing; import javax.imageio.ImageIO; import javax.swing.*; import java.net.URL; public class ImageIconDemo extends JFrame { public ImageIconDemo() throws Exception{ URL resource = ImageIconDemo.class.getResource("tx.jpg");//获取当前目录下的文件,需要重新编译 setBounds(100,110,500,500); ImageIcon imageIcon = new ImageIcon(resource);//参数为url类型 JLabel test = new JLabel("test", imageIcon, SwingConstants.CENTER); add(test); setIconImage(ImageIO.read(resource));//JFrame设置图标 setVisible(true); } public static void main(String[] args) throws Exception{ new ImageIconDemo(); } }
-
4、面板Jpanel和JScrollPanel
-
JPanel
package www.xiaoxiao.com.Swing; import javax.swing.*; import java.awt.*; public class JpanelDemo extends JFrame { public JpanelDemo() throws HeadlessException { setLayout(new GridLayout(2,2,10,10));//第三、四个参数为间距 setBounds(100,100,500,500); JPanel jPanel1 = new JPanel(new GridLayout(1, 2)); JPanel jPanel2 = new JPanel(new GridLayout(2, 1)); JPanel jPanel3 = new JPanel(new GridLayout(3, 2)); JPanel jPanel4 = new JPanel(new GridLayout(2, 3)); add(jPanel1); add(jPanel2); add(jPanel3); add(jPanel4); 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")); jPanel3.add(new JButton("3")); jPanel3.add(new JButton("3")); 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")); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new JpanelDemo(); } }
-
JScrollPanel
package www.xiaoxiao.com.Swing; import javax.swing.*; import java.awt.*; public class JScrollPanelDemo extends JFrame { public JScrollPanelDemo() throws HeadlessException { Container container=getContentPane(); setBounds(100,100,500,500); TextArea textArea = new TextArea(20, 50); JScrollPane jScrollPane = new JScrollPane(textArea); add(jScrollPane); setVisible(true); } public static void main(String[] args) { new JScrollPanelDemo(); } }
5、按钮
-
图片按钮
package www.xiaoxiao.com.Swing; import javax.swing.*; import java.awt.*; import java.net.URL; public class ImageButtonDemo extends JFrame { //图片按钮就是给普通迎按钮加个图片 public ImageButtonDemo() { //获取容器,用JFrame尽量用Container进行add等操作 Container contentPane = getContentPane(); URL resource = ImageButtonDemo.class.getResource("tx.jpg");//直接获取同级目录下的图片 ImageIcon imageIcon=new ImageIcon(resource);//创建一个ImageIcon,需要一个URL参数 JButton but1 = new JButton(); but1.setIcon(imageIcon); but1.setToolTipText("这是一个图片按钮");//设置鼠标悬浮提示 contentPane.add(but1); setSize(500,400); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new ImageButtonDemo(); } }
-
单选按钮
package www.xiaoxiao.com.Swing; import javax.swing.*; import java.awt.*; import java.net.URL; public class RadioButtonDemo extends JFrame { //图片按钮就是给普通迎按钮加个图片 public RadioButtonDemo() { //获取容器,用JFrame尽量用Container进行add等操作 Container contentPane = getContentPane(); contentPane.setLayout(new GridLayout(3,1)); JRadioButton jRadioButton01 = new JRadioButton("JRadioButton01"); JRadioButton jRadioButton02 = new JRadioButton("JRadioButton02"); JRadioButton jRadioButton03 = new JRadioButton("JRadioButton03"); //单选按钮要实现多个按钮一个可选,需要添加到同一个组中 ButtonGroup buttonGroup = new ButtonGroup(); buttonGroup.add(jRadioButton01); buttonGroup.add(jRadioButton02); buttonGroup.add(jRadioButton03); contentPane.add(jRadioButton01); contentPane.add(jRadioButton02); contentPane.add(jRadioButton03); setSize(500,400); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new RadioButtonDemo(); } }
-
复选框按钮
package www.xiaoxiao.com.Swing; import javax.swing.*; import java.awt.*; public class CheckedButtonDemo extends JFrame { //图片按钮就是给普通迎按钮加个图片 public CheckedButtonDemo() { //获取容器,用JFrame尽量用Container进行add等操作 Container contentPane = getContentPane(); contentPane.setLayout(new GridLayout(3, 1)); JCheckBox jCheckBox1= new JCheckBox("jCheckBox1"); JCheckBox jCheckBox2= new JCheckBox("jCheckBox2"); JCheckBox jCheckBox3= new JCheckBox("jCheckBox3"); jCheckBox3.setToolTipText("test"); contentPane.add(jCheckBox1); contentPane.add(jCheckBox2); contentPane.add(jCheckBox3); setSize(500, 400); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new CheckedButtonDemo(); } }
6、列表框
-
下拉列表
package www.xiaoxiao.com.Swing; import javax.swing.*; import java.awt.*; public class JComboboxDemo extends JFrame { public JComboboxDemo() throws HeadlessException { Container contentPane = getContentPane(); JComboBox jComboBox = new JComboBox(); //下拉列表需要加项 jComboBox.addItem("1"); jComboBox.addItem("2"); jComboBox.addItem("3"); contentPane.add(jComboBox); setSize(400,500); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new JComboboxDemo(); } }
-
列表框
package www.xiaoxiao.com.Swing; import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.Vector; public class DropListDemo extends JFrame { public DropListDemo() throws HeadlessException { Container contentPane = getContentPane(); //String[] arrs={"","1","2"}; //下拉列表,一般使用可动态扩容的数据类型,如Vector,这个地方不能用ArrayList,会报错,用数组可以 Vector vector=new Vector(); vector.add("1"); vector.add("2"); vector.add("3"); JList jList = new JList(vector); contentPane.add(jList); setSize(400,500); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setVisible(true); } public static void main(String[] args) { new DropListDemo(); } }
7、文本框
-
文本框、密码框、文本域
package www.xiaoxiao.com.Swing; import javafx.scene.control.PasswordField; import javax.swing.*; import java.awt.*; public class TextFiledDemo extends JFrame { public TextFiledDemo() throws HeadlessException { Container contentPane = getContentPane(); contentPane.setLayout(new GridLayout(4,1)); //文本框 JTextField jTextField = new JTextField("1",20); JTextField jTextField2 = new JTextField("2"); //密码文本框 JPasswordField passwordField = new JPasswordField(); //passwordField.setEchoChar('*'); TextArea textArea = new TextArea(); contentPane.add(jTextField); contentPane.add(jTextField2); contentPane.add(passwordField); contentPane.add(textArea); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setSize(500,500); setVisible(true); } public static void main(String[] args) { new TextFiledDemo(); } }
四、贪吃蛇小游戏
-
帧的概念:
- 时间片足够小,就形成了动画,一般游戏一秒30帧或60帧,拆开就是静态的图片。
- 要注意绘制顺序
//Snake类 import javax.swing.*; //程序主入口 public class Snake { public static void main(String[] args) { JFrame jFrame = new JFrame(); jFrame.add(new GamePanel()); jFrame.setResizable(false); jFrame.setBounds(100,100,920,800); jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); jFrame.setVisible(true); } } //面板绘制类GamePanel import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Random; import static java.awt.Font.BOLD; import static java.awt.Font.ITALIC; //面板,所有操作均在面板上实现 public class GamePanel extends JPanel implements KeyListener, ActionListener { //定义小蛇数据结构 int length;//小蛇长度 int snakeX[];//小蛇的X坐标位置数据 int snakeY[];//小蛇的Y坐标位置数据 String orientation;//蛇头方向 boolean status;//定义游戏状态:开始-停止 boolean fail;//定义失败状态 //食物坐标 int foodx; int foody; Random random; int score; Timer timer = new Timer(100, this);//创建一个定时器 public GamePanel() { init(); //设置焦点,默认为false setFocusable(true); //加键盘监听 addKeyListener(this); } //初使化 private void init() { length = 3;//默认长度为3 score=0;//分数 snakeX = new int[34];//小蛇的X坐标位置数据 snakeY = new int[26];//小蛇的Y坐标位置数据 snakeX[0] = 125; snakeY[0] = 100;//小蛇头 snakeX[1] = 100; snakeY[1] = 100;//小蛇身体 snakeX[2] = 75; snakeY[2] = 100;//小蛇身体 orientation = "right";//默认方向为向右 status = false; timer.start();//计时器开始 random = new Random();//生成食物用 //绘制食物 foodx = 25 + 25 * random.nextInt(33); foody = 75 + 25 * random.nextInt(25); fail = false; } //绘制方法,显示时自动调用 @Override protected void paintComponent(Graphics g) { super.paintComponent(g);//有清屏功能,如果不清屏会闪烁 //绘制静态面板 setBackground(Color.WHITE); g.setColor(Color.CYAN); //g.fillRect(25, 15, 850, 55);//游戏界面面板 //给一个组件绘制Icon Data.headerIcon.paintIcon(this, g, 0, 15);//头部广告栏绘制 g.setColor(Color.BLUE); g.setFont(new Font("宋体", BOLD | ITALIC, 32)); g.drawString("小狗平招商位", 75, 55); g.setColor(Color.RED); g.setFont(new Font("宋体", BOLD | ITALIC, 16)); g.drawString("小蛇长度:"+length, 750, 45); g.drawString("得分:"+score, 750, 58); g.setColor(Color.BLACK); g.fillRect(25, 75, 850, 650);//游戏界面面板 //小蛇静态绘制 //通过循环绘制身体 for (int i = 1; i <length; i++) { Data.bodyIcon.paintIcon(this, g, snakeX[i], snakeY[i]); } //根据方向画蛇头 switch (orientation) { case "right": Data.rightIcon.paintIcon(this, g, snakeX[0], snakeY[0]); break; case "left": Data.leftIcon.paintIcon(this, g, snakeX[0], snakeY[0]); break; case "up": Data.upIcon.paintIcon(this, g, snakeX[0], snakeY[0]); break; case "down": Data.downIcon.paintIcon(this, g, snakeX[0], snakeY[0]); break; } Data.foodIcon.paintIcon(this, g, foodx, foody); if (status == false) { g.setColor(Color.WHITE); g.setFont(new Font("微软雅黑", BOLD | ITALIC, 32)); g.drawString("按下空格开始游戏", 320, 400); } if (fail==true){ g.setColor(Color.red); g.setFont(new Font("微软雅黑", BOLD | ITALIC, 32)); g.drawString("失败喽,按下空格重新开始游戏", 320, 400); } } //键盘按下 @Override public void keyPressed(KeyEvent e) { int keyCode = e.getKeyCode(); switch (keyCode) { case KeyEvent.VK_SPACE: //按下空格取反,并重绘 if (fail==false){ status = !status; }else{ fail=true; init(); } repaint(); break; case KeyEvent.VK_UP: orientation = "up"; break; case KeyEvent.VK_DOWN: orientation = "down"; break; case KeyEvent.VK_RIGHT: orientation = "right"; break; case KeyEvent.VK_LEFT: orientation = "left"; break; } } @Override public void keyReleased(KeyEvent e) { } @Override public void keyTyped(KeyEvent e) { } //事件监听,用于定时器,每100ms执行一次,让小蛇动起来 @Override public void actionPerformed(ActionEvent e) { if (status && !fail) { //如果状态为true,让小蛇动起来 for (int i = length - 1; i > 0; i--) { //前一项赋值给后一项 snakeX[i] = snakeX[i-1]; snakeY[i] = snakeY[i-1]; } switch (orientation) { case "right"://向右 snakeX[0] = snakeX[0] + 25;//头动起来 if (snakeX[0] > 850) { snakeX[0] = 25; } break; case "left"://向左 snakeX[0] = snakeX[0] - 25;//头动起来 if (snakeX[0] < 25) { snakeX[0] = 850; } repaint(); break; case "up"://向上 snakeY[0] = snakeY[0] - 25;//头动起来 if (snakeY[0] < 75) { snakeY[0] = 700; } repaint(); break; case "down"://向下 snakeY[0] = snakeY[0] + 25;//头动起来 if (snakeY[0] > 700) { snakeY[0] = 75; } break; } //判断小蛇死亡 for (int j = 1; j < length; j++) { if (snakeX[0]==snakeX[j] && snakeY[0]==snakeY[j]){ fail=true; repaint(); } } if (snakeX[0] == foodx && snakeY[0] == foody) { //重绘食物 foodx = 25 + 25 * random.nextInt(33); foody = 75 + 25 * random.nextInt(25); length++;//小蛇长度+1 snakeX[length-1]=snakeX[length-2]; snakeY[length-1]=snakeY[length-2]; score+=10; } repaint(); } } } //静态资源类Data import javax.swing.*; import java.awt.*; import java.net.URL; public class Data { //Data.class.getResource这个路径是src的路径 public static URL header =Data.class.getResource("/static/header.png"); public static ImageIcon headerIcon=new ImageIcon(header); public static URL up =Data.class.getResource("/static/up.png"); public static ImageIcon upIcon=new ImageIcon(up); public static URL down =Data.class.getResource("/static/down.png"); public static ImageIcon downIcon=new ImageIcon(down); public static URL left =Data.class.getResource("/static/left.png"); public static ImageIcon leftIcon=new ImageIcon(left); public static URL right =Data.class.getResource("/static/right.png"); public static ImageIcon rightIcon=new ImageIcon(right); public static URL food =Data.class.getResource("/static/food.png"); public static ImageIcon foodIcon=new ImageIcon(food); public static URL body =Data.class.getResource("/static/body.png"); public static ImageIcon bodyIcon=new ImageIcon(body); }
本文来自博客园,作者:一只快乐的小67,转载请注明原文链接:https://www.cnblogs.com/sp520/p/16114543.html