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+" "); 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); } }