frame(窗口)类的基本知识
public class FirstFrame {
public static void main(String[] args) {
Frame first=new Frame("我的第一个窗口"); //建立一个窗口
first.setVisible(true); //设置窗口的可见性
first.setSize(400,400); //窗口的长和宽都是400
first.setBackground(new Color(11, 76, 141)); //设置窗口的背景颜色
first.setLocation(200,200); //设置窗口弹出来的初始位置
first.setResizable(false); //设置窗口不可拉伸
}
}
(IDEA中按住Ctrl再用鼠标左键点击可以查看类的源码)
panel(面板)
panel建立在窗口中
package TestFrame;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class FirstFrame {
public static void main(String[] args) {
Frame first=new Frame("我的第一个窗口"); //建立一个窗口
first.setVisible(true); //设置窗口的可见性
first.setSize(400,400); //窗口的长和宽都是400
first.setBackground(new Color(11, 76, 141)); //设置窗口的背景颜色
first.setLocation(200,200); //设置窗口弹出来的初始位置
first.setResizable(false); //设置窗口不可拉伸
Panel one=new Panel();
first.setLayout(null); //设置窗口的布局
one.setBounds(50,50,100,100); //设置面板的坐标(相对于窗口来说)和长宽
one.setVisible(true); //设置面板的可见性
one.setBackground(new Color(30,29,78)); //设置面板的背景颜色
first.add(one); //将设置好的面板加到窗口里
first.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
}); //添加一个监听事件,用来关闭窗口
}
}
三种布局
流式布局(FlowLayout)
package TestFrame;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestFlowLayout {
public static void main(String[] args) {
Button button1=new Button("1");
Button button2=new Button("2");
Button button3=new Button("3");
Frame frame=new Frame("贪吃蛇");
frame.setBounds(200,200,500,500);
frame.setBackground(new Color(1,79,3));
frame.setVisible(true);
//frame.setLayout(new FlowLayout(FlowLayout.CENTER));
frame.setLayout(new FlowLayout(FlowLayout.RIGHT));
frame.add(button1); //添加三个按钮到窗口中去
frame.add(button2);
frame.add(button3); //流式布局
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
}
}
东西南北中布局(BorderLayout)
package TestFrame;
import java.awt.*;
public class TestBorderLayout {
public static void main(String[] args) {
Frame frame=new Frame("贪吃蛇");
frame.setBounds(200,200,500,500);
frame.setVisible(true);
Button west=new Button("west");
Button east=new Button("east");
Button north=new Button("north");
Button south=new Button("south");
Button center=new Button("center");
frame.add(west,BorderLayout.WEST);
frame.add(east,BorderLayout.EAST);
frame.add(north,BorderLayout.NORTH);
frame.add(south,BorderLayout.SOUTH);
frame.add(center,BorderLayout.CENTER); //东西南北中布局
}
}
列表布局(GridLayout)
package TestFrame;
import java.awt.*;
public class TestGridLayout {
public static void main(String[] args) {
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");
Button bt6=new Button("bt6");
Button bt7=new Button("bt7");
Frame frame=new Frame("贪吃蛇");
frame.setVisible(true);
frame.setBounds(200,200,500,500);
frame.setLayout(new GridLayout(2,3));
frame.add(bt1);
frame.add(bt2);
frame.add(bt3);
frame.add(bt4);
frame.add(bt5);
frame.add(bt6);
frame.pack();
(任意数字).for 在idea中快捷生成一个for循环,(i=0;i<任意数字;i++)
学习三种布局之后的小作业
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3juo0cmb-1673504855086)(C:\Users\谢博文\AppData\Roaming\Typora\typora-user-images\image-20221227113519360.png)]
建立如图所示的布局
思路:
1.建立一个窗口(frame)
2.将窗口分成上下两部分 设置窗口的布局为GridLayout(列表布局)二行一列
3.上下两部分是两个面板(panel) 两部分的中间也是两个面板
4.上下两部分都是Borderlayout(东西南北中布局) 两部分的中间则是列表布局
package TestFrame;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class PracticeFrame {
public static void main(String[] args) {
Frame f1 = new Frame("贪吃蛇");
f1.setBounds(400,400,1800,1800);
f1.setVisible(true);
f1.setBackground(Color.BLUE);
f1.setLayout(new GridLayout(2,1));
Panel p1 = new Panel();
Panel p2 = new Panel();
Panel p3 = new Panel();
Panel p4 = new Panel();
p1.setLayout(new BorderLayout());
p1.add(new Button("west01"),BorderLayout.WEST);
p1.add(new Button("east01"),BorderLayout.EAST);
p2.setLayout(new GridLayout(2,1));
p2.add(new Button("bt1"));
p2.add(new Button("bt2"));
p1.add(p2,BorderLayout.CENTER);
p3.setLayout(new BorderLayout());
p3.add(new Button("west02"),BorderLayout.WEST);
p3.add(new Button("east02"),BorderLayout.EAST);
p4.setLayout(new GridLayout(2,2));
for (int i = 0; i < 4; i++) {
p4.add(new Button("bt" + (3 + i)));
}
p3.add(p4,BorderLayout.CENTER);
f1.add(p1);
f1.add(p3);
f1.pack();
f1.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
}
}
事件监听
package TestFrame;
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 TestEvent {
public static void main(String[] args) {
Button b1 = new Button("1");
Frame f1 = new Frame("贪吃蛇");
f1.add(b1);
f1.setVisible(true);
f1.pack();
f1.setBounds(200,200,500,500);
WindowClose(f1);
b1.addActionListener(new MyActionListener()); //调用自己写的事件
}
private static void WindowClose(Frame frame) {
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
} //将关闭窗口写成一个方法,之后调用即可
}
class MyActionListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("123");
}
} //自己写一个事件实现接口ActionListener
按钮实现事件,按下按钮实现对应的事件,事件需要自己来写。
多个按钮可以共享一个事件。
文本框(TextField)监听
package TestFrame;
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 MyTest {
public static void main(String[] args) {
MyFrame2 f1 = new MyFrame2(); //启动!
MyFrame2.Stop(f1);
}
}
class MyFrame2 extends Frame{
public MyFrame2(){
TextField t1 = new TextField();
add(t1);
setVisible(true);
t1.addActionListener(new MyActionListener1());
t1.setEchoChar('*'); //编码,将用户输入的密码转换为用*显示
}
public static void Stop(MyFrame2 f1){
f1.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
}
}
class MyActionListener1 implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
TextField textField = (TextField)e.getSource(); //将获取到的资源转化成文本类型
System.out.println(textField.getText());
textField.setText(""); //按下回车后文本框自动清零
}
}
获取文本框中的文本并将其转换成int类型
Integer.parselnt(String s);
此方法将 String 参数解析为带符号的十进制整数对象。 字符串中的字符必须是十进制数字,除了字符串的第一个字符可以是 ASCII 减号 ‘-’ 表示负值或 ASCII 加 ‘+’ 符号表示正值。 它返回由十进制整数中的参数表示的整数值。
int i=Integer.parselnt(String s);
将Integer类型自动转换成int类型
我的第一个计算器
package TestFrame;
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 Calculator {
public static void main(String[] args) {
MyCalculator.Stop(new MyCalculator("计算器"));
}
}
//计算器
class MyCalculator extends Frame {
public MyCalculator(String title) {
super(title);
//1.首先我们需要三个文本框来显示加数、被加数、和 2.然后在加数跟被加数的中间有一个加号(标签) 3.然后需要一个等号按钮,按下按钮计算出和并将加数、被加数清除
//三个文本框
TextField num1 = new TextField();
TextField num2 = new TextField();
TextField num3 = new TextField();
num1.setColumns(10);
num2.setColumns(10);
num3.setColumns(20);
//标签(一个加号)
Label l1 = new Label("+");
//一个按钮(等号)
Button bt1 = new Button("=");
add(num1);
add(l1);
add(num2);
add(bt1);
add(num3);
bt1.addActionListener(new MyCalculatorListener(num1, num2, num3));
setVisible(true);
setLayout(new FlowLayout());
pack();
}
//写一个方法用来关闭窗口
public static void Stop(MyCalculator myCalculator){
myCalculator.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
}
//监听
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) {
//获取加数跟被加数
int n1=Integer.parseInt(num1.getText());
int n2=Integer.parseInt(num2.getText());
//算出和放在第三个文本框,并将加数跟被加数清除
num3.setText(""+(n1+n2));
num1.setText("");
num2.setText("");
}
}
}
将以上代码用组合内部类的思想优化一下
1.类中有属性和方法
2.在一个类中创建另一个类的对象,那么就可以在这个类中使用另一个类的方法和属性
3.能不用继承就尽量不用继承,避免代码的重复性
4.内部类可以畅通无阻地访问外部类的方法和属性
package TestFrame;
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 Calculator {
public static void main(String[] args) {
MyCalculator calculator = new MyCalculator();
calculator.LoadMyCalculator();
calculator.Stop(calculator); //启动!
}
}
//计算器
class MyCalculator extends Frame {
TextField num1,num2,num3;
public void LoadMyCalculator(){
//1.首先我们需要三个文本框来显示加数、被加数、和 2.然后在加数跟被加数的中间有一个加号(标签) 3.然后需要一个等号按钮,按下按钮计算出和并将加数、被加数清除
//三个文本框
num1=new TextField(10);
num2=new TextField(10);
num3=new TextField(20);
//标签(一个加号)
Label l1 = new Label("+");
//一个按钮(等号)
Button bt1 = new Button("=");
add(num1);
add(l1);
add(num2);
add(bt1);
add(num3);
bt1.addActionListener(new MyCalculatorListener(this));
setVisible(true);
setLayout(new FlowLayout());
pack();
}
//写一个方法用来关闭窗口
public void Stop(MyCalculator myCalculator){
myCalculator.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
}
//监听
class MyCalculatorListener implements ActionListener{
MyCalculator calculator=null;
public MyCalculatorListener(MyCalculator calculator){
this.calculator=calculator;
}
@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("");
}
}
}
画笔
package TestFrame;
import java.awt.*;
public class Paint {
public static void main(String[] args) {
new MyPaint().LordFrame();
}
}
class MyPaint extends Frame{
public void LordFrame(){
setVisible(true);
setBounds(200,200,600,600);
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.BLUE);
g.drawOval(100,100,300,300);
g.setColor(Color.GREEN);
g.drawRect(200,200,200,400);
g.setColor(Color.black); //将画笔还原回原来的默认颜色
g.fillOval(300,300,100,100);
}
}
draw是空心,fill是实心
鼠标监听
package TestFrame;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Iterator;
public class TestMouseListener {
public static void main(String[] args) {
new MyFrame1("画图").Stop();
}
}
class MyFrame1 extends Frame {
ArrayList point; //设置一个point数组用来存储点的信息
public MyFrame1(String name){
super(name);
setBounds(200,200,400,400);
setVisible(true);
point=new ArrayList<>(); //给point赋初值
addMouseListener(new MyMouseListener()); //增加鼠标监听事件
}
@Override
public void paint(Graphics g) {
super.paint(g);
Iterator iterator= point.iterator(); //建立一个迭代器
while(iterator.hasNext()){
Point point1=(Point) iterator.next(); //迭代器指向下一个,将迭代器转换为point类型然后赋值给point1
g.setColor(Color.BLUE);
g.fillOval(point1.x, point1.y,10,10); //画一个蓝色的点
}
}
public void addPaint(Point point1){
this.point.add(point1);
}
private class MyMouseListener extends MouseAdapter{
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
MyFrame1 frame1=(MyFrame1)e.getSource(); //获取这个窗口的资源
frame1.addPaint(new Point(e.getX(),e.getY())); //将鼠标点击位置的坐标存到point里面
frame1.repaint();
}
}
public void Stop(){
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
}
}
写一个窗口用来画图,鼠标点击一下就会在窗口上生成一个点。
1.首先建立一个窗口,增加鼠标监听事件(addMouseListener)
2.鼠标监听事件里面获取鼠标点击的信息,将点击位置的坐标保存起来(ArrayList)
3.用画笔在该位置画一个点
窗口监听
package TestFrame;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestWindowListener {
public static void main(String[] args) {
new WindowFrame();
}
}
class WindowFrame extends Frame {
public WindowFrame(){
setBackground(Color.BLUE);
setBounds(200,200,500,500);
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.out.println("你在干嘛");
System.exit(0);
}
@Override
public void windowActivated(WindowEvent e) {
super.windowActivated(e);
WindowFrame windowFrame=(WindowFrame) e.getSource();
windowFrame.setTitle("燕子,没有你我可怎么活啊!");
System.out.println("别这样呜呜呜");
}
});
}
}
匿名内部类,在类的内部直接new一个类并重写他的方法(重要)
键盘监听
package TestFrame;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestKeyListener {
public static void main(String[] args) {
new KeyFrame();
}
}
class KeyFrame extends Frame {
public KeyFrame(){
setVisible(true);
setBounds(100,100,500,500);
setBackground(Color.GREEN);
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
int keycode=e.getKeyCode();
System.out.println(keycode);
if(keycode==KeyEvent.VK_UP){
System.out.println("那里!不要!");
}
}
});
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
}
}
键盘上的按键都有其对应的数字,e.getKeyCode就是获取按键对应的数字。
编程思想
主类中只写启动,其它要做的事情都写在其它的类中。