java GUI编程
目录
GUI编程
-
Gui的核心技术:Swing AWT
-
不流行的原因:
- 界面不美观
- 需要jre环境
-
我们为什么要学习
- 可以写出自己想要的一些小工具
- 了解MVC架构,了解监听
1. AWT 抽象的窗口工具
1.1 介绍
-
包含了很多类和接口
-
用于GUI编程:图形用户界面编程
-
元素:窗口,按钮,文本框
-
概念:

1.2 组件和容器
1、Frame
//gui的第一个界面
public class demo1Frame {
public static void main(String[] args) {
//Frame
Frame frame = new Frame("我的第一个java图像界面窗口");
//需要设置可见性
frame.setVisible(true);
//设置窗口大小
frame.setSize(400,400);
//设置背景颜色
frame.setBackground(new Color(143, 186, 187));
//弹出初始位置
frame.setLocation(300,200);
//设置大小固定
frame.setResizable(false);
}
}
//窗口关闭不掉:停止java程序运行

-
封装:一次展示多个窗口
public class demo2Frame { public static void main(String[] args) { //一次展示多个窗口 new MyFrame MyFrame myFrame = new MyFrame(100, 100, 200, 200, new Color(32, 137, 133)); MyFrame myFrame2 = new MyFrame(300, 100, 300, 200, Color.pink); } } class MyFrame extends Frame{ static int id=0; public MyFrame(int x,int y,int w,int h,Color color){ super("Myframe"+(++id));//可能展示多个窗口,需要一个计数器id setBackground(color); setBounds(x,y,w,h); setVisible(true); } }
2、面板Panel
- Panel可以看成是一个空间,但不能单独存在
- Panel的许多设置跟frame一样:比如设置坐标、背景颜色等。
- 解决了关闭窗口问题:awt的解决方式
//Panel可以看成是一个空间,但不能单独存在
public class demo01Panel {
public static void main(String[] args) {
Frame frame = new Frame();
//布局的概念
Panel panel = new Panel();
//设置布局
frame.setLayout(null);
frame.setBounds(300,300,500,500);
frame.setBackground(new Color(137, 198, 170));
//panel设置坐标,相对于frame
panel.setBounds(50,50,400,400);
panel.setBackground(Color.gray);
//frame.add(panel)
frame.add(panel);
frame.setVisible(true);
//监听事件,监听窗口关闭事件 System.exit(0)
//适配器模式:
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
//结束程序
System.exit(0);
}
});
}
}
3、布局管理
-
流式布局
public class TestFlowLayout { public static void main(String[] args) { Frame frame = new Frame(); frame.setBounds(300,300,500,500); 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.add(button1); frame.add(button2); frame.add(button3); } } -
东西南北中
public class TestBorderLayout { public static void main(String[] args) { Frame frame = new Frame(); frame.setBounds(300,300,500,500); 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.setVisible(true); } }
-
表格布局
public class TestGridLayout { public static void main(String[] args) { Frame frame = new Frame("GridLayout"); frame.setBounds(300,300,500,500); frame.setVisible(true); Button b1 = new Button("b1"); Button b2 = new Button("b2"); Button b3 = new Button("b3"); Button b4 = new Button("b4"); Button b5 = new Button("b5"); Button b6 = new Button("b6"); frame.setLayout(new GridLayout(3,2));//三行两列 frame.add(b1); frame.add(b2); frame.add(b3); frame.add(b4); frame.add(b5); frame.add(b6); frame.pack();//java函数:调整此窗口的大小,以适合其子组件的首选大小和布局 } }
-
练习:
public class Demo { public static void main(String[] args){ Frame frame = new Frame("GridLayout"); frame.setBounds(300,300,500,500); frame.setVisible(true); frame.setLayout(new GridLayout(2,1)); //4个面板 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)); p1.add(new Button("east1"),BorderLayout.EAST); p1.add(new Button("west1"),BorderLayout.WEST); p2.add(new Button("p2-btn-1")); p2.add(new Button("p2-btn-2")); p1.add(p2,BorderLayout.CENTER); p3.add(new Button("east2"),BorderLayout.EAST); p3.add(new Button("west2"),BorderLayout.WEST); for (int i = 0; i < 4; i++) { p4.add(new Button("p4"+i)); } p3.add(p4,BorderLayout.CENTER); frame.add(p1); frame.add(p3); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } }
-
总结:
- Frame是一个顶级窗口
- Panel无法单独显示,必须添加到某个容器中
- 布局管理器
- 流式、东西南北中、表格
- 大小、定位、背景颜色、可见性、监听
4、事件监听
-
事件监听:当某个事情发生的时候,干什么
public class Demo02 { public static void main(String[] args){ Frame frame = new Frame(); frame.setBounds(300,300,500,500); frame.setVisible(true); Button button = new Button("button1"); Button button2 = new Button("btn2"); //同一个JFrame里可能有多个按钮的事件,为了避免冲突,给每个按钮设置不同的ActionCommand button.setActionCommand("bb11"); //因为addActionListener()需要一个ActionListener,所以我们需要构造一个ActionListener //可以多个按钮只写一个监听类 MyActionListener myActionListener = new MyActionListener(); button.addActionListener(myActionListener); button2.addActionListener(myActionListener); frame.add(button,BorderLayout.NORTH); frame.add(button2,BorderLayout.SOUTH); windowClose(frame); } //关闭窗体的事件 private static void windowClose(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(e.getActionCommand()); //点击button:bb11 点击button2:btn2 } }
5、输入框 TextField监听
public class TestText01 {
public static void main(String[] args) {
//启动
new MyFrame();
}
}
class MyFrame extends Frame{
public MyFrame(){
TextField textField = new TextField();
add(textField);
//监听这个文本框输入的文字
MyActionListener myActionListener = new MyActionListener();
//按下enter就会触发这个输入框的事件
textField.addActionListener(myActionListener);
//设置替换编码
textField.setEchoChar('*');
setVisible(true);
pack();
}
}
class MyActionListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
TextField field = (TextField) e.getSource();//获得一些资源,返回一个对象
System.out.println(field.getText());//获得输入框的文本
field.setText("");//回车后清空
}
}
6、练习:简易计算器 (组合+内部类回顾)
-
oop(面向对象)原则:组合 大于继承
//简易计算器 public class TestCalc { public static void main(String[] args) { new Calculator(); } } //计算器类 class Calculator extends Frame{ public Calculator(){ //3个文本框 TextField num1 = new TextField(10); TextField num2 = new TextField(10); TextField num3 = new TextField(20); //一个按钮 Button button = new Button("="); button.addActionListener(new MyCalculatorListener(num1,num2,num3)); //1个标签 Label label = new Label("+"); //布局 setLayout(new FlowLayout()); add(num1); add(label); add(num2); add(button); add(num3); setVisible(true); pack(); } } //监听器类 class MyCalculatorListener implements ActionListener{ //获取三个变量 private TextField num1,num2,num3; public MyCalculatorListener(TextField num1,TextField num2,TextField num3) { this.num1=num1; this.num2=num2; this.num3=num3; } @Override public void actionPerformed(ActionEvent e) { //1.获得加数和被加数 int n1 = Integer.parseInt(num1.getText()); int n2 = Integer.parseInt(num2.getText()); //2.将这个值+法运算后 放到第三个框 num3.setText(""+(n1+n2)); //3.清楚前两个框 num1.setText(""); num2.setText(""); } }

-
完全改造为面向对象写法
//简易计算器 public class TestCalc { public static void main(String[] args) { new Calculator().loadFrame(); } } //计算器类 class Calculator extends Frame{ //属性 TextField num1,num2,num3; //方法 public void loadFrame(){ //3个文本框 num1 = new TextField(10); num2 = new TextField(10); num3 = new TextField(20); //一个按钮 Button button = new Button("="); //1个标签 Label label = new Label("+"); button.addActionListener(new MyCalculatorListener(this)); //布局 setLayout(new FlowLayout()); add(num1); add(label); add(num2); add(button); add(num3); setVisible(true); pack(); } } //监听器类 class MyCalculatorListener implements ActionListener{ //获取计算器这个对象,在一个类中组合另外一个类 Calculator calculator=null; public MyCalculatorListener(Calculator calculator) { this.calculator=calculator; } @Override public void actionPerformed(ActionEvent e) { //1.获得加数和被加数 int n1 = Integer.parseInt(calculator.num1.getText()); int n2 = Integer.parseInt(calculator.num2.getText()); //2.将这个值+法运算后 放到第三个框 calculator.num3.setText(""+(n1+n2)); //3.清楚前两个框 calculator.num1.setText(""); calculator.num2.setText(""); } } -
内部类:更好的包装
-
内部类的最大好处:就是可以畅通无阻的访问外部的属性和方法
//简易计算器 public class TestCalc { public static void main(String[] args) { new Calculator().loadFrame(); } } //计算器类 class Calculator extends Frame{ //属性 TextField num1,num2,num3; //方法 public void loadFrame(){ //3个文本框 num1 = new TextField(10); num2 = new TextField(10); num3 = new TextField(20); //一个按钮 Button button = new Button("="); //1个标签 Label label = new Label("+"); button.addActionListener(new MyCalculatorListener()); //布局 setLayout(new FlowLayout()); add(num1); add(label); add(num2); add(button); add(num3); setVisible(true); pack(); } //内部类 //监听器类 class MyCalculatorListener implements ActionListener{ public void actionPerformed(ActionEvent e) { //1.获得加数和被加数 int n1 = Integer.parseInt(num1.getText()); int n2 = Integer.parseInt(num2.getText()); //2.将这个值+法运算后 放到第三个框 num3.setText(""+(n1+n2)); //3.清楚前两个框 num1.setText(""); num2.setText(""); } } }
7、画笔
-
需要继承JFrame类来画窗口
-
paint()方法定义后自动调用
public class TestPaint { public static void main(String[] args) { new MyPaint().loadFrame(); } } class MyPaint extends Frame{ public void loadFrame(){ setBounds(200,200,600,800); setVisible(true); } //画笔 @Override public void paint(Graphics g) { //画笔颜色 g.setColor(Color.red); g.fillOval(100,100,100,100); //养成习惯,画笔用完还原到最初的颜色 } }
8、鼠标监听
-
鼠标点击在窗口上画点
-
需要鼠标监听事件
//鼠标监听事件 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,500,500); setVisible(true); //存鼠标的点 points=new ArrayList<>(); //鼠标监听器,针对这个窗口的 this.addMouseListener(new MyMouseListener()); } //画笔 @Override public void paint(Graphics g) { //画画,监听鼠标的事件 Iterator iterator = points.iterator(); while (iterator.hasNext()) {//把集合中的的点都画出来 Point point =(Point) iterator.next(); g.setColor(Color.red); g.fillOval(point.x,point.y,10,10); } } //添加一个点到集合中 public void addPaint(Point point){ points.add(point); } //内部类 适配器模式 private class MyMouseListener extends MouseAdapter{ //鼠标 按下 、弹起、 按住不放 @Override public void mousePressed(MouseEvent e) {//鼠标按下触发事件 MyFrame myFrame = (MyFrame)e.getSource(); //鼠标按下,会在界面上画出一个点 myFrame.addPaint(new Point(e.getX(),e.getY())); //每次点击鼠标都需要重新画一遍 myFrame.repaint();//刷新 } } }
9、窗口监听
-
常用窗口监听事件:关闭窗口、激活窗口
public class TestWindow { public static void main(String[] args) { } } class WindowFrame extends Frame{ public WindowFrame(){ super("aaa"); setBackground(Color.pink); setBounds(200,200,500,550); this.addWindowListener( //匿名内部类 new WindowAdapter() { //关闭窗口 @Override public void windowClosing(WindowEvent e) { setVisible(false);//隐藏窗口 System.exit(0); } //激活窗口 @Override public void windowActivated(WindowEvent e) { WindowFrame windowFrame=(WindowFrame) e.getSource(); windowFrame.setTitle("被激活了"); super.windowActivated(e); } } ); } }
10、键盘监听
public class TestKeyListener {
public static void main(String[] args) {
new KeyFrame();
}
}
class KeyFrame extends Frame{
public KeyFrame(){
setBounds(200,200,500,500);
setVisible(true);
this.addKeyListener(new KeyAdapter() {
//键盘按下
@Override
public void keyPressed(KeyEvent e) {
//获得键盘按下的键是哪个
int keyCode = e.getKeyCode();
if (keyCode==KeyEvent.VK_UP){
System.out.println("按上建");
}
super.keyTyped(e);
}
});
}
}
2. Swing
2.1 窗口、面板
-
标签居中
-
没有容器,很多设置不会生效,比如背景颜色
package com.wu.gui编程.JFrame; import javax.swing.*; import java.awt.*; public class JFrameDemo01 { public static void main(String[] args) { new JFrameDemo01().init(); } //init(); 初始化方法 public void init(){ //顶级窗口 JFrame jframe = new JFrame("JFrame窗口"); jframe.setVisible(true); jframe.setBounds(200,200,500,500); //获取一个容器 Container container = jframe.getContentPane(); container.setBackground(Color.pink); //设置文字 JLabel jLabel = new JLabel("JFrame"); //让文本标签居中 设置水平对齐 jLabel.setHorizontalAlignment(SwingConstants.CENTER); jframe.add(jLabel); //关闭事件 jframe.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } }
2.2 弹窗
-
点击按钮弹出一个弹窗JDialog
//主窗口 public class DialogDemo extends JFrame { public DialogDemo(){ this.setVisible(true); this.setBounds(300,300,500,700); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //JFrame 放东西,容器 Container container = this.getContentPane(); //绝对布局 container.setLayout(null); //按钮 JButton jButton = new JButton("点击弹出一个对话框"); jButton.setBounds(30,30,200,50); //点击按钮弹出一个弹窗 jButton.addActionListener(new ActionListener() {//监听器 @Override public void actionPerformed(ActionEvent e) { new MyDialogDemo(); } }); container.add(jButton); } 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(EXIT_ON_CLOSE); //会报错 // defaultCloseOperation must be one of: DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE, or DISPOSE_ON_CLOSE Container container = this.getContentPane(); container.add(new JLabel("弹窗出现!")); } }
2.3 标签
-
Label 用画笔画出图标Icon
//图标,需要实现类,Frame继承 public class IconDemo extends JFrame implements Icon { private int width; private 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 jLabel = new JLabel("icontest", iconDemo, SwingConstants.CENTER); Container container = getContentPane(); container.add(jLabel); this.setVisible(true); this.setBounds(200,200,500,500); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } 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; } }

-
在Label上添加图片Icon
public class ImageIconDemo extends JFrame { public ImageIconDemo(){ JLabel label = new JLabel("ImageIcon"); //获取图片的地址 URL url = ImageIconDemo.class.getResource("xx.png");//获取当前类下面的同级资源 ImageIcon imageIcon = new ImageIcon(url); label.setIcon(imageIcon); label.setHorizontalAlignment(SwingConstants.CENTER); Container container = getContentPane(); container.add(label); setVisible(true); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setBounds(200,200,500,500); } public static void main(String[] args) { new ImageIconDemo(); } }

2.4 面板
-
JPanel
public class JPanelDemo extends JFrame { public JPanelDemo(){ Container container = this.getContentPane(); container.setLayout(new GridLayout(2,1,10,10));//2行一列,后面的参数是间距 JPanel panel1 = new JPanel(new GridLayout(1,3)); JPanel panel2 = new JPanel(new GridLayout(1,2)); panel1.add(new JButton("1")); panel1.add(new JButton("2")); panel1.add(new JButton("3")); panel2.add(new JButton("4")); panel2.add(new JButton("5")); container.add(panel1); container.add(panel2); this.setVisible(true); this.setBounds(200,200,500,500); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JPanelDemo(); } }

-
JScrollPanel
public class JScrollDemo extends JFrame { public JScrollDemo(){ Container container = this.getContentPane(); //文本域 JTextArea textArea = new JTextArea(20, 50); textArea.setText("hello"); //Scroll面板 JScrollPane jScrollPane = new JScrollPane(textArea);//带滚动条的 container.add(jScrollPane); this.setVisible(true); this.setBounds(200,200,500,500); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JScrollDemo(); } }

2.5 按钮
-
图片按钮,把图片变为图标和标签一样
public class JButttonDemo01 extends JFrame { public JButttonDemo01(){ Container container = this.getContentPane(); //将一个图片变为图标 URL resource = JButttonDemo01.class.getResource("蛇.png"); Icon icon = new ImageIcon(resource); //把图标放在按钮上 JButton jButton = new JButton(); jButton.setIcon(icon); jButton.setToolTipText("图片按钮");//鼠标悬浮文字 container.add(jButton); this.setVisible(true); this.setBounds(200,200,600,600); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JButttonDemo01(); } } -
单选按钮
public class JButttonDemo01 extends JFrame { public JButttonDemo01(){ Container container = this.getContentPane(); //单选框 JRadioButton rb1 = new JRadioButton("rb1"); JRadioButton rb2 = new JRadioButton("rb2"); JRadioButton rb3 = new JRadioButton("rb3"); ButtonGroup group = new ButtonGroup(); group.add(rb1); group.add(rb2); group.add(rb3); container.add(rb1,BorderLayout.CENTER); container.add(rb2,BorderLayout.NORTH); container.add(rb3,BorderLayout.SOUTH); this.setVisible(true); this.setBounds(200,200,600,600); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JButttonDemo01(); } } -
复选按钮
public class JButttonDemo extends JFrame { public JButttonDemo01(){ Container container = this.getContentPane(); //多选框 JCheckBox jCheckBox1 = new JCheckBox("cb1"); JCheckBox jCheckBox2 = new JCheckBox("cb2"); container.add(jCheckBox1,BorderLayout.SOUTH); container.add(jCheckBox2,BorderLayout.NORTH); this.setVisible(true); this.setBounds(200,200,600,600); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new JButttonDemo(); } }
2.6 列表
-
下拉框
public class TestComboboxDemo01 extends JFrame { public TestComboboxDemo01(){ Container container = this.getContentPane(); JComboBox status = new JComboBox(); status.addItem("a"); status.addItem("b"); status.addItem("c"); status.addItem("d"); container.add(status); this.setVisible(true); this.setBounds(200,200,600,600); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new TestComboboxDemo01(); } } -
列表框
public class TestComboboxDemo01 extends JFrame { public TestComboboxDemo01(){ Container container = this.getContentPane(); //生成列表的内容 String[] contents={"1","2","3"}; JList list = new JList(contents);//参数也可以用别的列表类型 container.add(list); this.setVisible(true); this.setBounds(200,200,600,600); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } public static void main(String[] args) { new TestComboboxDemo01(); } } -
应用场景
- 选择地区,或者一些单个选项
- 列表:展示信息,一般是动态扩容
2.7 文本框
- 文本框
- 密码框
- 文本域
- 在2.4面板处有

浙公网安备 33010602011771号