奋斗黑马程序员----Java GUI基础讲解
2013-04-12 15:25
218 查看
----------android培训、java培训、期待与您交流! ----------
/** * Java GUI基础讲解: * 1 :GUI(图形用户界面) * 2 :GUI之布局 * 3 :GUI之Frame * 4 :列出制定目录的内容。 * 5 :菜单制作 * 6 :打开文件与保存文件 */ /** 1 :GUI(图形用户界面) * * 两种和用户进行交互的界面: * GUI:Graphical User Interface(图形用户接口),用图形的方式,来显示计算机 * 操作的界面,这样更方便更直观。 * CLI:Commend Line User Interface(命令行用户接口)。就是常见的DOS命令行操 * 作。需要记忆一些常用的命令,操作不直观。 * * 举例:如创建文件夹,删除文件夹等。 * * Java为GUI提供的对象都存在java.Awt和javax.Swing两个包中。 * Awt和Swing: * java.Awt:Abstract Window ToolKit(抽象窗口工具包),需要调用本地系统方法实现功能。 * 属重量级控件。(有点依赖于平台,跨平台性不太好) * java.Swing:在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件, * 而且完全由Java实现。增强了移植性,属轻量级控件。 (用的多) * eclipse用的不是二者,而是一个叫做SWT的包。 * * 体系构成(常用的) *component:组件 *|---Button:按钮 *|---Label:标签(组件需要文字支持,但是不能直接把文字放到组件上,就用了标签。用来封装文字。) *|---Checkbox:复选框 *|---TextComponent:文本组件 * |---TextArea: * |---TestField: * *|---Contianer:容器 * |---Window:窗口 * |---Frame:框架 * |---Dialog:对话框 * |---FileDialog:文件对话框。如,上传文件的。 * |---Panel:面板 * * Container:(有点特殊,作为一个组件,里面能添加组件。其他的不行)为容器,是一个特殊的组件, *该组件中可以通过add方法添加其他组件进来。如,可以把button添加到Container里,反之不行。 */ /** 2 :GUI之布局。 * * 容器中组件的排序方式,就是布局。 * 常见的布局管理器: * Flow Layout(流式布局管理器):默认是居中的。 * 1.从左到右的顺序排列 * 2.Panel默认的布局管理器 * BorderLayout(边界布局管理器) * 1.东。南,西,北,中 * 2.Frame默认的布局管理器 * GridLayout(网格布局管理器) * 1.规则的矩阵 * GardLayout(卡片布局管理器) * 1.选项卡 * GridBahLayout(网络包布局管理器) * 1.非规则的矩阵。 * * 窗体的默认布局为 BorderLayout。 */ /** 3 :GUI之Frame * * 创建图形化界面思路: * 1.创建Frame窗体。 * 2.对窗体进行基本设置。比如,大小,位置,布局== * 3.定义组件 * 4.将组件通过窗体的add方法添加到窗体中。 * 5.让窗体显示。setVisible(true). 最后一步。这样一个窗体就显现了。 * * 此时创建的窗体还存在很多的问题: * 1.点击按钮,没有反应。 * 2.可以最大化,和最小化,但是点击“关闭”,却不管用。 * == * * **事件监听机制。 * * dos命令行: * delete删除的是文件夹下所有的内容。 * 而rd删除的是文件夹 * * 鼠标右键有许多操作,很方便,但是实现起来却很难。 * * 做出的窗口无法关闭。是怎么回事呢?这里面涉及到一个问题:事件监听机制: * 事件监听机制组成: * 事件源(组件) * 事件(event) * 监听器(Listener) * 事件处理(引发事件后处理方式) * * 事件源:就是awt包或者swing包中的哪些图形界面组件。 * 事件:每一个事件源都有自己的特有的对应事件和共性事件。 * 监听器:将可以触发某一个事件的动作(不止一个动作)都已经封装到了监听器中。 * * 以上三者:在java中都已经定义好了。直接获取其对象来用就好了。 * 我们要做的是,就是对产生的动作进行处理就行了。(前三者开发的过程中,实例代 * 码是不需要写的。通过画布来完成) * * 理解案例: * 1.金库密码锁:当有外部非正常的操作(如,撬,砸等)时,报警器(监听装置)就会 * 采取相应的处理方式。 * * * **窗体事件--关闭动作 * * 经查手册可知:WindowListener接口中有我们需要的方法,但是。 * class MyWin implements WindowListener * { * //如果要实现这个类,必须要覆盖里面的7个方法,可是我们只用到了其中的关闭动作。 * //其他的动作都没有用到,可是却必须复写。如此一来就显得很麻烦。 * //因此我们又找到了其子类WindowAdapter(抽象的,但是其方法却不是抽象的,防止其创建子类). * } * * 因为WindowListener的子类WindowAdapter已经实现了WindowListener接口, * 并覆盖了其中的所有方法,那么我们只要继承自WindowAdapter,覆盖我们需要的方法即可。 * * public interface WindowListener extends EventListener * 用于接收窗口事件的侦听器接口。旨在处理窗口事件的类要么实现此接口(及其包含的所有方 * 法),要么扩展抽象类 WindowAdapter(仅重写所需的方法)。然后使用窗口的 addWindowListener * 方法将从该类所创建的侦听器对象向该 Window 注册。当通过打开、关闭、激活或停用、图标化或 * 取消图标化而改变了窗口状态时,将调用该侦听器对象中的相关方法,并将 WindowEvent 传递给 * 该方法。 * * public abstract class WindowAdapter extends Object implements WindowListener, * WindowStateListener, WindowFocusListener * 接收窗口事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象。 * 扩展此类可创建 WindowEvent 侦听器并为所需事件重写该方法。(如果要实现 WindowListener * 接口,则必须定义该接口内的所有方法。此抽象类将所有方法都定义为 null,所以只需针对关 * 心的事件定义方法。) */ import java.awt.*; //导入此包,只能添加窗体,但没有对应的处理动作 import java.awt.event.*; //导入此包,可以为窗体添加效果(即时间监听)。玩窗体,此包必不可少。 public class AwtDemo { public static void main(String[] args) { /**方法摘要: * void setSize(int width, int height) 调整组件的大小,使其宽度为 width,高度为 height。 * * (Component) void setLocation(int x, int y) 将组件移到新位置。 * x - 父级坐标空间中新位置左上角的 x 坐标 * y - 父级坐标空间中新位置左上角的 y 坐标 * * (Container) void setLayout(LayoutManager mgr) 设置此容器的布局管理器。 * FlowLayout() 构造一个新的 FlowLayout,它是居中对齐的,默认的水平和垂 * 直间隙是 5 个单位。 * * (Container) Component add(Component comp) 将指定组件追加到此容器的尾部。 * * Button(String label) 构造一个带指定标签的按钮。 */ Frame f = new Frame("my awt"); System.out.println("看到什么么?"); /*图形化界面是有另外的线程来控制的。如果想要让窗体可见。这个要放到最后。 * 2.看到窗体了。哈哈。但是太mini了。有点不爽。 */ f.setSize(500,400); //3.setSize(横坐标,纵坐标); 一般第一个都是横的,第二个都是纵的。 // 4.窗体每次出现的位置都是在左上角,有点不爽。那怎么自定义位置呢? f.setLocation(300,200); //定点距上边和左边的距离。 //6.调节按钮的方法。 f.setLayout(new FlowLayout()); //原来的按钮是全窗口的,加上这个之就会发生改变。 Button b = new Button("我是一个按钮"); f.add(b); /*5.按钮有点大。怎么调节? * 边界式布局。在Frame里调节。 * 用setLayout();调节。要放于button上面。 */ /** * 添加关闭动作。可用匿名内部类来代替。 * void addWindowListener(WindowListener l) 添加指定的窗口侦听器,以从此窗口接收窗口事件。 * 抽象类WindowAdapter继承WindowListener,并重写了父类中的所有方法,但是,WindowAdapter中 * 的所有方法却都不是抽象的,都有方法体,只不过方法体是null而已。 */ //f.addWindowListener(new MyWin()); f.addWindowListener(new WindowAdapter() { /* * public void windowClosing(WindowEvent e)窗口正处在关闭过程中时调用。 * 此时可重写关闭操作。 * * public class WindowEvent extends ComponentEvent指示窗口状态改变的低级别事件。 * 当打开、关闭、激活、停用、图标化或取消图标化 Window 对象时,或者焦点转移到 * Window 内或移出 Window 时,由 Window 对象生成此低级别事件。 * * public static void exit(int status)终止当前正在运行的 Java 虚拟机。参数用作 * 状态码;根据惯例,非 0 的状态码表示异常终止。 */ public void windowClosing(WindowEvent e) //该动作最常见 { System.out.println("这个匿名内部类的关闭方法"); System.exit(0); //非0数字表示非正常关闭虚拟机 } public void windowActivated(WindowEvent e) //激活状态。即前置。 { System.out.println("我活了。。。"); } public void windowOpened(WindowEvent e) //开启动作就一次。 { System.out.println("我被打开了,哈哈哈"); } } ); //1.没有反应,什么都没有看到。也没有见窗体啊。f.setVisible(true);可以解决。 f.setVisible(true); System.out.println("这次看到什么了?"); } } class MyWin extends WindowAdapter { public void windowClosing(WindowEvent e) { //System.out.println("Window closing"+e.toString()); //打印关闭的信息 System.out.println("只要你点了关闭,窗体就会关闭,不信你试试"); /*但是输出信息是在后面的,这也就意味着,这里面所有的操作都是在点击 * 关闭后才会出现的。 */ System.exit(0); //可以实现关闭的操作。 } } /**4 :列出制定目录的内容。 * 用到的内容: * 1,一个窗体 * 2,按钮,文本框,文本域 * 3,对话框 * 4,label层 * * */ import java.awt.*; import java.awt.event.*; import java.io.*; public class MyWindow //extends Frame //继承Frame也可以。 { private Frame f; private TextField tf; private Button but; private TextArea ta; private Dialog d; /* 关于dialog的存在,如果用户的输入时正确的话,或窗体还没有加载完,此时 * dialog就没必要存在了。否则会浪费内存。 * dialog上面有一个按钮,还有些文字提示。 */ private Label lab; //把文字封装成对象,添加到组件上。组件里不能直接写文本。 private Button okBut; MyWindow() { init(); } public void init() { /* * void setBounds(int x, int y, int width, int height) 移动组件并调整其大小。 * x - 组件的新 x 坐标 * y - 组件的新 y 坐标 * width - 组件的新 width * height - 组件的新 height * * Dialog(Dialog owner, String title, boolean modal) 构造一个最初不可见的 Dialog, * 它带有指定的所有者 Dialog、标题和模式。 * owner - dialog 的所有者,如果此 dialog 没有所有者,则该参数为 null * title - dialog 的标题,如果此 dialog 没有标题,则该参数为 null * modal - 指定在显示的时候是否阻止用户将内容输入到其他顶级窗口中。如果该参数为 false, * 则 dialog 是 MODELESS;如果该参数为 true,则模式类型属性被设置为 DEFAULT_MODALITY_TYPE */ f = new Frame("My windwo"); f.setBounds(300,100,600,500); //设置窗体的位置。 f.setLayout(new FlowLayout()); //设置布局管理 tf = new TextField(60); //制定列数 but = new Button("转到"); ta = new TextArea(25,70); //参数可以指定行、列。还可传入默认文字。不需要可以不写。 d = new Dialog(f,"提示信息--self",true); /* * 构造函数:Dialog(Frame owner, boolean modal) * 后面的modal(模式): * 1,为true时,这个对话框如果用户不操作,那么它所属的窗体就无法操作。就会死。 * 2,为false时,可以不操作对话框,但可以操作窗体。 */ d.setBounds(400,200,240,160); d.setLayout(new FlowLayout()); /* * public class Label extends Component implements Accessible * Label 对象是一个可在容器中放置文本的组件。一个标签只显示一行只读文本。文本可 * 由应用程序更改,但是用户不能直接对其进行编辑。 * * Label() 构造一个空标签。 */ lab = new Label(); //初始化时没有信息的。 okBut = new Button("确定"); d.add(lab); d.add(okBut); /*其实,d本身也是一个窗体,可以加到Frame里面。 * 因为Frame一打开,Dialog就存在,是没有意义的。只有见到某些操作,才会出现。 * */ f.add(tf); f.add(but); f.add(ta); /* * 现在基本的界面已经做出来了。但是我们想要的是,在文本框里输入一个“路径”,点击“转到”, * 然后就能列出该目录下的文件。(不要求实现图标,但要显示名字) * 做这个功能:按钮是事件源。 */ myEvent(); f.setVisible(true); } private void myEvent() { /* * Button--void addActionListener(ActionListener l) 添加指定的动作侦听器, * 以接收发自此按钮的动作事件。 * * public interface ActionListener extends EventListener * 用于接收操作事件的侦听器接口。对处理操作事件感兴趣的类可以实现此接口, * 而使用该类创建的对象可使用组件的 addActionListener 方法向该组件注册。在 * 发生操作事件时,调用该对象的 actionPerformed 方法。 * * void actionPerformed(ActionEvent e) 发生操作时调用。 */ okBut.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { d.setVisible(false); } }); f.addWindowListener(new WindowAdapter() //实现窗口关闭。 { public void windowClosing(WindowEvent e) { System.exit(0); } } ); /*在windows中,输入路径后,一“回车”就会转到相应目录。 * 那么怎么实现呢? * 此时,文本框是事件源,要为文本框添加键盘监听 * * void addKeyListener(KeyListener l) 添加指定的按键侦听器, * 以接收发自此组件的按键事件。 * * void keyPressed(KeyEvent e) 按下某个键时调用此方法。 * * KeyEvent--int getKeyCode() 返回与此事件中的键关联的整数 keyCode。 * */ tf.addKeyListener(new KeyAdapter() { public void keyPressed(KeyEvent e) { if(e.getKeyCode()==KeyEvent.VK_ENTER) { showDir(); } } }); d.addWindowListener(new WindowAdapter() //实现窗口关闭。 { public void windowClosing(WindowEvent e) { //System.exit(0); d.setVisible(false); } } ); but.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { showDir(); } }); } private void showDir() { /* * TextField---String getText() 返回此文本组件表示的文本。 * * TextArea---void setText(String t) 将此文本组件显示的文本设置为指定文本。 * * TextArea---void append(String str) Appends the given text to the text * area's current text. */ String dirPath = tf.getText(); //接受路径。 File dir = new File(dirPath); if(dir.exists() && dir.isDirectory()) //判断路径是否存在,是否是目录 { String[] names = dir.list(); ta.setText(""); //将之前的信息清空 ta.setText("\""+dirPath+"\""+"目录下的文件有:\r\n"); for(String name:names) { //ta.setText(name+"\r\n"); //添加数据。 /* * 但是此时还有个问题:每次获取到的数据存到文本域里,都会替换原来 * 的数据,这个怎么解决? * 可以用一个StringBuilder存起来。 * TextArea里面有一个append方法。追加。 */ ta.append(name+"\r\n"); /* * 但是这时又出现一个问题:第一次添加的名字在下一次添加时并没有删除。 * 而是显示到了新的目录下。在循环开始前用setText("");清空 */ } } /* * 此时又出现了问题,如果所输入的路径不存在,应该有提示的。但此时还没 * 有实现这个功能。(对话框,window的子类) */ else{ String info = "您输入的路径:\""+dirPath+"\"是错误的"; lab.setText(info); //lab.setAlignment(Label.CENTER); //文字居中。 d.setVisible(true); //这个参数必须要为true,否则对话框就是隐藏的。 } //找tf的对象获取文本。 String text = tf.getText(); //按钮已经获取到了文本框的内容。 //System.out.println(text); //测试输出 //ta.setText(text); //将获取到的文本数据放到文本域里。 /* * 但是此时还有个问题:每次获取到的数据存到文本域里,都会替换原来的 * 数据,这个怎么解决? */ //tf.setText(""); //清空文本框里的数据。 } public static void main(String[] args) { new MyWindow(); } } /** 5 :菜单制作 * * 菜单制作过程: * 1,一个窗口要有菜单,首先要有MenuBar,不过真实编程中,f.setMenuBar(mb) * 要放到最后一步(切记) * 2,MenuBar上面要有菜单,必须要将Menu放到MenuBar上,而且只能是Menu。 * 3,如果要制作多级菜单:子菜单项MenuItem 必须要 添加到Menu上,然后把该 * Menu添加到MenuBar上。 * 4,上面的过程倒着来。 */ import java.awt.*; import java.awt.event.*; public class MyMenuDemo { private Frame f; private MenuBar mb; private Menu m; private MenuItem closeItem,subItem; private Menu subMenu; MyMenuDemo() { init(); } public void init() { /* * MenuItem add(MenuItem mi) 将指定的菜单项添加到此菜单。 */ f = new Frame("my window"); f.setBounds(300,100,500,600); f.setLayout(new FlowLayout()); //布局管理 mb = new MenuBar(); //搞一个菜单条 subMenu = new Menu("子菜单"); m = new Menu("文件"); //菜单初始化 subItem = new MenuItem("子条目"); /* * 怎么给子菜单添加子菜单。 */ closeItem = new MenuItem("退出"); //菜单项 /*向menu a 中添加menu b,b会带有小三角.那么b还可以有子条目 * 如果向menu a中添加menuItem c,则c不会带有小三角。即c为最终条目 */ subMenu.add(subItem); m.add(subMenu); m.add(closeItem); //将菜单项添加到菜单中。 mb.add(m); //将菜单添加到菜单条中。 f.setMenuBar(mb); //setMenuBar(MenuBar mb) 将此窗体的菜单栏设置为指定的菜单栏。 myEvent(); f.setVisible(true); } public void myEvent() { f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); /* * MenuItem addActionListener(ActionListener l) 添加指定的动作侦听器,以从此菜单项接收动作事件。 * 动作侦听器:菜单条目可以用键盘操作。 * */ closeItem.addActionListener(new ActionListener() //菜单监听器,菜单条目事件 { public void actionPerformed(ActionEvent e) { System.exit(0); } }); } public static void main(String[] args) { /*菜单栏,菜单项 * MenuBar * */ new MyMenuDemo(); } } /** 6 :打开文件与保存文件 * 主要用的知识是:FileDialog,以及以前IO里面的操作。 * * public class FileDialog extends Dialog * FileDialog 类显示一个对话框窗口,用户可以从中选择文件。 由于它是一个模式对话 * 框,当应用程序调用其 show 方法来显示对话框时,它将阻塞其余应用程序,直到用户选 * 择一个文件。 * * FileDialog(Dialog parent, String title, int mode) 创建一个具有指定标题的文件 * 对话框窗口,用于加载或保存文件。 * parent - 对话框的所有者 * title - 对话框的标题;接受 null 值时不会抛出 NullPointerException * mode - 对话框的模式,FileDialog.LOAD 或 FileDialog.SAVE * * *总结: *1.操作窗体的动作: * f.addWindowListener(new WindowAdapter(){ * public void .....(WindowEvent e){ * ...... * } * }); *2.控制菜单的动作: * menuItem.addActionListener(new ActionListener(){ * public void actionPerformed(ActionEvent e){ * ....... * } * }); * */ import java.awt.*; import java.awt.event.*; import java.io.*; public class MyMenuTest { private Frame f; private MenuBar mb; //使用菜单,必须要有menubar private Menu m; private MenuItem openItem,saveItem,closeItem; private FileDialog openDia,saveDia; private TextArea ta; private File file; //为什么要这么写? MyMenuTest() { init(); } public void init() { f = new Frame("my window"); mb = new MenuBar(); m = new Menu("文件"); ta = new TextArea(); openItem = new MenuItem("打开"); saveItem = new MenuItem("保存"); closeItem = new MenuItem("退出"); f.setBounds(200,100,600,400); //f.setLayout(new FlowLayout()); //没有了这个设置,文本域会自动适应窗体。 m.add(openItem); m.add(saveItem); m.add(closeItem); mb.add(m); f.setMenuBar(mb); openDia = new FileDialog(f,"我要打开",FileDialog.LOAD); saveDia = new FileDialog(f,"我要保存",FileDialog.SAVE); f.add(ta); myEvent(); f.setVisible(true); } public void myEvent() { f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); openItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { openDia.setVisible(true); //这个必须要放在最上面,否则会出错。 /* * FileDialog-- String getDirectory() 获取此文件对话框的目录。 * * FileDialog-- String getFile() 获取此文件对话框的选定文件。 */ String dirPath = openDia.getDirectory(); String fileName = openDia.getFile(); //System.out.println(dirPath+"...."+fileName); //测试一下 if(dirPath==null || fileName==null) { //如果点击了“取消”话,没有此判断会出异常。 return ; //直接返回,不做任何事情 } ta.setText(""); //清空之前的文件 File file = new File(dirPath,fileName); try{ BufferedReader bufr = new BufferedReader(new FileReader(file)); String line = null; while((line=bufr.readLine())!=null) { ta.append(line+"\r\n"); } bufr.close(); } catch(IOException x) { throw new RuntimeException("读取失败"); } } }); /**保存文件 * 打开已经写完了。 * 保存对话框,有一个问题,就是该对话框在什么时候弹出呢?(不是“另存为”) * 如果文件存在,就不弹出,直接保存;如果文件不存在,就要弹出。 * */ saveItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if(file==null) //此处的file怎么理解? { //弹与不弹,关键怎么办? saveDia.setVisible(true); String dirPath = saveDia.getDirectory(); String fileName = saveDia.getFile(); if(dirPath==null||fileName==null) return ; file = new File(dirPath,fileName); //此时,如果文件已经存在,就不需要再new了。所以要把文件提到成员上来。 } try{ BufferedWriter bufw = new BufferedWriter(new FileWriter(file)); String text = ta.getText(); bufw.write(text); bufw.flush(); bufw.close(); } catch(IOException ex) { throw new RuntimeException(); } } }); /* closeItem.addActionListener(new ActionListener() { public void windowClosing(WindowEvent e ) { } }); */ } public static void main(String[] args) { new MyMenuTest(); } } /**6 :双击jar包执行。(具体请参照视频)因为是win7系统,所以不便操作。 * 在使用dos命令行是,会有点麻烦。而且使用javac编译时,会在目录下产生好多类。有点乱。 * 此时,搞个包就完了:在最顶行添加代码:package mymenu; 其中,mymenu表示要打成的包名。 * 使用此命令: javac -d e:\java(目的地) MyMenuTest.java * 然后进入e:\java * 使用命令:jar -cvf my.jar mymenu * */
[/code]
----------android培训、java培训、期待与您交流!----------
详细请查看:http://edu.csdn.net/heima/
相关文章推荐
- 黑马程序员Java基础__GUI
- 黑马程序员——Java基础—GUI
- 黑马程序员-java基础(八)-图形用户界面GUI
- 黑马程序员_Java基础_GUI
- 黑马程序员_java基础_GUI
- 黑马程序员 java基础24天 GUI编程学习总结
- 黑马程序员-->Java基础-->GUI
- 黑马程序员——java基础——GUI
- 黑马程序员---java基础----GUI添加工具栏
- 黑马程序员_java基础11-GUI
- 黑马程序员-JAVA基础-GUI
- 黑马程序员——【Java基础】——GUI(图形用户界面)
- 黑马程序员:Java基础总结----GUI图形化界面
- 黑马程序员:Java基础总结----GUI图形化界面
- 黑马程序员 ----java基础----自制一个画图板GUI
- 黑马程序员——Java基础---GUI,网络编程
- 黑马程序员——Java基础--GUI(图形化界面)
- 黑马程序员—java技术blog—第十二篇java基础应用GUI模拟登陆注册
- 黑马程序员——Java基础---GUI
- 黑马程序员_java基础-图形用户接口GUI(Graphical User Interface)