GUI是图形用户接口,与之相对的是CLI,即命令行接口
GUI在awt和swing包下进行操作
java.awt 抽象窗口工具 需要调用本地系统方法实现功能 重量级控件
javax.swing 在awt的基础上建立的一套图形界面系统,提供了更多的组件,而且完全由Java实现,增强了移植性,轻量级控件
注:java和javax的区别:前者是基本的标准的java包,带x的是java的扩展包
重量级轻量级并不是说包的轻重,而是和本地系统方法的耦合度相关,因此在Windows下用awt实现的一个按钮在Linux下外观就有可能不一样
Component是一个具有图形表示能力的对象
继承体系图
上图中左边的Container Window Panel Frame Dialog FileDialog是容器组件
右边的Button Label Checkbox TextComponent TextArea Textfield是基本组件
基本组件依赖于容器组件
Window类的对象是一个没有边界和菜单栏的顶层窗口,窗口的默认布局是BorderLayout
Frame实Window的子类,是带有标题和边框的顶层窗口
public class FrameDemo{
public static void main(String[] args){
//创建窗体对象 构造一个最初不可见的Frame新实例
Frame f=new Frame();//java.awt.Frame
//调用一个方法,让窗体可见
//f.show();//show方法已过时
f.setTitle("helloworld");
f.setSize(400,300);//第一个是宽,第二个是高,单位像素
f.setLocation(400,200);//x坐标 y坐标
f.setVisible(true);
System.out.println("helloworld");
}
}
public class FrameDemo{
public static void main(String[] args){
Frame f=new Frame("设置方法调用的前后关系");
f.setSize(400,300);
//通过下面的方法也可以设置尺寸
//Dimension d=new Dimension(400,300);
//f.setSize(d);
f.setLocation(400,200);
//通过下面的方法也可以设置位置
//Point p=new Point(400,200);
//f.setLocation(p);
//还可以用一个方法来搞定
//f.setBounds(400,200,400,200);//类似canvas里面的fillRect
//如果需要延迟一段时间出现,将其放在setLocation和setSize之后效果比较好
try{
Thread.sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}
f.setVisible(true);
}
}
public class FrameDemo{
public static void main(String[] args){
Frame f=new Frame("窗体关闭");
f.setBounds(400,200,400,200);
f.setVisible(true);
//窗口的关闭是利用了事件监听机制
//事件源 事件 事件处理 事件监听 这些概念和js中的是一样的
f.addWindowListener(new WindowListener(){
//WindowListener是一个接口
//这里会自动生成很多方法,因为接口WindowListenr必须实现所有的方法
//但是我们需要监听的只有windowClosing一个
//此处采用匿名内部类来做
public void windowOpened(WindowEvent e){
}
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
}
上面实现窗口关闭太繁琐,我们并不需要接口中的那么多方法,所以我们要想办法解决这个问题,下面改用适配器类来关闭
public class FrameDemo{
public static void main(String[] args){
Frame f=new Frame("窗体关闭");
f.setBounds(400,200,400,200);
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
f.setVisible(true);
}
}
按钮点击
先介绍一下窗体布局方案
窗体布局即窗体中组建的排列方式
流式布局FlowLayout 从上到下 从左到右 Frame默认采用此布局方式
边界布局BorderLayout 东西南北中
网格布局GridLayout 按照矩阵区域划分成等大的矩形
网格包布局GridBagLayout 划分还是按照网格布局来,但可能一个按钮占两行 两列 或两行两列
卡片布局CardLayout 其实就是选项卡
public class FrameDemo{
Frame f=new Frame("添加按钮");
f.setBounds(400,200,400,300);
f.setLayout(new FlowLayout());//设置布局方式为流式布局,否则的话按钮就会撑满整个Frame,非常大
Button b=new Button("按钮");
f.add(b);
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("aaaa");
}
});
f.setVisible(true);
}
数据转移案例
public class FrameDemo{
public static void main(String[] args){
Frame f=new Frame("数据转移");
f.setBounds(400,400,400,400);
f.setLayout(new FlowLayout());
//局部内部类访问局部变量的时候需要加final
final TextField tf=new TextField(20);//20个字符,类似js里面的input
Button b=new Button("数据转移");
TextArea ta=new Textarea(10,40);//10行40列,类似textarea
//add的是偶是有顺序的
f.add(tf);
f.add(b);
f.add(ta);
f.addWindowListener(new WindowAdapter(){
public void windowClosing(){
System.exit(0);
}
});
b.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String tf_str=tf.getText().trim();
tf.setText("");
ta.append(tf_str+"\r\n");
tf.requestFocus();
}
});
f.setVisible(true);
}
}
选项卡改变背景
public class FrameDemo{
public static void main(String[] args){
Frame f=new Frame("数据转移");
f.setBounds(400,400,400,400);
f.setLayout(new FlowLayout());
Button redButton=new Button("数据转移");
redButton.addMouseListener(new MouseAdapter(){
//public void mouseClicked(MouseEvent e){
// f.setBackground(Color.RED);
//}
//类似js中的mouseover
public void mouseEntered(MouseEvent e){
f.setBackground(Color.RED);
}
//类似js中的mouseout
public void mouseExited(MouseEvent e){
f.setBackground(Color.GREEN);
}
});
}
}
只能输数字的输入框
public class FrameDemo{
public static void main(String[] args){
Frame f=new Frame("xxx");
f.setBounds(400,400,400,400);
f.setLayout(new FlowLayout());
Label label=new Label("只能输入数字");
TextField tf=new TextField(40);
f.add(label);
f.add(tf);
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
tf.addKeyListener(new KeyAdapter(){
public void keyPress(WindowEvent e){
char ch=e.getKeyCar();
if(ch<'0'||ch>'9'){
e.consume();
}
}
});
f.setVisible(true);
}
}
一级菜单案例
public class FrameDemo{
public static void main(String[] args){
Frame f=new Frame("一级菜单");
f.setBounds(400,400,400,400);
f.setLayout(new FlowLayout());
//菜单栏
MenuBar mb=new MenuBar();
//菜单
Menu m=new Menu("文件");
//菜单项
MenuItem mi=new MenuItem("退出");
m.add(mi);
mb.add(m);
f.setMenuBar(mb);
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
mi.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
f.setVisible(true);
}
}
多级菜单案例
public class FrameDemo{
public static void main(String[] args){
Frame f=new Frame("多级菜单");
f.setBounds(400,400,400,400);
f.setLayout(new FlowLayout());
//菜单栏
MenuBar mb=new MenuBar();
//菜单
Menu m1=new Menu("文件");
Menu m2=new Menu("更改名称");
//菜单项
final MenuItem mi1=new MenuItem("aaa");
MenuItem mi2=new MenuItem("bbb");
MenuItem mi3=new MenuItem("ccc");
MenuItem mi4=new MenuItem("ddd");
MenuItem mi5=new MenuItem("退出");
m2.add(mi1);
m2.add(mi2);
m2.add(mi3);
m1.add(m2);
m1.add(mi4);
m1.add(mi5);
mb.add(m1);
f.setMenuBar(mb);
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
mi1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
f.setTitle(mi1.getLabel());
}
});
mi4.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Runtime r=Runtime.getRuntime();
try{
r.exec("notepad");//打开记事本
}catch(IOException e){
e1.printStackTrace();
}
}
});
mi5.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.exit(0);
}
});
f.setVisible(true);
}
}