AWT介绍
- AWT(Abstract Window Toolkit)包括了很多类和接口,用于Java Application的GUI(GraphicsUser Interface 图形用户界面)编程。
- GUI的各种元素(如:窗口,按钮,文本框等)由Java类来实现。
- 使用AWT所涉及的类一般在Java.AWT包及其子包中。
- Container和Component是AWT中的两个核心类。
Frame
import java.awt.*; //学习JAVA的GUI编程编写的第一个图形界面窗口 public class TestFrame { public static void main(String[] args) { //这里只是在内存里面创建了一个窗口对象 还不能真正显示出来然我们看到 Frame frame = new Frame("我的第一个JAVA图形界面窗口"); //设置窗体的背景颜色 frame.setBackground(Color.blue); //设置窗体是否可见 //要想看到在内存里面创建出来的窗口对象 //必须调用setVisble()方法 //并且把参数true传入才能看得见窗体 //如果传入的参数是false //那么窗体也是看不见的 frame.setVisible(true); //设置窗体的初始大小 frame.setSize(400,400); //设置窗体出现时的位置,如果不设置则默认在左上角(0,0)位置显示 frame.setLocation(200,200); // 设置窗体能否被改变大小 // 设置为false后表示不能改变窗体的显示大小 // 这里将窗体显示的大小设置为200X200 // 那么窗体的显示只能是这个大小了,不能再使用鼠标拖大或者缩小 frame.setResizable(false); } }
import java.awt.*; public class TestMultiFrame { public static void main(String[] args) { MyFrame f1 = new MyFrame(100,100,200,200,Color.blue); MyFrame f2 = new MyFrame(300,100,200,200,Color.yellow); MyFrame f3 = new MyFrame(100,300,200,200,Color.red); MyFrame f4 = new MyFrame(300,300,200,200,Color.MAGENTA); } }//自定义一个类MyFrame,并且从Frame类继承 //这样MyFrame类就拥有了Frame类的一切属性和方法 //并且MyFrame类还可以自定义属性和方法 //因此使用从Frame类继承而来的自定义类来创建图形窗口比直接使用Frame类来创建图形窗口要灵活 //所以一般使用从Frame类继承而来的自定义类创建图形窗口界面比较好, //不推荐直接使用Frame类来创建图形窗口界面 class MyFrame extends Frame{ //定义一个静态成员变量id,用来记录创建出来的窗口的数目 static int id = 0; //自定义构成方法,在构造方法体内使用super调用父类Frame的构造方法 public MyFrame(int x,int y,int w,int h,Color color){ super("MyFrame"+(++id)); /*使用从父类Frame继承而来的方法设置窗体的相关属性*/setBackground(color); setLayout(null); setBounds(x,y,w,h); setVisible(true); } }
Panel
import java.awt.*; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; public class TestPanel { public static void main(String[] args) { Frame frame = new Frame("JAVA Frame With Panel"); Panel panel = new Panel(null); frame.setLayout(null); //这里设置的坐标(300,300)是相对于整个屏幕的 frame.setBounds(300,300,500,500); //设置背景颜色时使用三基色(红,绿,蓝)的比例来调配背景色 frame.setBackground(new Color(0,0,102)); //这里设置的坐标(50,50)是相对于Frame窗体的 panel.setBounds(50,50,400,400); panel.setBackground(new Color(204,204,255)); //把Panel容器装入到Frame容器中,使其能在Frame窗口中显示出来 frame.add(panel); frame.setVisible(true); //解决关闭问题 frame.addWindowListener(new WindowListener() { @Override public void windowOpened(WindowEvent e) { }@Override public void windowClosing(WindowEvent e) { System.exit(0); }@Override public void windowClosed(WindowEvent e) { }@Override public void windowIconified(WindowEvent e) { }@Override public void windowDeiconified(WindowEvent e) { }@Override public void windowActivated(WindowEvent e) { } @Override public void windowDeactivated(WindowEvent e) { } }); } }
第一种布局管理器——FlowLayout
import java.awt.*; public class TestFlowLayout { public static void main(String[] args) { Frame frame = new Frame("FlowLayout"); //使用Button类创建按钮 // 按钮类的其中一个构造方法:Button(String label) label为按钮显示的文本 Button button1 = new Button("button1"); Button button2 = new Button("button2"); Button button3 = new Button("button3"); // setLayout方法的定义:public void setLayout(LayoutManager mgr) // 使用流水(Flow)线般的布局 frame.setLayout(new FlowLayout()); // 使用了布局管理器FlowLayout,这里的布局采用默认的水平居中模式 // frame.setLayout(new FlowLayout(FlowLayout.LEFT)); // 这里在布局的时候使用了FlowLayout.LEFT常量,这样就将按钮设置为左对齐 // frame.setLayout(new FlowLayout(FlowLayout.RIGHT)); //这里在布局的时候使用了FlowLayout.RIGHT常量,这样就将按钮设置为右对齐 frame.setSize(200,200); frame.add(button1); // 把创建出来的按钮放置到Frame窗体中 frame.add(button2); // 这里并没有设置按钮的大小与位置 frame.add(button3); // 设置按钮的大小与位置都是由布局管理器来做的 frame.setVisible(true); } }
第二种布局管理器——BorderLayout
import java.awt.*; public class TestBorderLayout { public static void main(String[] args) { Frame frame = new Frame("TestBorderLayout"); Button buttonEast = new Button("East"); Button buttonWest = new Button("West"); Button buttonSouth = new Button("South"); Button buttonNorth = new Button("North"); Button buttonCenter = new Button("Center"); //把按钮放置到Frame窗体时按照东西南北中五个方向排列好,推荐使用这种方式去排列窗体 元素 //这样容易检查出错误 因为这样写如果写错了编译器会提示出错 frame.add(buttonEast,BorderLayout.EAST); frame.add(buttonWest,BorderLayout.WEST); frame.add(buttonSouth,BorderLayout.SOUTH); frame.add(buttonNorth,BorderLayout.NORTH); frame.add(buttonCenter,BorderLayout.CENTER); //也可以使用这样的方式排列按钮 在把按钮放置到Frame窗体时使用方向定位的字符串指定 按钮的放置位置 //这种使用方向定位的字符串指定按钮的放置方式不推荐使用 一旦写错了方向字符串就不好 检查出来 //因为即使是写错了仍然可以编译通过 /*frame.add(buttonEast,"EAST"); frame.add(buttonWest,"West"); frame.add(buttonSouth,"South"); frame.add(buttonNorth,"North"); frame.add(buttonCenter,"Center"); */frame.setSize(200,200); frame.setVisible(true); } }
第三种布局管理器——GridLayout(表格布局管理器)
import java.awt.*; public class TestGridLayout { public static void main(String[] args) { Frame frame = new Frame("TestGridLayout"); Button btn1 = new Button("btn1"); Button btn2 = new Button("btn2"); Button btn3 = new Button("btn3"); Button btn4 = new Button("btn4"); Button btn5 = new Button("btn5"); Button btn6 = new Button("bnt6"); // 把布局划分成3行2列的表格布局形式 frame.setLayout(new GridLayout(3,2)); frame.add(btn1); frame.add(btn2); frame.add(btn3); frame.add(btn4); frame.add(btn5); frame.add(btn6); // Frame.pack()是JAVA语言的一个函数 // 这个函数的作用就是根据窗口里面的布局及组件的preferredSize来确定frame的最佳 大小。 frame.pack(); frame.setVisible(true); } }
布局练习
import java.awt.*; public class TestTenButtons { public static void main(String[] args) { //这里主要是对显示窗体进行设置 Frame frame = new Frame("布局管理器的嵌套使用"); //把整个窗体分成2行1列的表格布局 frame.setLayout(new GridLayout(2,1)); frame.setLocation(300,400); frame.setSize(400,300); frame.setVisible(true); frame.setBackground(new Color(204,204,255)); //这里主要是对Panel进行布局的设置 Panel p1 = new Panel(new BorderLayout()); //p2使用2行1列的表格布局 Panel p2 = new Panel(new GridLayout(2,1)); Panel p3 = new Panel(new BorderLayout()); //p4使用2行2列的表格布局 Panel p4 = new Panel(new GridLayout(2,2)); //这里主要是把按钮元素加入到Panel里面 p1.add(new Button("East(p1-东)"),BorderLayout.EAST); p1.add(new Button("West(p1-西)"),BorderLayout.WEST); p2.add(new Button("p2-Button1")); p2.add(new Button("p2-Button2")); //p1里面嵌套p2,把p2里面的按钮作为p的中间部分装入到p1里面 //把p2作为元素加入到p1里面 p1.add(p2,BorderLayout.CENTER); p3.add(new Button("East(p3-东)"),BorderLayout.EAST); p3.add(new Button("West(p3-西)"),BorderLayout.WEST); for(int i=0;i<4;i++){ p4.add(new Button("p4-Button"+i)); }//p3里面嵌套p4,把p4里面的按钮作为p的中间部分装入到p3里面 p3.add(p4,BorderLayout.CENTER); //把Panel装入Frame里面,以便于在Frame窗体中显示出来 frame.add(p1); frame.add(p3); } }
事件监听
import java.awt.*; import java.awt.event.*; public class TestActionEvent { public static void main(String[] args) { Frame frame = new Frame("TestActionEvent"); Button button = new Button("Press Me"); // 创建一个监听对象 MyActionListener listener = new MyActionListener(); // 把监听加入到按钮里面,监听按钮的动作, // 当按钮触发打击事件时,就会返回一个监听对象e // 然后就会自动执行actionPerformed方法 button.addActionListener(listener); frame.add(button, BorderLayout.CENTER); frame.pack(); addWindowClosingEvent(frame); frame.setVisible(true); }//点击窗体上的关闭按钮关闭窗体 private static void addWindowClosingEvent(Frame frame){ frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); } }// 自定义Monitor(监听)类实现事件监听接口ActionListener // 一个类要想成为监听类,那么必须实现ActionListener接口 class MyActionListener implements ActionListener{ //重写ActionListener接口里面的actionPerformed(ActionEvent e)方法 @Override public void actionPerformed(ActionEvent e) { System.out.println("A Button has been Pressed"); } }
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class TestActionEvent2 { public static void main(String[] args) { Frame frame = new Frame("TestActionEvent"); Button btn1 = new Button("start"); Button btn2 = new Button("stop"); //创建监听对象 MyMonitor monitor = new MyMonitor(); //一个监听对象同时监听两个按钮的动作 btn1.addActionListener(monitor); btn2.addActionListener(monitor); //设置btn2的执行单击命令后的返回信息 btn2.setActionCommand("GameOver"); frame.add(btn1,BorderLayout.NORTH); frame.add(btn2,BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } }class MyMonitor implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { //使用返回的监听对象e调用getActionCommand()方法获取两个按钮执行单击命令后的返 回信息 //根据返回信息的不同区分开当前操作的是哪一个按钮,btn1没有使用 setActionCommand()方法设置 //则btn1返回的信息就是按钮上显示的文本 System.out.println("a button has been pressed,"+"the relative info is:\n" +e.getActionCommand());
} }
TextField事件监听
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class TestTextField { public static void main(String[] args) { new MyFrameTextField(); } }class MyFrameTextField extends Frame{ MyFrameTextField(){ TextField textField = new TextField(); add(textField); textField.addActionListener(new MyMonitor2()); //这个setEchoChar()方法是设置文本框输入时显示的字符,这里设置为*, //这样输入任何内容就都以*显示出来,不过打印出来时依然可以看到输入的内容 textField.setEchoChar('*'); setVisible(true); pack(); } }class MyMonitor2 implements ActionListener{ //接口里面的所有方法都是public(公共的) //所以从API文档复制void actionPerformed(ActionEvent e)时 要在void前面加上 public@Override public void actionPerformed(ActionEvent e) { //事件的相关信息都封装在了对象e里面,通过对象e的相关方法就可以获取事件的相关信息 //getSource()方法是拿到事件源,注意:拿到这个事件源的时候 //是把它当作TextField的父类来对待 //getSource()方法的定义是:“public Object getSource()”返回值是一个Object 对象 //所以要强制转换成TextField类型的对象 //在一个类里面想访问另外一个类的事件源对象可以通过getSource()方法 TextField textField = (TextField) e.getSource(); // textField.getText()是取得文本框里面的内容 System.out.println(textField.getText()); // 把文本框里面的内容清空 textField.setText(""); } }
【使用TextField类实现简单的计算器】
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class TestMath { public static void main(String[] args) { new Calculator(); } }//这里主要是完成计算器元素的布局 class Calculator extends Frame{ Calculator(){ //创建3个文本框,并指定其初始大小分别为10个字符和15个字符的大小 这里使用的是 TextField类的另外一种构造方法 public TextField(int columns) TextField num1 = new TextField(10); TextField num2 = new TextField(10); TextField num3 = new TextField(15); //创建等号按钮 Button btnEqual = new Button("="); //给等号按钮加上监听,让点击按钮后有响应事件发生 btnEqual.addActionListener( new MyMonitor(num1, num2, num3) );//“+”是一个静态文本,所以使用Label类创建一个静态文本对象 Label lblPlus = new Label("+"); //把Frame默认的BorderLayout布局改成FlowLayout布局 setLayout(new FlowLayout()); add(num1); add(lblPlus); add(num2); add(btnEqual); add(num3); pack(); setVisible(true); } }class MyMonitor implements ActionListener{ //为了使对按钮的监听能够对文本框也起作用 //所以在自定义类MyMonitor里面定义三个TextField类型的对象 num1,num2,num3, //并且定义了MyMonitor类的一个构造方法 这个构造方法带有三个TextField类型的参数, //用于接收 从TFFrame类里面传递过来的三个TextField类型的参数 //然后把接收到的三个TextField类型的参数赋值给在本类中声明的 三个TextField类型的参数 num1,num2,num3 //然后再在actionPerformed()方法里面处理num1,num2,num3 TextField num1, num2, num3; public MyMonitor(TextField num1, TextField num2, TextField num3) { this.num1 = num1; this.num2 = num2; this.num3 = num3; }//事件的相关信息都封装在了对象e里面,通过对象e的相关方法就可以获取事件的相关信息 @Override public void actionPerformed(ActionEvent e) { // num对象调用getText()方法取得自己显示的文本字符串 int n1 = Integer.parseInt(num1.getText()); int n2 = Integer.parseInt(num2.getText()); //num3对象调用setText()方法设置自己的显示文本 //字符串与任意类型的数据使用“+”连接时得到的一定是字符串, //这里使用一个空字符串与int类型的数连接,这样就可以直接把(n1+n2)得到的int类型的 数隐式地转换成字符串了, //这是一种把别的基础数据类型转换成字符串的一个小技巧。 //也可以使用“String.valueOf((n1+n2))”把(n1+n2)的和转换成字符串 num3.setText("" + (n1 + n2)); //num3.setText(String.valueOf((n1+n2))); //计算结束后清空num1,num2文本框里面的内容 num1.setText(""); num2.setText(""); } }
【JAVA里面的经典用法:在一个类里面持有另外一个类的引用】
import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class TestMath1 { public static void main(String[] args) { new Calculator2().launchFrame(); } }//做好计算器的窗体界面 class Calculator2 extends Frame { //把设计计算器窗体的代码封装成一个方法 TextField num1, num2, num3; public void launchFrame() { num1 = new TextField(10); num2 = new TextField(10); num3 = new TextField(15); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); btnEqual.addActionListener(new MyMonitorbtnEqual(this)); setLayout(new FlowLayout()); add(num1); add(lblPlus); add(num2); add(btnEqual); add(num3); pack(); setVisible(true); } }//这里通过取得Calculator2类的引用,然后使用这个引用去访问Calculator2类里面的成员变量 //这种做法比上一种直接去访问Calculator2类里面的成员变量要好得多 //因为现在不需要知道 Calculator2类里面有哪些成员变量了, //现在要访问Calculator2类里面的成员变量,直接使用 Calculator2类对象的引用去访问即可 //这个Calculator2类的对象好比是一个大管家, 而我告诉大管家,我要访问Calculator2类里面的 那些成员变量, //大管家的引用就会去帮我找,不再需要我自己去找了。 //这种在一个类里面持有另一个类的引用的用法是一种非常典型的用法 //使用获取到的引用就可以在一个类里面访问另一个类的所有成员了 class MyMonitorbtnEqual implements ActionListener { Calculator2 calculator2 = null; public MyMonitorbtnEqual(Calculator2 calculator2) { this.calculator2 = calculator2; }@Override public void actionPerformed(ActionEvent e) { int n1 = Integer.parseInt(calculator2.num1.getText()); int n2 = Integer.parseInt(calculator2.num2.getText()); calculator2.num3.setText("" + (n1 + n2)); calculator2.num1.setText(""); calculator2.num2.setText(""); } }
内部类
好处:
可以方便的访问包装类的成员
可以更清楚的组织逻辑,防止不应该被其他类 访问的类 进行访问
何时使用:
该类不允许或不需要其它类进行访问时
import java.awt.*; import java.awt.event.*; public class TestMath3 { public static void main(String args[]) { new MyMathFrame().launchFrame(); } }class MyMathFrame extends Frame { TextField num1, num2, num3; public void launchFrame() { num1 = new TextField(10); num2 = new TextField(15); num3 = new TextField(15); Label lblPlus = new Label("+"); Button btnEqual = new Button("="); btnEqual.addActionListener(new MyMonitor()); setLayout(new FlowLayout()); add(num1); add(lblPlus); add(num2); add(btnEqual); add(num3); pack(); setVisible(true); }/** 这个MyMonitor类是内部类,它在MyFrame类里面定义 MyFrame类称为MyMonitor类的包 装类 */ /** 使用内部类的好处: * 第一个巨大的好处就是可以畅通无阻地访问外部类(即内部类的包装类)的所有成员变量和方法 * 如这里的在MyFrame类(外部类)定义的三个成员变量num1,num2,num3, * 在MyMonitor(内部类)里面就可以直接访问 * 这相当于在创建外部类对象时内部类对象默认就拥有了一个外部类对象的引用 */ private class MyMonitor implements ActionListener { 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(""); } } }
内部类带来的巨大好处是:
可以很方便地访问外部类定义的成员变量和方法
当某一个类不需要其他类访问的时候就把这个类声明为内部类。
Graphics 类
每个Component都有一个paint(Graphics g)用于实现绘图目的,每次重画该Component时都自动调用paint方法
import java.awt.*; public class TestPaint { public static void main(String[] args) { new MyPaint().launchFrame(); //在main()方法里面并没有显示调用paint(Graphics g)方法 //可是当创建出Frame窗体后却可以看到Frame窗体上画出了圆和矩形 //这是因为paint()方法是一个比较特殊的方法 //在创建Frame窗体时会自动隐式调用 //当我们把Frame窗体最小化又再次打开时 //又会再次调用paint()方法重新把圆和矩形在Frame窗体上画出来 //即每次需要重画Frame窗体的时候就会自动调用paint()方法 } }class MyPaint extends Frame{ public void launchFrame(){ setBounds(200,200,640,480); setVisible(true); }public void paint(Graphics g){ //paint(Graphics g)方法有一个Graphics类型的参数g //我们可以把这个g当作是一个画家,这个画家手里拿着一只画笔 //我们通过设置画笔的颜色与形状来画出我们想要的各种各样的图像 /*设置画笔的颜色*/ g.setColor(Color.red); g.fillOval(100,100,100,100);/*画一个实心椭圆*/ g.setColor(Color.green); g.fillRect(150,200,200,200);/*画一个实心矩形*/ //这下面的两行代码是为了写程序的良好编程习惯而写的 //前面设置了画笔的颜色,现在就应该把画笔的初始颜色恢复过来 //就相当于是画家用完画笔之后把画笔上的颜色清理掉一样 Color c = g.getColor(); g.setColor(c); System.out.println("gogoogo"); } }
鼠标事件适配器
-
抽象类java.awt.event.MouseAdapter实现了MouseListener接口,可以使用其子类作为MouseEvent的监听器,只要重写其相应的方法即可。
-
对于其他的监听器,也有对应的适配器。
-
适用适配器可以避免监听器定义没有必要的空方法。
import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Iterator; public class TestMouseAdapter { public static void main(String[] args) { new MyFrame("drawing...."); } }class MyFrame extends Frame{ ArrayList points = null; MyFrame(String s){ super(s); points = new ArrayList(); setLayout(null); setBounds(200,200,400,300); this.setBackground(new Color(204,204,255)); setVisible(true); this.addMouseListener(new Monitor()); }public void paint(Graphics g){ Iterator i = points.iterator(); while (i.hasNext()){ Point p = (Point)i.next(); g.setColor(Color.BLUE); g.fillOval(p.x,p.y,10,10); } }public void addPoint(Point p){ points.add(p); }private class Monitor extends MouseAdapter{ @Override public void mousePressed(MouseEvent e) { MyFrame frame = (MyFrame) e.getSource(); frame.addPoint(new Point(e.getX(),e.getY())); frame.repaint(); } } }
window事件
import java.awt.*; import java.awt.event.*; public class TestWindowClose{ public static void main(String args[]){ new WindowFrame("关闭WindowFrame"); } }class WindowFrame extends Frame{ public WindowFrame(String s){ super(s); setBounds(200,200,400,300); setLayout(null); setBackground(new Color(204,204,255)); setVisible(true); this.addWindowListener(new WindowMonitor()); /*监听本窗体的动作,把所有的动作信息封装成一个对象传递到监听类里面*/ this.addWindowListener( /*在一个方法里面定义一个类,这个类称为局部类,也叫匿名的内部类, 这里的{……代码……}里面的代码很像一个类的类体,只不过这个类没有名字,所以叫匿名类 在这里是把这个匿名类当成WindowAdapter类来使用,语法上这样写的本质意义是相当于这 个匿名类 从WindowAdapter类继承,现在new了一个匿名类的对象出来然后把这个对象当成 WindowAdapter来使用 这个匿名类出了()就没有人认识了*/ new WindowAdapter(){ public void windowClosing(WindowEvent e){ setVisible(false); System.exit(-1); } } ); }/*这里也是将监听类定义为内部类*/ class WindowMonitor extends WindowAdapter{ /*WindowAdapter(Window适配器)类实现了WindowListener监听接口 重写了WindowListener接口里面的所有方法 如果直接使用自定义WindowMonitor类直接去 实现WindowListener接口,那么就得要重写WindowListener接口 里面的所有方法,但现在只需要用到这些方法里面的其中一个方法 所以采用继承实现WindowListener监听接口的一个子类 并重写这个子类里面需要用到的那个方法即可 这种做法比直接实现WindowListener监听接口要重写很多个用不到的方法要简洁方便得多 */ /*重写需要用到的windowClosing(WindowEvent e)方法*/ public void windowClosing(WindowEvent e){ setVisible(false);/*将窗体设置为不显示,即可实现窗体关闭*/ System.exit(0);/*正常退出*/ } } }
键盘响应事件
import java.awt.*; import java.awt.event.*; public class TestKeyEvent{ public static void main(String args[]){ new KeyFrame("键盘响应事件"); } }class KeyFrame extends Frame{ public KeyFrame(String s){ super(s); setBounds(200,200,400,300); setLayout(null); setVisible(true); addKeyListener(new KeyMonitor()); }/*把自定义的键盘的监听类定义为内部类 这个监听类从键盘适配器KeyAdapter类继承 从KeyAdapter类继承也是为了可以简洁方便 只需要重写需要用到的方法即可,这种做法比 直接实现KeyListener接口要简单方便,如果 直接实现KeyListener接口就要把KeyListener 接口里面的所有方法重写一遍,但真正用到的 只有一个方法,这样重写其他的方法但又用不到 难免会做无用功*/ class KeyMonitor extends KeyAdapter{ public void keyPressed(KeyEvent e){ int keycode = e.getKeyCode(); /*使用getKeyCode()方法获取按键的虚拟码*/ /*如果获取到的键的虚拟码等于up键的虚拟码 则表示当前按下的键是up键 KeyEvent.VK_UP表示取得up键的虚拟码 键盘中的每一个键都对应有一个虚拟码这些虚拟码在KeyEvent类里面都被定义为静态常量 所以可以使用“类名.静态常量名”的形式访问得到这些静态常量*/ if(keycode == KeyEvent.VK_UP){ System.out.println("你按的是up键"); } } } }/*键盘的处理事件是这样的:每一个键都对应着一个虚拟的码, 当按下某一个键时,系统就会去找这个键对应的虚拟的码,以此来确定当前按下的是那个键 */
Swing JFrame框架窗体
JFrame窗体是一个容器,在Swing开发中我们经常要用到,它是Swing程序中各个组件的载体。语法格
式如下
JFrame jf = new JFrame(title);
import javax.swing.JFrame; import javax.swing.WindowConstants; public class JFrameDemo { public void CreateJFrame() { // 实例化一个JFrame对象 JFrame jf = new JFrame("这是一个JFrame窗体"); // 设置窗体可视 jf.setVisible(true); // 设置窗体大小 jf.setSize(500, 350); // 设置窗体关闭方式 jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new JFrameDemo().CreateJFrame(); // 调用CreateJFrame()方法 } }
常用的窗体关闭方式有四种:
“DO_NOTHING_ON_CLOSE” :什么也不做就将窗体关闭;
“DISPOSE_ON_CLOSE” :任何注册监听程序对象后会自动隐藏并释放窗体;
“HIDE_ON_CLOSE” : 隐藏窗口的默认窗口关闭;
“EXIT_ON_CLOSE”:退出应用程序默认窗口关闭。
import java.awt.Color; import java.awt.Container; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingConstants; import javax.swing.WindowConstants; public class JFrameDemo2 extends JFrame{ public void init() { // 可视化 this.setVisible(true); // 大小 this.setSize(500, 350); // 标题 this.setTitle("西部开源"); // 关闭方式 this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 创建一个JLabel标签 JLabel jl = new JLabel("欢迎来到西部开源学习,我是你们的Java老师,秦疆!"); // 使标签文字居中 jl.setHorizontalAlignment(SwingConstants.CENTER); // 获取一个容器 Container container = this.getContentPane(); // 将标签添加至容器 container.add(jl); // 设置容器背景颜色 container.setBackground(Color.YELLOW); }public static void main(String[] args) { new JFrameDemo2().init(); } }
JDialog窗体
JDialog窗体是Swing组件中的对话框,继承了AWT组件中的java.awt.Dialog类。功能是从一个窗体中弹出另一个窗体。
import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.WindowConstants; // 继承JDialog类 public class JDialogDemo extends JDialog { // 实例化一个JDialog类对象,指定其父窗体、窗口标题和类型 public JDialogDemo() { super(new MyJFrame(), "这是一个JDialog窗体", true); Container container = this.getContentPane(); container.add(new JLabel("秦老师带你学Java")); this.setSize(500, 350); }public static void main(String[] args) { new JDialogDemo(); } }// 下面这部分内容包含监听器,可自行查阅资料 class MyJFrame extends JFrame { public MyJFrame() { this.setVisible(true); this.setSize(700, 500); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); Container container = this.getContentPane(); container.setLayout(null); JButton jb = new JButton("点击弹出对话框"); // 创建按钮 jb.setBounds(30, 30, 200, 50); // 按钮位置及大小 jb.addActionListener(new ActionListener() { // 监听器,用于监听 点击事件 @Override public void actionPerformed(ActionEvent e) { new JDialogDemo().setVisible(true); } }); container.add(jb); } }
标签
标签由JLabel类定义,可以显示一行只读文本、一个图像或带图像的文本。
JLabel jl = new JLabel();
图标
Swing中的图标可以放置在按钮、标签等组件上,用于描述组件的用途。图标可以用Java支持的图片文件类型进行创建,也可以使用java.awt.Graphics类提供的功能方法来创建。
在Swing中通过Icon接口来创建图标,可以在创建时给定图标的大小、颜色等特性。
注意,Icon是接口,在使用Icon接口的时候,必须实现Icon接口的三个方法:
public int getIconHeight() public int getIconWidth() public void paintIcon(Component arg0, Graphics arg1, int arg2, int arg3)
import java.awt.Component; import java.awt.Container; import java.awt.Graphics; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingConstants; import javax.swing.WindowConstants; 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; }@Override public int getIconHeight() { // 实现getIconHeight()方法 return this.height; }@Override public int getIconWidth() { // 实现getIconWidth()方法 return this.width; }@Override public void paintIcon(Component arg0, Graphics arg1, int arg2, int arg3) { // 实现paintIcon()方法 arg1.fillOval(arg2, arg3, width, height); // 绘制一个圆形 }public void init() { // 定义一个方法用于实现界面 IconDemo iconDemo = new IconDemo(15, 15); // 定义图标的长和宽 JLabel jb = new JLabel("icon测试", iconDemo, SwingConstants.CENTER); // 设置标签上的文字在标签正中间 Container container = getContentPane(); container.add(jb); this.setVisible(true); this.setSize(500, 350); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new IconDemo().init(); } }
图片图标
Swing中的图标除了可以绘制之外,还可以使用某个特定的图片创建。利用javax.swing.ImageIcon类根据现有图片创建图标。
import java.awt.Container; import java.net.URL; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.SwingConstants; import javax.swing.WindowConstants; public class ImageIconDemo extends JFrame { public ImageIconDemo() { JLabel jl = new JLabel("这是一个JFrame窗体,旁边是一个图片"); URL url = ImageIconDemo.class.getResource("tx-old.jpg"); // 获得图片所在URL Icon icon = new ImageIcon(url); // 实例化Icon对象 jl.setIcon(icon); // 为标签设置图片 jl.setHorizontalAlignment(SwingConstants.CENTER); jl.setOpaque(true); // 设置标签为不透明状态 Container container = getContentPane(); container.add(jl); setVisible(true); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setSize(500, 350); }public static void main(String[] args) { new ImageIconDemo(); } }
对于图片标签,我们经常将图片放置在标签上,用JLabel中的setIcon()方法即可,当然也可以在初始化JLabel对象时为标签指定图标,这需要获取一个Icon实例。
而getResource()方法可以获得资源文件的URL路径,这里的路径是相对于前面的那个类的,所以可将该图片与该类放在同一个文件夹下;如果不在同一个文件夹下,需通过其它方法获取路径。
绝对布局
Container container = getContentPane(); // 创建容器 JButton jb = new JButton("按钮"); // 创建按钮 jb.setBounds(10, 30, 100, 30); // 设置按钮位置和大小 container.add(jb); // 将按钮添加到容器中
流布局管理器
import java.awt.Container; import java.awt.FlowLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.WindowConstants; public class FlowLayoutDemo extends JFrame { public FlowLayoutDemo() { Container container = this.getContentPane(); // 设置流布局管理器,2是右对齐,后两个参数分别为组件间的水平间隔和垂直间隔 this.setLayout(new FlowLayout(2, 10, 10)); // 循环添加按钮 for(int i=0; i<10; i++) { container.add(new JButton("按钮" + i)); }this.setSize(300, 200); this.setVisible(true); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new FlowLayoutDemo(); } }
边界布局管理器
import java.awt.BorderLayout; import java.awt.Container; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.WindowConstants; public class BorderLayoutDemo extends JFrame { private String[] border = {BorderLayout.CENTER, BorderLayout.NORTH, BorderLayout.SOUTH, BorderLayout.WEST, BorderLayout.EAST}; // 此数 组用于存放组件摆放位置 private String[] button = {"中", "北", "南", "西", "东"}; // 此数组用于存 放按钮名称 public BorderLayoutDemo() { Container container = this.getContentPane(); this.setLayout(new BorderLayout()); // 设置容器为边界布局管理器 // 循环添加按钮 for(int i=0; i<button.length ; i++) { container.add(border[i], new JButton(button[i])); // 左参数为设 置布局,右参数为创建按钮 }this.setVisible(true); this.setSize(300, 200); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new BorderLayoutDemo(); } }
网格布局管理器
import java.awt.Container; import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.WindowConstants; class GirdLayoutDemo extends JFrame { public GirdLayoutDemo() { Container container = this.getContentPane(); this.setLayout(new GridLayout(7, 3, 5, 5)); // 前两个参数为7行3列, 后两个参数为网格间的间距 for(int i=0; i<20; i++) { container.add(new JButton("按钮" + i)); }this.setVisible(true); this.setSize(300, 300); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new GirdLayoutDemo(); } }
JPanel
import java.awt.Container; import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.WindowConstants; public class JPanelDemo extends JFrame { public JPanelDemo() { Container container = this.getContentPane(); container.setLayout(new GridLayout(2, 1, 10, 10)); // 整个容器为2行 1列 JPanel p1 = new JPanel(new GridLayout(1, 3)); // 初始化一个面板,设 置1行3列的网格布局 JPanel p2 = new JPanel(new GridLayout(1, 2)); // 初始化一个面板,设 置1行2列的网格布局 JPanel p3 = new JPanel(new GridLayout(2, 1)); // 初始化一个面板,设 置2行1列的网格布局 JPanel p4 = new JPanel(new GridLayout(3, 2)); // 初始化一个面板,设 置3行2列的网格布局 p1.add(new JButton("1")); // 在JPanel面板中添加按钮 p1.add(new JButton("1")); // 在JPanel面板中添加按钮 p1.add(new JButton("1")); // 在JPanel面板中添加按钮 p2.add(new JButton("2")); // 在JPanel面板中添加按钮 p2.add(new JButton("2")); // 在JPanel面板中添加按钮 p3.add(new JButton("3")); // 在JPanel面板中添加按钮 p3.add(new JButton("3")); // 在JPanel面板中添加按钮 p4.add(new JButton("4")); // 在JPanel面板中添加按钮 p4.add(new JButton("4")); // 在JPanel面板中添加按钮 p4.add(new JButton("4")); // 在JPanel面板中添加按钮 p4.add(new JButton("4")); // 在JPanel面板中添加按钮 p4.add(new JButton("4")); // 在JPanel面板中添加按钮 p4.add(new JButton("4")); // 在JPanel面板中添加按钮 container.add(p1); // 在容器中添加面板 container.add(p2); // 在容器中添加面板 container.add(p3); // 在容器中添加面板 container.add(p4); // 在容器中添加面板 this.setVisible(true); this.setSize(500, 350); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new JPanelDemo(); } }
JScrollPane
若遇到一个较小的容器窗体中显示一个较大部分内容的情况,可用JScrollPane面板。这是一个带滚动条的面板,就像平时浏览网页,经常遇到的滚动条一样。
如果需要在JScrollPane面板中放置多个组件,需将这多个组件放置在JPanel面板上,然后将JPanel面板作为一个整体组件添加在JScrollPane面板上。
import java.awt.Container; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.WindowConstants; public class JScrollPaneDemo extends JFrame { public JScrollPaneDemo() { Container container = this.getContentPane(); JTextArea tArea = new JTextArea(20, 50); // 创建文本区域组件 tArea.setText("欢迎来到西部开源学Java"); JScrollPane sp = new JScrollPane(tArea); container.add(sp); this.setVisible(true); this.setSize(300, 150); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new JScrollPaneDemo(); } }
提交按钮组件(JButton)
import javax.swing.*; import java.awt.*; public class Demo extends JFrame { public Demo(){ Container container = this.getContentPane(); Icon icon = new ImageIcon(Demo.class.getResource("tx-old.jpg")); JButton jb = new JButton(); jb.setIcon(icon); // 设置图标 jb.setToolTipText("图片按钮"); // 设置按钮提示 container.add(jb); this.setVisible(true); this.setSize(500, 350); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new Demo(); } }
单选按钮组件(JRadioButton)
默认情况下,单选按钮显示一个圆形图标,通常在其旁放置一些说明性文字。当用户选中某个单选按钮后,按钮组中其它按钮将被自动取消,这时就需要按钮组(ButtonGroup)来将同组按钮放在一起,该按钮组中的按钮只能选择一个,而不在此按钮中的按钮不受影响。语法格式如下:
import javax.swing.*; import java.awt.*; public class Demo extends JFrame { public Demo(){ Container container = this.getContentPane(); Icon icon = new ImageIcon(Demo.class.getResource("tx-old.jpg")); //单选框 JRadioButton jr1 = new JRadioButton("JRadioButton1"); JRadioButton jr2 = new JRadioButton("JRadioButton2"); JRadioButton jr3 = new JRadioButton("JRadioButton3"); //按钮组,单选框只能选择一个 ButtonGroup group = new ButtonGroup(); group.add(jr1); group.add(jr2); group.add(jr3); container.add(jr1,BorderLayout.CENTER); container.add(jr2,BorderLayout.NORTH); container.add(jr3,BorderLayout.SOUTH); this.setVisible(true); this.setSize(500, 350); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new Demo(); } }
复选框组件(JCheckBox)
复选框是一个方块图标,外加一段描述性文字,与单选按钮的区别就是可以多选。每一个复选框都提供“选中”与“不选中”两种状态。语法格式如下
import javax.swing.*; import java.awt.*; public class Demo extends JFrame { public Demo(){ Container container = this.getContentPane(); Icon icon = new ImageIcon(Demo.class.getResource("tx-old.jpg")); //多选框 JCheckBox jrb = new JCheckBox("abc"); JCheckBox jrb2 = new JCheckBox("abc"); container.add(jrb); container.add(jrb2,BorderLayout.NORTH); this.setVisible(true); this.setSize(500, 350); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new Demo(); } }
下拉列表(JComboBox)
import javax.swing.*; import java.awt.*; public class Demo extends JFrame { public Demo(){ Container container = this.getContentPane(); Icon icon = new ImageIcon(Demo.class.getResource("tx-old.jpg")); JComboBox status = new JComboBox(); status.addItem(null); status.addItem("正在上映"); status.addItem("即将上映"); status.addItem("下架"); container.add(status); this.setVisible(true); this.setSize(500, 350); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new Demo(); } }
列表框(JList)
列表框只是在窗体上占据固定的大小,如果要使列表框具有滚动效果,可以将列表框放入滚动面板中。使用数组初始化列表框的参数如下。
import javax.swing.*; import java.awt.*; public class Demo extends JFrame { public Demo(){ Container container = this.getContentPane(); Icon icon = new ImageIcon(Demo.class.getResource("tx-old.jpg")); //使用数组初始化列表框的参数如下。 String[] contents = {"1", "2", "3"}; JList jl = new JList(contents); container.add(jl); this.setVisible(true); this.setSize(500, 350); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new Demo(); } }
将Vector类型的数据作为初始化JList的参数如下。
import javax.swing.*; import java.awt.*; import java.util.Vector; public class Demo extends JFrame { public Demo(){ Container container = this.getContentPane(); Icon icon = new ImageIcon(Demo.class.getResource("tx-old.jpg")); //将Vector类型的数据作为初始化JList的参数如下 Vector contents = new Vector(); JList jl = new JList(contents); contents.add("1"); contents.add("2"); contents.add("3"); container.add(jl); this.setVisible(true); this.setSize(500, 350); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); }public static void main(String[] args) { new Demo(); } }
文本框(JTextField)
JTextField jt = new JTextField("aaa"); // 创建一个文本框,值为aaa JTextField jt2 = new JTextField("aaa", 20); // 创建一个长度为20的文本框,值为 aaa jt.setText(""); // 将文本框置空
密码框(JPasswordField)
JPasswordField jp = new JPasswordField(); jp.setEchoChar('#'); // 设置回显符号
文本域(JTextArea)
JTextArea tArea = new JTextArea(20, 50); // 创建文本区域组件 tArea.setText("欢迎来到西部开源学Java");