JAVA图形用户界面设计与实现.ppt
图形用户界面的设计与实现,教材第7章,设计原则 容器与布局 标准组件 事件处理 自定义成分,用户界面设计原则,使用图形界面GUI(Graphics User Interface)字符界面采用命令行方式与用户交互。图形界面用多种媒体显示信息,用直观、方便的GUI标准组件来接收命令。控制权在用户(用户要由操作的主动权)界面与操作的风格一致性。宽容(容错)性。简洁与美观并重。,界面构成,容器,标准组件,用户自定义成分,创建GUI各组成成分,并安排相互 位置关系(包含,相邻,相交)。定义GUI各成分对不同事件的响应,实现与用户的交互与界面功能。,界面元素,容器是用来组织其他界面成分和元素的单元。可以形成容器的层次,构筑复杂结构Window(Frame、Applet、Dialog)组件是图形用户界面的基本单位,它里面不再包含其他的成分。GUI组件是图形用户界面标准化的结果。GUI组件的作用是完成与用户的交互。用户自定义成分文字、图形、图象不能像标准组件一样被系统识别和承认,只起装饰作用。不能响应用户的动作,不具有交互功能。,AWT包,Abstract Windows Toolkit(抽象窗口工具)AWT类库中的各种操作是被定义为在一个并不存在的“抽象窗口”中进行的。抽取不同软硬件平台中所实现的窗口的公共特性。所设计的界面独立于具体的界面实现。提供与机器无关的基本GUI标准组件。选择类组件:单选按钮、复选框、下拉选单、列表框文字处理类组件:标签、文本框、编辑框命令类组件:按钮、工具栏、菜单,AWT类层次关系图,Component,Container,Panel,Applet,Window,Frame,Dialog,Button,TextField,TextArea,TextComponent,Checkbox,MenuComponent,Menu,MenuItem,MenuBar,其他组件,独立,不独立,Component类,可显示在屏幕上的图形对象,可与用户交互。方法:add(PopupMenupopup)加一弹出菜单addFocusListener(FocusListenerl)将发生在本组件上的事件注册给监听者,以进行事件处理。setSize(intwidth,intheight)设置组件尺寸paint(Graphicsg)重画组件setFont(Fontf)设置组件字体setBackground(Colorc)设置组件背景色setForeground(Colorc)设置组件前景色,paint和repaint 方法,某组件的paint()和 update()为系统自动调用的有关图形绘制的方法,不可人为编程调用;但可编程重新定义其操作内容。使用repaint()方法可以触发update()方法。,Font类,设计字体显示效果(创建字体对象)Font fn=new Font(String 字体,int 风格,int 字号);字体:TimesRoman,Courier,Arial等风格:三个常量Font.PLAIN,Font.BOLD,Font.ITALIC字号:字的大小(磅数)使用字体对象 如设置某组件当前使用的字体:setFont(Font fn)获取组件当前使用的字体:getFont(),Color类,构造函数1(设置颜色)Color c=new Color(intred,intgreen,intblue)范围:0255 new Color(200,200,200)new Color(255,0,100)构造函数2Color c=new Color(int rgb)兰色:07 位 绿色:815位 红色:1623位 颜色常量值public static final Color black Color.black,Color.blue,Color.gray,Color.red Color.white,Containers 容器组件,Window 不需要其他组件支撑,独立显示。Frame Dialog 没有菜单条,不能改变大小Panel 必须放在Window组件中(或Web浏览器窗口)才能显示。它为一矩形区域,在其中可摆放其他组件,可以有自己的布局管理器。基本方法add(Component comp)将指定组件放到容器中add(Component comp,int index)remove(Componentcomp)删除指定组件setLayout(LayoutManagermgr)设置容器布局paint 画容器(及其上面的组件),容器的组件布局,依靠布局管理器(layout manager)方式调用容器的setLayout方法,为容器指定某种布局管理器的一个对象。例:setLayout(new FlowLayout()该布局管理器对象负责确定容器中组件的位置和大小。当容器需要定位组件和确定组件大小时,就会给布局管理器对象发消息,让它完成该项工作。直接管理组件方式调用容器的 setLayout(null)方法,关闭布局管理器。调用每一个组件的setLocation()方法决定组件位置。调用每一个组件的setSize()方法决定其大小。直接管理组件将失去平台无关性。,布局管理器对象,布局管理器种类,FlowLayout:组件在一行中从左至右水平排列,排满后折行BorderLayout:北、南、东、西、中GridLayout:以行和列的网格形式安排组件GridBagLayout:更复杂、功能更强的网格布局CardLayout:每一个组件作为一个卡片,容器仅显示多个卡片中的某一个,确定容器布局,缺省的布局管理器Window、Frame、Dialog BorderLayoutPanel、Applet FlowLayout:选择布局管理器的方法建立布局管理器类的对象利用容器的 setLayout 为容器指定布局(即指定一个布局管理器的对象)例:将myFrame布局设定为FlowLayout类型 myFrame.setLayout(new FlowLayout();,Frame,Frame(String title)构造一个新的不可见的frame隐含的布局管理器是:BorderLayoutsetLayout()设置新的布局管理器。add(Componentcomp)在容器上增加一个组件(在容器为不可见的状态时加)。void setSize(intwidth,intheight)setVisible(true),7-1a,Frame Panel,Frame fm1=new Frame(Hello);fm1.setSize(400,350);fm1.setBackground(Color.gray);fm1.setLayout(null);Panel pn1=new Panel();pn1.setSize(100,100);pn1.setBackground(Color.red);pn1.setLocation(0,50);fm1.add(pn1);fm1.setVisible(true);,7-1b,FlowLayout布局管理器,构造函数:FlowLayout();FlowLayout(int align,int hgap,int vgap);align:对齐方式:LEFT CENTER RIGHThgap:组件水平间距(象素)vgap:组件垂直间距(象素)无参数的构造函数创建的FlowLayout对象,其对齐方式为CENTER居中方式,组件间的横纵间距都为5个像素。,FlowLayout布局管理器,Frame f=new Frame(FlowLayout);f.setSize(400,300);/不起作用 f.setBackground(Color.gray);f.setLayout(new FlowLayout(FlowLayout.LEFT,10,20);b1=new Button(button1);b2=new Button(button2);b3=new Button(button3);f.add(b1);f.add(b2);f.add(b3);f.setVisible(true);f.pack();,7-1c,BorderLayout布局管理器,setLayout(new BorderLayout()add(b1,BorderLayout.NORTH);当容器大小改变,组件相对位置不会改变。,BorderLayout布局管理器,f=new Frame(BorderLayout);f.setSize(200,200);b1=new Button(button1);b5=new Button(button5);f.add(b1,BorderLayout.NORTH);f.add(b2,BorderLayout.SOUTH);f.add(b3,BorderLayout.WEST);f.add(b4,BorderLayout.EAST);f.add(b5,BorderLayout.CENTER);f.setVisible(true);,7-1d,Border-Panel,class MyFrame extends Frame MyFrame()Button b1=new Button(1);Button b2=new Button(2);Button b3=new Button(3);Button b4=new Button(4);Panel p=new Panel();p.add(b1);p.add(b2);add(p,BorderLayout.NORTH);add(b3,BorderLayout.WEST);add(b4,BorderLayout.CENTER);pack();setVisible(true);,7-1e,GridLayout布局管理器,创建GridLayout对象作为布局编辑器,指定划分网格的行数和列数(网格大小一样)。setLayout(new GridLayout(行数,列数);setLayout(new GridLayout(行数,列数,行间隔,列间隔);调用容器的方法add()将组件加入容器,组件填入容器的顺序将按照第一行第一个格中、第一行第二个格中、每个网格中都必须填入组件,如果希望某个网格为空白,可以为它加入一个空的标签:add(new Label();,GridLayout布局管理器,f=new Frame(GridLayout);f.setLayout(new GridLayout(2,3);f.setSize(200,100);f.setBackground(Color.gray);b1=new Button(1);b6=new Button(6);f.add(b1);f.setVisible(true);,7-1f,布局例,Frame fm=new Frame()fm.setLayout(new FlowLayout();tf=new TextField(22);fm.add(tf);Panel p1=new Panel();p1.setLayout(new GridLayout(4,3);p1.add();Panel p2=new Panel();p2.setLayout(new GridLayout(4,3);p2.add();fm.add(p1);fm.add(p2);,7-2布局,GridBagLayout布局管理器,每个GridBagLayout对象维护一个动态矩形网格,每个组件可占据一个或多个单元作为它的显示区域。每一个组件都与一个GridBagConstraints类的实例相连,以指定在显示区域中如何摆放,并可确定大小。步骤:setLayout(new GridBagLayout();GridBagConstraints gbc=new GridBagConstraints();gbc.gridx=0;(属性赋值)add(button1,gbc),GridBagLayout布局管理器,设置GridBagConstraints类实例属性值:gridx gridy 组件显示区域的左上角单元格坐标gridwidth gridheight 指定显示区域行、列单元数RELATIVE 指定紧挨着前一个组件摆放fill 当显示区域大于组件时如何扩充组件:HORIZONTAL 水平充满 VERTICAL 垂直充满 BOTH 全部填充 NONE 不调整(隐含)ipadx ipady 指定组件间最小间隔 anchor 当显示区域大于组件时如何摆放组件:CENTER(隐含),NORTH,EAST,SOUTH,WEST,SOUTHEAST,NORTHEAST,SOUTHWEST,NORTHWEST.,CardLayout布局管理器,将每一个组件视为一张卡片,同一时刻只能显示一个组件。setLayout(new CardLayout()CardLayout方法(按序指定组件)first(Containerparent)last(Containerparent)previous(Containerparent)next(Containerparent)CardLayout方法(按名显示组件)addLayoutComponent(Stringname,Componentc)show(Containerparent,Stringname),事件及处理机制,用户操作GUI组件时会引发各种事件。事件:描述“发生了什么事情”的对象。系统根据用户的操作构造出相应事件类的对象。事件源:事件的产生地。事件处理程序:是一个方法,它接收一个事件对象,分析它,并完成对该事件的处理。每个事件有一个相应的监听者接口,它规定了能够接收(并处理)该类事件的方法的规范。监听者:实现了监听者接口的类,它包含有事件处理程序。编程人员要为事件源指定监听者对象(即指定处理某种事件的事件处理程序监听者对象方法)。,鼠标单击按扭,事件及处理机制,ActionEvent事件,public void actionPerformed(ActionEvent e),ActionListener接口,ActionEvent事件,监听者类,监听者对象,调用按扭的 addActionListener()方法,为该按扭指定监听者。,实现接口,事件类,ActionEvent类:存放这个事件的细节。该类的方法有:getSource()返回事件发生的对象(名)getActionCommand()返回按扭名。ActionListener 接口public void actionPerformed(ActionEvent e),图形用户界面例,import java.awt.*;import java.awt.event.*;public class a public static void main(String args)MyFrame form1=new MyFrame();class MyFrame extends Frame MyFrame()super(窗口标题);setSize(200,100);setFont(new Font(TimesRoman,Font.BOLD,20);,图形用户界面例,setLayout(new FlowLayout();Button b=new Button(close);add(b);b.addActionListener(new Bprocess();setVisible(true);class Bprocess implements ActionListener public void actionPerformed(ActionEvent e)System.exit(0);,监听者类,某个类可以兼职也可以专职做这件事(实现监听者接口)。一个类若实现一个接口,必须实现接口的全部方法。例如:ActionListener接口只有一个方法:void actionPerformed(ActionEvent e)实现接口的类可以是:一般类内部类匿名类,7-3 一般类,7-4 内部类,7-5 匿名类,事件处理有关问题,有哪些事件类(java.awt.event)?每个事件类的监听者接口?每个监听者接口规定的方法?多方法的监听者接口的适配器(实现接口的抽象类)是什么?组件的事件委托(注册)方法?,窗口事件(适配器说明),关闭窗口框时引发 WindowEvent事件委托:addWindowListener(new Wclose();定义监听者类 class Wclose implements WindowListener public void windowClosing(WindowEvent e)System.exit(0);其他方法,窗口事件,WindowListener类有7 个方法,都必须实现。windowActivated(WindowEvent e)windowClosed(WindowEvent e)windowClosing(WindowEvent e)windowDeactivated(WindowEvent e)windowDeiconified(WindowEvent e)windowIconified(WindowEvent e)windowOpened(WindowEvent e)WindowAdapter:系统实现的处理窗口事件的抽象适配器类,用空内容实现了WindowListener接口的全部7个方法。class Wclose extends WindowAdapter,仅须编写需要的方法,ActionEvent事件,引发原因:单击按扭,双击列表框中选项,选择菜单项,文本框中的回车事件监听接口:ActionListener接口方法:actionPerformed(ActionEvent e)组件注册该事件方法:addActionListener(监听者对象),TextEvent事件,引发原因:文本框或文本区域内容改变事件监听接口:TextListener接口方法:textValueChanged(TextEvente)组件注册该事件方法:addTextListener(监听者对象),ItemEvent事件,引发原因:改变列表框中的选中项改变复选框选中状态改变下拉选单的选中项事件监听接口:ItemListener接口方法:itemStateChanged(ItemEvente)组件注册该事件方法:addItemListener(监听者),AdjustmentEvent事件,引发原因:操作滚动条改变滑块位置事件监听接口:AdjustmentListener接口方法:adjustmentValueChanged(AdjustmentEvente)组件注册该事件方法:addAdjustmentListener(监听者),KeyEvent事件,引发原因:敲完键(KEY-TYPED)按下键(KEY-PRESSED)释放键(KEY-RELEASE)事件监听接口:KeyListener接口方法:keyPressed(KeyEvente)键已被按下时调用keyReleased(KeyEvente)键已被释放时调用keyTyped(KeyEvente)键已被敲完时调用KeyEvent方法:char ch=e.getKeyChar();事件监听适配器(抽象类)KeyAdapter组件注册该事件方法:addKeyListener(监听者),MouseEvent事件,引发原因:(鼠标作用在一个组件上)鼠标事件:鼠标键按下,鼠标键抬起,单击鼠标,鼠标光标进入一个组件,鼠标光标离开一个组件。鼠标移动事件:鼠标移动,鼠标拖动 鼠标事件监听接口1:MouseListener 接受鼠标事件该接口定义的方法:mouseClicked(MouseEvente)mouseEntered(MouseEvente)鼠标光标进入一个组件mouseExited(MouseEvente)鼠标光标离开一个组件鼠标事件监听适配器(抽象类)MouseAdapter,MouseEvent事件(续),鼠标事件监听接口2:MouseMotionListener 接受鼠标移动事件该接口方法:mouseMoved(MouseEvente)鼠标光标在组件上移动mouseDragged(MouseEvente)用鼠标拖动一个组件鼠标移动事件监听适配器 MouseMotionAdapter组件注册鼠标事件方法:add MouseListener(监听者)组件注册鼠标移动事件方法:add MouseMotionListener(监听者),MouseEvent事件(续),MouseEvent方法e.getClickCount()=1 单击=2 双击Point e.getPoint()取鼠标光标位置int e.getX()int e.getY()取鼠标光标位置e.getModifiers()=e.BUTTON1_MASK 鼠标左键=e.BUTTON3_MASK 鼠标右键,7-6 鼠标事件,WindowEvent事件,引发原因:有关窗口操作引发的事件事件监听接口WindowListener接口方法windowActivated(WindowEvente)激活窗口windowClosed(WindowEvente)调用dispose方法关闭窗口后。windowClosing(WindowEvente)试图利用窗口关闭框关闭窗口windowDeactivated(WindowEvente)本窗口成为非活动窗口,WindowEvent事件(续),windowDeiconified(WindowEvente)窗口从最小化恢复为普通窗口windowIconified(WindowEvente)窗口变为最小化图标windowOpened(WindowEvente)当窗口第一次打开成为可见时接口适配器 WindowAdapter注册事件方法addWindowListener,FocusEvent事件,引发原因:组件获得焦点组件失去焦点事件监听接口 FocusListener接口方法:focusGained(FocusEvent e)组件获得焦点时调用focusLost(FocusEvente)组件失去焦点时调用接口适配器:FocusAdapter组件注册该事件方法:addFocusListener,TextEvent事件,引发原因:当组件(如文本框)文本改变时引发事件监听接口:TextListener接口方法:textValueChanged(TextEvente)组件注册该事件方法:addTextListener,ComponentEvent 事件,引发原因:当组件移动、改变大小、改变可见性时引发事件监听接口:ComponentListener接口方法:componentHidden(ComponentEvent e)组件隐藏componentMoved(ComponentEvente)组件移动componentResized(ComponentEvente)组件改变大小componentShown(ComponentEvente)组件变为可见接口适配器 ComponentAdapter组件注册该事件方法:addComponentListener,ContainerEvent 事件,引发原因:当容器内增加或移走组件时引发事件监听接口:ContainerListener接口方法componentAdded(ContainerEvente)容器内加入组件componentRemoved(ContainerEvente)从容器中移走组件接口适配器 ContainerAdapter容器注册该事件方法:addContainerListener,标准组件简介,Label(标签)构造函数Label a=new Label(“information”);Label a=new Label(“information”,Label.CENTER);方法a.setText(“新内容”);设置标签内容String a.getText()读取标签内容Button(按钮)Button myB=new Button(“Cancel”);,Checkbox组件,构造函数Checkbox(Stringlabel)Checkbox(Stringlabel,booleanstate)Checkbox(Stringlabel,booleanstate,CheckboxGroupgroup)方法:boolean getState()setState(booleanstate),CheckboxGroup组件,将一组Checkbox 按扭组成单选按扭组件。例setLayout(new GridLayout(3,1);CheckboxGroup cbg=new CheckboxGroup();Checkbox ck1=new Checkbox(“one”,true,cbg);Checkbox ck2=new Checkbox(“two”,false,cbg);Checkbox ck3=new Checkbox(“three”,false,cbg);方法:Checkbox getSelectedCheckbox()setSelectedCheckbox(Checkboxbox),TextField行编辑框组件,构造函数TextField f1=new TextField(30);TextField f1=new TextField(“abc”,30);建30个字符宽的行编辑框方法:String getText()读文本框内容 setText(“abc”)设置编辑框内容 setEchoChar(charc)设置回显字符TextComponent 方法:setEditable(false);selectAll(),7-7 计算器,TextArea编辑框组件,构造函数TextArea ta1=new TestArea(10,45);建10行、45列的文本区域TextArea ta1=new TestArea(“abc”,10,45);TextArea ta1=new TestArea(“abc”,10,45,滚动条);滚动条指定SCROLLBARS_BOTH SCROLLBARS_HORIZONTAL_ONLYSCROLLBARS_VERTICAL_ONLYSCROLLBARS_NONE方法append(Stringstr)追加文本,List 列表框,首先创建List对象,再调用add()方法加入List列表的各选项构造函数List(introws,booleanmultipleMode)rows 显示行数;multipleMode 是否允许多选方法:list1.add(“class A”);list1.add(“class B”);list1.add(“class C”,0);指定加入选项位置,List 列表框,方法int getSelectedIndex()取被选项索引int getSelectedIndexes()取被选项索引(多选)String getSelectedItem()取被选项String getSelectedItems()取被选项(多选)void select(intindex)选中指定的项String getItem(intindex)按索引号取出该项int getItemCount()取出项数String getItems()取出所有的项,Choice下拉选单,例 Choice ColorChooser=new Choice();ColorChooser.add(Green);ColorChooser.add(Red);ColorChooser.add(Blue);String getSelectedItem(),Scrollbar 滚动条,构造函数mySlider=new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,Integer.MAX_VALUE);滚动条方向滑块初始位置滑块尺寸滚动槽最小值滚动槽最大值方法int getValue()返回滑块当前位置setUnitIncrement(1);设置单位增量(点按两端箭头)setBlockIncrement(50);设置块增量(点按滚动槽),7-8 滚动条,菜单,创建菜单条(MenuBar)MenuBar m_MenuBar=new MenuBar();创建菜单(Menu),加入菜单条Menu menuFile=new Menu(“File”);/创建菜单m_MenuBar.add(menuFile);/将菜单加入菜单条创建菜单项(MenuItem)加入相应菜单MenuItem f1=new MenuItem(“Open”),/创建各菜单项MenuItem f2=new MenuItem(Close),menuFile.add(f1);/加入菜单menuFile.add(f2);将菜单条放入frame:myFrame.setMenuBar(m_MenuBar);编写响应菜单操作的代码(ActionEvent),7-9 菜单,文件对话框,FileDialog(Frameparent,Stringtitle,intmode)parent 对话框所属窗体 title 对话框标题 mode 对话框模式 FileDialog.LOAD 打开文件 FileDialog.SAVE 保存文件,文件对话框,class MyFrame extends Frame MyFrame getMyFrameIns()return this;子类方法代码片段:FileDialog f=new FileDialog(getMyFrameIns(),open,FileDialog.SAVE);f.setVisible(true);String fname=f.getDirectory()+f.getFile();ig=getToolkit().getImage(fname);,绘制用户自定义成分,一般在容器中(窗口)或画布上绘制。利用Java.awt类库中的类及其方法绘制用户自定义的图形界面成分。Graphics类包含很多绘制图形和文字的方法。首先要获得Graphics类的实例,然后利用其方法绘制。Graphics类的实例一般作为相关方法的参数传递进来:paint(Graphics g)坐标规定,paint和repaint 方法,某组件的paint()和 update()为系统自动调用的有关图形绘制的方法,不可人为编程调用;但可编程重新定义其操作内容使用repaint()方法可以触发update()方法,Graphics的方法,drawLine(x1,y1,x2,y2)/直线drawRect(x,y,w,h)/矩形drawOval(x,y,w,h)/圆或椭圆fillOval(x,y,w,h)/实心圆或椭圆drawPolygon(X坐标数组,Y坐标数组,个数)/画多边形drawArc(x,y,w,h,开始角度,弧度角度)setColor(Color c)/置颜色setFont(Font f)/置字体getColor()getFont(),7-10,Graphics的方法,DrawImage(Image img,int x,int y,this)显示图像的方法第一个参数是保存图像数据的Image对象。第二、三个参数是图像的左上角坐标,它们决定了图像在容器中的显示位置。最后一个参数是显示图像的容器对象。static Toolkit getToolkit()getTookit().getImage(文件名),7-11 动画,图象显示方法,读取图片显示图片在application中使用ToolKit类的getImage方法取得图片:Image ig=getToolkit().getImage(“文件名”);然后用Graphics类的drowImage方法显示Image对象。在applet小程序中,可使用Applet类的getImage方法获得图象。Image ig=getImage(),综合题,7-2 综合,