GUI编程
1~2节:每个组件都是一个类!!!!
1.Frame
import java.awt.*;
//GUI的第一个界面
public class TestFrame {
public static void main(String[] args) {
Frame frame = new Frame("frame标题");
// 设置窗口可见
frame.setVisible(true);
// 设置大小
frame.setSize(400,400);
// 设置背景颜色
frame.setBackground(Color.BLACK);
// 设置初始位置
frame.setLocation(400,400);
// 设置大小固定
frame.setResizable(false);
}
}
问题:关闭按钮无反应,关闭程序进程才会关闭窗口
封装打开多个实现:
import java.awt.*;
public class TestFrame2 {
public static void main(String[] args) {
new MyFrame(100,100,200,200,Color.BLACK);
new MyFrame(300,100,200,200,Color.BLUE);
new MyFrame(100,300,200,200,Color.YELLOW);
new MyFrame(300,300,200,200,Color.WHITE);
}
}
class MyFrame extends Frame{
// 计数器
private static int id = 0;
public MyFrame(int x,int y,int w,int h,Color color){
super("MyFrame+"+id++);//这个是frame类的构造方法,当然,frame有多个构造方法。
this.setBounds(x,y,w,h);
this.setBackground(color);
this.setVisible(true);
}
}
2.Panel(面板)
面板不能单独的存在,他必须放在一个容器里面,比如:frame
Panel(面板)的位置,在设置位置的时候,位置是相对于其父级容器的
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestPanel {
public static void main(String[] args) {
Frame frame = new Frame("带面板的Frame");
Panel panel = new Panel();
frame.setBounds(400,400,500,500);
frame.setBackground(Color.BLACK);
frame.setLayout(null);
panel.setBounds(100,100,300,300);
panel.setBackground(Color.YELLOW);
// 将面板放入frame中
frame.add(panel);
frame.setVisible(true);
// 添加监听
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//强制退出,监听窗口关闭的时候
}
});
}
}
适配器模式,这个不用重写所有的方法,只需要重写选中的方法,其他的程序默认。
不用适配,要重写所有的方法:
3.布局管理器
流式布局 FlowLayout、(绝对布局) 不会自动填充(放大后)
默认的是,居中对齐,但是可以FlowLayout.RIGHT改变对齐的方式
import java.awt.*;
//流式布局
public class TestFlowLayout {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(400,400,500,500);
Button button1 = new Button("按钮1");
Button button2 = new Button("按钮2");
Button button3 = new Button("按钮3");
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
}
}
东西南北中 BorderLayout 会自动填充(放大后)
注意这种布局添加时要指明方向
package GUI0;
import java.awt.*;
class TestBorderLayout {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(400,400,500,500);
frame.setLayout(new BorderLayout());
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);
}
}
表格式布局 GridLayout 会自动填充 (放大后)
frame.pack();
//自动布局窗口的大小,测试过程中发现不能在第一行写这个,需要在添加完毕后增加会分配默认size
new GridLayout(3,2)
//不设置几行几列就会导致先排满第一行在排第二行。
import java.awt.*;
public class TestGridLayout {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
// frame.setBounds(400,400,500,500);
Button button1 = new Button("but1");
Button button2 = new Button("but2");
Button button3 = new Button("but3");
Button button4 = new Button("but4");
Button button5 = new Button("but5");
Button button6 = new Button("but6");
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
frame.add(button6);
frame.setLayout(new GridLayout(3,2));//不设置几行几列就会导致先排满第一行在排第二行。
//自动布局窗口的大小,测试过程中发现不能在第一行写这个,需要在添加完毕后增加会分配默认size
frame.pack();
}
}
盒子布局 BoxLayoutB(等会再写)
注意:frame和penel是有布局的,而按钮,文本域等等这都是没有布局的 。frame是个顶级容器,就是他是所有容器的子类,除了Jframe,
实战:
import java.awt.*;
public class TestDemo1 {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(100,100,800,800);
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");
Button button7 = new Button("button7");
Button button8 = new Button("button8");
Button button9 = new Button("button9");
Button button10 = new Button("button10");
frame.setLayout(null);
Panel panel1 = new Panel(new GridLayout(1,1));
panel1.setBounds(0,0,200,400);
panel1.add(button1);
Panel panel3 = new Panel(new GridLayout(2,1));
panel3.setBounds(200,0,400,400);
panel3.add(button2);
panel3.add(button3);
Panel panel4 = new Panel(new GridLayout(1,1));
panel4.setBounds(600,0,200,400);
panel4.add(button4);
Panel panel2 = new Panel(new GridLayout());
panel2.setBounds(0,400,200,400);
panel2.add(button5);
Panel panel5 = new Panel(new GridLayout(2,2));
panel5.setBounds(200,400,400,400);
panel5.add(button6);
panel5.add(button7);
panel5.add(button8);
panel5.add(button9);
Panel panel6 = new Panel(new GridLayout());
panel6.setBounds(600,400,200,400);
panel6.add(button10);
frame.add(panel1);
frame.add(panel3);
frame.add(panel4);
frame.add(panel2);
frame.add(panel5);
frame.add(panel6);
}
}
4.事件监听
WindowListener ActionListener
1.一个按钮可以添加多个监听
package GUI0;
import homework001.test01.A;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
class TestActionEvent1 {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(100,100,500,500);
// 一个按钮可以同时添加多个监听
Button button = new Button();
//通过匿名内部类实现接口
button.addActionListener(new ActionListener() {//给按钮添加事件监听
@Override//这个实现的时 ActionListener这个接口
public void actionPerformed(ActionEvent e) {
System.out.println("666666");
}
});
//这个是因为,添加监听器的这个方法需要一个 ActionListener的对象,所以我们需要一个创建一个 ActionListener
myActionListener myaction = new myActionListener();//通过实现这个方法实现这个接口
button.addActionListener(myaction)
frame.add(button,BorderLayout.NORTH);
frame.addWindowListener(new WindowAdapter() {//窗口监听,适配器,只需要重写其中的一个方法
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
class myActionListener implements ActionListener {//实现这个接口
public void actionPerformed(ActionEvent e){
System.out.println("9999999");
}
}
在这里输出动作发生后的内容
2.一个监听可以给多个按钮共同使用
package GUI0;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
class TestActionEvent2 {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(100,100,500,500);
// 顶一个一个监听可以多个按钮共同使用,通过if条件判断语句来实现,要那个!
ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("11111111111111")){
System.out.println("第一个按钮");
}
else{
System.out.println("第二个按钮");
}
}//这样就实现了一个监听器实现了对两个不同按钮不同功能的监听
};
Button button1 = new Button("1");//监听器通过e.getActionCommand()获取!
//setActionCommand可以为按钮带参数来控制同一个监听执行不同按钮的方法
button1.setActionCommand("11111111111111");//监听器通过e.getActionCommand()获取!
//e.getActionCommand()在默认状态下是定义按钮时候的string,可以通过setActionCommand()修改
button1.addActionListener(actionListener);
Button button2 = new Button("2");
button2.addActionListener(actionListener);
frame.add(button1,BorderLayout.NORTH);
frame.add(button2,BorderLayout.SOUTH);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
补充
匿名内部类,都是实现接口或者抽象类中必须重写的方法!!!!!!
1.第一种调用的方式
2.第二中情况,
其中A3是个接口,
二者之间的本质是一样的,都是new 接口()的形式产生一个对象的。
5.输入框监听
package GUI0;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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();//获得一些资源,返回的一个对象,返回对象的类型是object
//还有,这个监听谁返回的就是谁!
System.out.println(field.getText());//获得输入框中的文本
field.setText("");//null,回车就清空原来输入的
}
}
settext:修改输入框的文本;
gettext:获得输入框的文本;
细节操作:
后台获得的是*后的实际数字
实战:简易计算机
oop原则:组合,大于基础!
class A extends B{
}//继承
class A{
public B b
} //组合
目前代码
package 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 num1 = new TextField(10);//最多能填10个字符
TextField num2 = new TextField(10);
TextField num3 = new TextField(20);
//1 个按钮
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);
pack();
setVisible(true);
}
}
//监听器期类
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("");
}
}
完全改造为面向对象写法
package 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 num1,num2,num3;
//方法
public void loadFrame(){
num1 = new TextField(10);//字符数
num2 = new TextField(10);//字符数
num3 = new TextField(20);//字符数
//1 个按钮
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);
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.num1.getText());
int n2 = Integer.parseInt(calculator.num2.getText());
calculator.num3.setText(""+(n1+n2));
calculator.num1.setText("");
calculator.num2.setText("");
}
}
内部类:更好的包装
package 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 num1,num2,num3;
//方法
public void loadFrame(){
num1 = new TextField(10);//字符数
num2 = new TextField(10);//字符数
num3 = new TextField(20);//字符数
//1 个按钮
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);
pack();
setVisible(true);
}
//监听器期类
//内部类最大的好处,就是可以畅通无阻的访问外部类的属性和方法
private class MyCalculatorListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
//1.获取加数和被加数
//2.将这个值加法运算后,放到第三个款
//3.清除钱两个框
int n1 = Integer.parseInt(num1.getText());
int n2 = Integer.parseInt(num2.getText());
num3.setText(""+(n1+n2));
num1.setText("");
num2.setText("");
}
}
}