GUI的核心技术:Swing AWT
界面不美观,需要jre环境
为什么要学习:
程序设计能力
-
可以写出自己心中的一些小工具
-
工作,可能需要维护到swing界面,概率极小
-
了解MVC架构,了解监听
Java为GUI提供的对象存在java.Awt和Javax.Swing两个包中.Java当中如何完成图形化界面的制作呢?AWT:abstract Window ToolKit.需要调用本地系统实现功能.属于重量级控件.依赖于平台.跨平台性不是特别好.Javax.Swing:在AWT基础上.建立一套图形化系统,提供更多组件,完全由java实现,增强了可移植性,属于轻量级控件.所以以后最好用Swing开发.还有一个SWT外观包.
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件的以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
API除了有应用“应用程序接口”的意思外,还特指 API的说明文档,也称为帮助文档。
2.AWT
2.1、AWT介绍
-
包含了很多类和接口 GUI:图形用户界面
-
元素:窗口,按钮,文本框
-
java.awt
2.2、组件和容器
1、Frame
public class TestFrame1 {
public static void main(String[] args) {
//看源码!
Frame frame = new Frame("我的第一个Frame界面");
//需要设置可见性
frame.setVisible(true);
//设置窗口大小
frame.setSize(500,500);
//设置背景颜色 Color
//new Color()
frame.setBackground(Color.BLACK);
//弹出的初始位置
frame.setLocation(200,200);
//设置大小固定
frame.setResizable(false);
}
}
问题:窗口关闭不掉,停止java程序!
尝试回顾封装:
public class TestFrame2 {
public static void main(String[] args) {
//展示多个窗口new
MyFrame myFrame1 = new MyFrame(100,100,200,200,Color.BLACK);
MyFrame myFrame2 = new MyFrame(300,100,200,200,Color.BLUE);
MyFrame myFrame3 = new MyFrame(100,300,200,200,Color.green);
MyFrame myFrame4 = new MyFrame(300,300,200,200,Color.magenta);
}
}
class MyFrame extends Frame{
static int id = 0;//可能存在多个窗口,我们需要一个计数器
public MyFrame(int x,int y,int w,int h,Color color){
super("MyFrame+"+(++id));
setBackground(color);
setBounds(x,y,w,h);
setVisible(true);
}
}
2、面板Panel
可以看成一个空间,但是不能单独存在
package com.feng.lesson01;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
//Panel 可以看成一个空间,但不能单独存在
public class TestPanel {
public static void main(String[] args) {
Frame frame = new Frame();
Panel panel = new Panel();
//设置布局(如果不设的话,默认置顶)
frame.setLayout(null);
//坐标
//frame.setLocation(200,300);
//frame.setSize(300,300);
frame.setBounds(200,300,300,300);
frame.setBackground(new Color(73, 37, 114));
//panel设置坐标,相对于frame
panel.setBounds(100,100,100,100);
panel.setBackground(new Color(22, 37, 55,44));
//frame.add(panel)
frame.add(panel);
frame.setVisible(true);
//监听事件,监听窗口关闭事件 System.exit(0)
//适配器模式:
frame.addWindowListener(new WindowAdapter() {
//窗口关闭时需要做的事情(1的时候异常退出)
3.布局
-
流式布局:从左到右
package com.feng.lesson01;
import java.awt.*;
public class TestFlowLayout {
public static void main(String[] args) {
Frame frame = new Frame();
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");
//设置为流式布局(默认居中)
//frame.setLayout(new FlowLayout());
frame.setLayout(new FlowLayout(FlowLayout.LEFT));
frame.setSize(400,200);
//把按钮添加上去
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.setVisible(true);
}
}
-
东西南北中
package com.feng.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 north = new Button("North");
Button south = new Button("South");
Button center = new Button("Center");
frame.add(east,BorderLayout.EAST);
frame.add(west,BorderLayout.WEST);
frame.add(north,BorderLayout.NORTH);
frame.add(south,BorderLayout.SOUTH);
frame.add(center,BorderLayout.CENTER);
frame.setSize(200,200);
frame.setVisible(true);
}
}
-
表格布局
package com.feng.lesson01;
import java.awt.*;
public class TestGridLayout {
public static void main(String[] args) {
Frame frame = new Frame();
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");
Button button4 = new Button("button4");
Button button5 = new Button("button5");
Button button6 = new Button("button6");
frame.setLayout(new GridLayout(2,3));
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
frame.add(button6);
frame.pack();//java函数(自动填充)
frame.setVisible(true);
}
}
总结:
Frame是个顶级容器
Panel无法单独显示,必须添加到某个容器中。
布局管理器:流式,东西南北中,表格
大小,定位,背景颜色,可见性,监听
4.事件监听
当某个事情发生的时候,干什么?
package com.feng.lesson01;
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("button");
/* 因为是接口,所以就new一个,这种形式是匿名内部类,我们一般不这么干。正常情况我们写一个类
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
}
});
*/
//因为它需要一个ActionListener类型的对象,所以我们构造一个。(接口就写实现类,父类就继承)
MyActionListener myActionListener = new MyActionListener();
button.addActionListener(myActionListener);
frame.add(button,BorderLayout.CENTER);
frame.pack();
windowClose(frame);
frame.setVisible(true);
}
private static void windowClose(Frame frame){
frame.addWindowListener(new WindowAdapter() {
监听多个按钮
package com.feng.lesson01;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestActiontwo {
public static void main(String[] args) {
Frame frame = new Frame();
Button button1 = new Button("start");
Button button2 = new Button("stop");
frame.add(button1,BorderLayout.SOUTH);
frame.add(button2,BorderLayout.NORTH);
//可以显示的定义触发会返回的命令,如果不显示,则会走默认的值(button的label)
//可以多个按钮只写一个监听类
//button1.setActionCommand("button1-start");
Monitor monitor = new Monitor();
button1.addActionListener(monitor);
button2.addActionListener(monitor);
frame.setVisible(true);
frame.pack();
}
}
class Monitor implements ActionListener{
文本框
package com.feng.lesson01;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestText01 {
public static void main(String[] args) {
//启动!
new MyFrame1();
}
}
class MyFrame1 extends Frame{
public MyFrame1(){
TextField textField = new TextField();
add(textField);
//监听这个文本框输入文字
MyActionListener2 myActionListener2 = new MyActionListener2();
textField.addActionListener(myActionListener2);
textField.setEchoChar('*');
// setLayout(new FlowLayout()); 文本域不写也没事,就是一行
setVisible(true);
//要写,要不然有框,但是不是好的,有时候太小了!
pack();
}
}
class MyActionListener2 implements ActionListener{
oop原则:组合,大于继承!
计算器(目前代码)
package com.feng.lesson01;
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() {
TextField num1 = new TextField(10); //字符数
TextField num2 = new TextField(10);
TextField num3 = new TextField(20);
Button button = new Button("=");
button.addActionListener(new MyActionListener1(num1,num2,num3));
Label label = new Label("+");
setLayout(new FlowLayout());
add(num1);
add(label);
add(num2);
add(button);
add(num3);
pack();
setVisible(true);
}
}
class MyActionListener1 implements ActionListener{
private TextField num1,num2,num3;
public MyActionListener1(TextField num1,TextField num2,TextField num3){
this.num1 = num1;
this.num2 = num2;
this.num3 = num3;
}
java基础知识思想积累,学习感想
在此类中没有的,你又要用它就得new它,等同于new 构造函数(),有时构造函数可以传参-->为之实例,当他new的时候传参的时候就接收到传到执行的方法中初始化了,同时当这个执行的时候,属于你本类的就有了一个这个类型的东西(类的实例),当然,未来为了方便你后面用它去调用它里面的方法去做啥效果、对它本身自己下定义(eg,设大小)或者参数,你最好给它起个名儿(标识),这样直接就用名字指代它了。
方法也是这个思想,打个比方: init方法,里面其实是由像关于本类对象本身设置的方法,like可见的方法,设大小的方法等等,以后每次new本类对象都得执行这一堆方法去初始化这次的对象,那干脆把这一堆固定最初都执行的方法封装为一个方法,到时候直接用new构造的实例对象调用这一个init就方便了,就不用到哪要调用一堆一个个调用了,方便了很多,代码就看起来更抽象简洁。
类也是这个思想,打个比方:
因为要遵循面向对象,从而使代码抽象简洁,所以写东西,执行的操作啥的最后封装到一个类里,到时候在哪用就new对象就有了。
coordinate:左标
oval:椭圆
Generate:生成
3.Swing
extends JFrame ------- JFrame 别少写了J,否则没有this.getContentPane()方法
JFrame 放东西就得想容器this.getContentPane()方法得到一个容器!!
3.1 窗口、面板
package com.feng.lesson01;
import javax.swing.*;
import java.awt.*;
public class JFrameDemo {
public JFrameDemo() {
JFrame jf = new JFrame("123");
jf.setVisible(true);
jf.setBounds(100,100,200,200);
Label label = new Label("456");
jf.add(label);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JFrameDemo();
}
}
3.2 弹窗
package com.feng.lesson01;
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 放东西就得想容器this.getContentPane()方法得到一个容器
Container container = this.getContentPane();
container.setLayout(null); //设了绝对布局,就必须给出组件的x,y!否则不显示组件!
JButton button = new JButton("an-niu");
button.setBounds(30,30,50,35);
button.addActionListener(new ActionListener() {
3.3 标签
label
new JLable("xxx");
icon
package com.feng.lesson01;
import javax.swing.*;
import java.awt.*;
public class IconDemo extends JFrame implements Icon {
private int width;
private int height;
public IconDemo(int width, int height){
this.height = height;
this.width = width;
}
public IconDemo(){}
public void init(){
IconDemo iconDemo = new IconDemo(15, 15);
//图标放在标签,也可以放在按钮上!
JLabel jLabel = new JLabel("icontest",iconDemo,SwingConstants.CENTER);
Container container = getContentPane();
container.add(jLabel);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//如果没有这句,关闭时只是隐藏程序,并没终止。
}
public static void main(String[] args) {
new IconDemo().init();
}
图标ICON
package com.feng.lesson01;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class ImageIconDemo extends JFrame {
public ImageIconDemo(){
//获取图片的地址(获取当前这个类下面同级资源 它会返回一个URL
JLabel label = new JLabel("ImageIcon");
URL url = ImageIconDemo.class.getResource("tx.jpg");
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);
}
public static void main(String[] args) {
new ImageIconDemo();
}
}
//图片显示不出来重启一下idea
//把图片粘贴到out中对应的放那个代码的报下就好了
3.4 面板
JPanel
package com.feng.lesson01;
import javax.swing.*;
import java.awt.*;
public class JPanelDemo extends JFrame {
public JPanelDemo() {
Container container = this.getContentPane();
container.setLayout(new GridLayout(2,1,10,10));
//像JPanel这种面的组件的构造方法可以传布局的格式,所以button不可以,button是可传text
JPanel panel1 = new JPanel(new GridLayout(1,3));
JPanel panel2 = new JPanel(new GridLayout(1,2));
JPanel panel3 = new JPanel(new GridLayout(2,1));
JPanel panel4 = new JPanel(new GridLayout(3,2));
panel1.add(new JButton("1"));
panel1.add(new JButton("1"));
panel1.add(new JButton("1"));
panel2.add(new JButton("2"));
panel2.add(new JButton("2"));
panel3.add(new JButton("3"));
panel3.add(new JButton("3"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
container.add(panel1);
container.add(panel2);
container.add(panel3);
container.add(panel4);
setVisible(true);
this.setSize(100,200);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JPanelDemo();
}
}
JScroll
package com.feng.lesson01;
import javax.swing.*;
import java.awt.*;
public class JScrollDemo extends JFrame {
public JScrollDemo() {
Container container = this.getContentPane();
//文本域
JTextArea textArea = new JTextArea(20, 13);
textArea.setText("今天是2023/3/26");
//Scroll面板
JScrollPane scrollPane = new JScrollPane(textArea); //一定要添加要显示的组件对象,否则不给它添加滚动条
//scrollPane.add(textArea); 添加了就覆盖了滚动条界面。
container.add(scrollPane);
setVisible(true);
this.setBounds(100,100,300,350);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JScrollDemo();
}
}
3.5 按钮
普通button
package com.feng.lesson01;
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("tx.jpg");
ImageIcon icon = new ImageIcon(url);
//把图标放在按钮上
JButton button = new JButton();
button.setIcon(icon);
button.setToolTipText("tupiananniu");
container.add(button);
this.setVisible(true);
this.setSize(500,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JButtonDemo01();
}
}
单选
package com.feng.lesson01;
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("tx.jpg");
ImageIcon icon = new ImageIcon(url);
//单选框
JRadioButton radioButton1 = new JRadioButton("JRadioButton1");
JRadioButton radioButton2 = new JRadioButton("JRadioButton2");
JRadioButton radioButton3 = new JRadioButton("JRadioButton3");
//单选框只能选一个,所以把他们分组
ButtonGroup group = new ButtonGroup();
group.add(radioButton1);
group.add(radioButton2);
group.add(radioButton3);
//在continer中添加组件
container.add(radioButton1,BorderLayout.NORTH);
container.add(radioButton2,BorderLayout.CENTER);
container.add(radioButton3,BorderLayout.SOUTH);
this.setVisible(true);
this.setSize(500,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JButtonDemo02();
}
}
复选框按钮
package com.feng.lesson01;
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class JButtonDemo03 extends JFrame {
public JButtonDemo03() {
Container container = this.getContentPane();
//将一个图片变为图标
URL url = JButtonDemo02.class.getResource("tx.jpg");
ImageIcon icon = new ImageIcon(url);
JCheckBox checkBox01 = new JCheckBox("checkBox01");
JCheckBox checkBox02 = new JCheckBox("checkBox02");
container.add(checkBox01,BorderLayout.NORTH);
container.add(checkBox02 ,BorderLayout.SOUTH);
this.setVisible(true);
this.setSize(500,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JButtonDemo03();
}
}
3.6 列表
下拉框
Combo box:组合框,其实是文本框(TextBox)和列表框(ListBox)的组合。功能是从一个列表中一次只能选取或输入一个选项,其主要特点是具有带向下箭头的方框。
package com.feng.lesson01;
import javafx.scene.control.ComboBox;
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(100,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestComboboxDemo01();
}
}
列表框
package com.feng.lesson01;
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("zhangsan");
contents.add("lisi");
container.add(jList);
this.setVisible(true);
this.setSize(100,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestComboboxDemo02();
}
}
补充:Java中Vector类是允许不同类型元素共存的变长数组,Java.util.Vector提供了向量(Vector)类以实现类似动态数组的功能。
应用场景
下拉框:选择地区(可级联,或者两个以上选项的选择
列表:展示信息,一般是动态扩容
3.7 文本框
文本框
package com.feng.lesson01;
import javax.swing.*;
import java.awt.*;
public class TestTextDemo01 extends JFrame {
public TestTextDemo01() {
Container container = this.getContentPane();
JTextField textField = new JTextField("hello");
JTextField textField2 = new JTextField("world",20);
//记得写上约束,否则显示不全
container.add(textField,BorderLayout.NORTH);
container.add(textField2,BorderLayout.SOUTH);
this.setVisible(true);
this.setSize(100,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestTextDemo01();
}
}
密码框
package com.feng.lesson01;
import javax.swing.*;
import java.awt.*;
public class TestTextDemo02 extends JFrame {
public TestTextDemo02() {
Container container = this.getContentPane();
//尽量不要在container上(默认东西南北中的中,放面板上
JPasswordField passwordField = new JPasswordField();
passwordField.setEchoChar('*');
container.add(passwordField);
this.setVisible(true);
this.setSize(100,300);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestTextDemo02();
}
}
文本域
package com.feng.lesson01;
import javax.swing.*;
import java.awt.*;
public class JScrollDemo extends JFrame {
public JScrollDemo() {
Container container = this.getContentPane();
//文本域
JTextArea textArea = new JTextArea(20, 13);
textArea.setText("今天是2023/3/26");
//Scroll面板
JScrollPane scrollPane = new JScrollPane(textArea); //一定要添加要显示的组件对象,否则不给它添加滚动条
//scrollPane.add(textArea); 添加了就覆盖了滚动条界面。
container.add(scrollPane);
setVisible(true);
this.setBounds(100,100,300,350);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JScrollDemo();
}
}