1、案例7:使用Swing实现学生成绩查询系统基本功能,包括用户登录、教师成绩输入与统计和学生成绩查询 。,浙江工业大学 计算机学院 赵小敏 ,涉及知识点,1、容器组件 2、基本组件 3、布局管理器 4、事件处理模型 5、高级图像用户界面,7.1 容器组件,JFrame JPanel JScrollPane,1、JFrame(框架),类 JFrame 是java.awt.Frame的子类 在Swing的组件中, JFrame 并不全是由Java编写的 是一种与平台关系比较密切的组件(Heavyweight component) java.lang.Object|+-java.awt.Compone
2、nt|+-java.awt.Container|+-java.awt.Window|+-java.awt.Frame|+-javax.swing.JFrame,例1:基于AWT实现的框架界面,import java.awt.*; public class FrameDemoFrame f;Button b;public FrameDemo()f=new Frame(“Frame Demo“);b=new Button(“Press me“);f.add(b);f.setSize(200,200);f.setVisible(true);public static void main(String
3、 args)new FrameDemo(); ,例2:基于Swing实现的框架界面,import java.awt.*; import javax.swing.*; public class JFrameDemoJFrame f;JButton b;Container c;public JFrameDemo()f=new JFrame(“JFrame Demo“);b=new JButton(“Press me“);c=f.getContentPane();c.add(b); f.setSize(200,200);f.setVisible(true);public static void ma
4、in(String args)new JFrameDemo(); ,在JFrame中加入组件的方法,1) 用getContentPane( )方法获得JFrame的内容面板,再对其加入组件:Container c=frame.getContentPane()c.add(childComponent)2) 建立一个JPanel或 JDesktopPane之类的中间容器,把组件添加到容器中,用setContentPane()方法把该容器置为JFrame的内容面板: JPanel contentPane=new JPanel( ); /把其它组件添加到Jpanel中; frame.setConten
5、tPane(contentPane); /把contentPane对象设置成为frame的内容面板,2、JPanel(面板),一种中间容器,用来组成其它组件 可以添加各种组件(包括面板组件) 面板(JPanel)的大小由它所包含的组件决定 当组件个数增加,面板(JPanel)也会随之而增大,例3:利用JPanel创建界面,import java.awt.*; import javax.swing.*; public class JPanelDemo extends JFramepublic JPanel getGUI()JPanel p=new JPanel();p.add(new JButt
6、on(“Press me“);return p;public JPanelDemo()super(“JPanel Demo“);setContentPane(getGUI();setSize(200,200);setVisible(true);public static void main(String args)new JPanelDemo(); ,import java.awt.*; import javax.swing.*; public class JPanelDemo extends JFramepublic JPanel getGUI()JPanel p=new JPanel();
7、p.add(new JButton(“Press me“);return p; public static void main(String args)JPanelDemo jp=new JPanelDemo();jp.setTitle(“JPanel Demo“);jp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jp.setContentPane(jp.getGUI();jp.setSize(200,200);jp.setVisible(true); ,3、Swing的组件,在javax.swing包中,定义了两种类型的组件:容器和组件。
8、容器 各种组件必须放在容器 容器本身也是一种组件 分类 顶层容器,如JFrame,JApplet,JDialog和JWindow 其它容器,如JPanel,JScrollPane,JSplitPane,JToolBar 组件 基本控制组件,如JButton, JComboBox, JList, JMenu, JSlider, JTextField 不可编辑的信息显示组件,如JLabel, JProgressBar, JToolTip 可编辑的信息显示组件,如JColorChooser, JFileChooser, JTable, JTextArea,4、Swing的类层次结构,Swing的类层
9、次结构java.awt.Component |java.awt.Container java.awt.Window java.awt.Frame javax.swing.JFrame javax.Dialog javax.swing.JDialog javax.swing.JWindow java.awt.Applet-javax.swing.JApplet javax.swing.Box javax.swing.JComponet,7.2基本组件,标签(JLabel) 文本框(JTextField) 按钮(JButton) 组合框(JComboBox) 文本(JTextArea) 列表JLi
10、st(单选列表和多选列表),1、标签(JLabel),标签 为GUI提供文本(主要)或图像(也可以)信息 对应类(JLabel) (JComponent的子类) 可以显示: 单行的只读的文本信息 图像 同时显示文本与图像信息 程序一般不修改标签的内容,例4:JLabel的演示例子,import java.awt.Container; import java.awt.FlowLayout; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel;public class JLabelDe
11、mo extends JFramepublic JLabelDemo( )super( “框架和标签例程“ );String s = “文本标签“, “文字在图标的左侧“, “文字在图标的下方“;ImageIcon ic = null, new ImageIcon( “img1.gif“ ),new ImageIcon( “img2.gif“ );int ih = 0, JLabel.LEFT, JLabel.CENTER;int iv = 0, JLabel.CENTER, JLabel.BOTTOM;Container c = getContentPane( );c.setLayout(
12、new FlowLayout(FlowLayout.LEFT) );,例4:JLabel的演示例子(续),for (int i=0; i0)aLabel.setHorizontalTextPosition(ihi);aLabel.setVerticalTextPosition(ivi); aLabel.setToolTipText( “第“ + (i+1) + “个标签“);c.add( aLabel ); public static void main(String args )JLabelDemo app = new JLabelDemo( );app.setDefaultCloseOpe
13、ration(JFrame.EXIT_ON_CLOSE);app.setSize( 360, 150 );app.setVisible( true ); ,2、文本框(JTextField),显示单行的文本信息 JTextField extends JTextComponent 密码输入框JPasswordField,例5:JTextField的演示例子,import java.awt.Container; import java.awt.FlowLayout; import javax.swing.JFrame; import javax.swing.JPasswordField; impo
14、rt javax.swing.JTextField;public class JTextFieldDemopublic static void main(String args )JFrame app = new JFrame( “文本编辑框例程“ );app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);app.setSize( 320, 120 );Container c = app.getContentPane( );c.setLayout( new FlowLayout( ) );JTextField t = new JTextField
15、(“正常文本:“, 8), new JTextField(“显示“, 15),new JTextField(“密码文本:“, 8), new JPasswordField(“隐藏“, 15);t0.setEditable( false );t2.setEditable( false );for (int i=0; i4; i+)c.add( ti );app.setVisible( true ); ,3、按钮(JButton),当鼠标左键单击按钮组件时,能触发特定的事件 在Java中, 广义的按钮包括: 命令式按钮(JButton) 复选框(JCheckBox) 单选按钮(JRadioButt
16、on),按钮类的层次结构,Container c = getContentPane( );c.setLayout( new FlowLayout( ) );int i;ImageIcon ic = new ImageIcon(“left.gif“),new ImageIcon(“right.gif“);JButton b = new JButton(“左“, ic0), new JButton(“中间“),new JButton(“右“, ic1);for (i=0; i b.length; i+)c.add( bi );JCheckBox ck = new JCheckBox(“左“), n
17、ew JCheckBox(“右“);for (i=0; ick.length; i+)c.add( cki );cki.setSelected(true); JRadioButton r=new JRadioButton(“左“), new JRadioButton(“右“);ButtonGroup rg = new ButtonGroup( );for (i=0; i r.length; i+)c.add( ri );rg.add( ri ); r0.setSelected(true);r1.setSelected(false);,4、组合框(JComboBox),组合框(JComboBox
18、) 可以从下拉式的列表框中选取其中的列表项 有时也称为下拉框(drop-down list) 类JComboBox中的方法 getSelectedIndex( ) 返回当前被选中的项 setMaximumRowCount( n ) 设置最多显示列表项的项数 滚动条(Scrollbar)会自动加上,5、文本(JTextArea),JTextArea 是一个显示纯文本的多行区域。 JTextArea 不管理滚动,可把它放置在 JScrollPane 的ViewPort中实现滚动,如:JTextArea textArea = new JTextArea();JScrollPane area=new
19、JScrollPane(textArea);TextArea 具有换行能力,JTextArea默认为不换行,需设置换行策略,如: textArea.setLineWrap(true);textArea.setWrapStyleWord(true);,JTextArea的代码段, /建立容纳文本区的面板JPanel textPanel = new JPanel();/新建无回绕的文本区,行数为5,列数为20noWrapArea = new JTextArea(“nowrap“, 5, 20);/新建有回绕的文本区,行数为5,列数为20wrapArea = new JTextArea(“wrapa
20、rea“, 5, 20);wrapArea.setLineWrap(true);/新建带滚动条的文本区,行数为5,列数为20scrollArea = new JTextArea(“scrollarea“, 5, 20);/将文本区插入到滚动窗格中JScrollPane scrollPane = new JScrollPane(scrollArea);textPanel.add(noWrapArea);textPanel.add(wrapArea);/将滚动窗格加入到框架中textPanel.add(scrollPane);,6、列表JList,JList显示出一系列选项,用户可以从中选择一个或
21、多项。 String colorNames = “Black”, “Blue”, “Cyan”, “Dark Gray”, “Gray“; colorList = new JList( colorNames ); colorList.setVisibleRowCount( 5 ); colorList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION );colorList.getSelectedIndex() ; colorList.getSelectedValue() ;,多选列表,在JList中选择多个选项,方法是按住shift键或
22、ctrl键。 多选列表没有和多个选择相关的事件。通常由另一个GUI组件生成的事件(外部事件)来指定处理JList中的多个选择。,多选列表的使用方法,String colorNames = “Black”, “Blue”, “Cyan”, “Dark Gray”, “Gray“; JList colorList = new JList( colorNames ); colorList.setVisibleRowCount( 5 );colorList.setFixedCellHeight( 15 ); colorList.setSelectionMode(ListSelectionModel.M
23、ULTIPLE_INTERVAL_SELECTION ); colorList.getSelectedValues(),7.3布局管理器,用来控制组件在容器中的布局方式 应当尽量利用已有的基本布局方式 布局管理器处理组件布局的大部分细节,布局管理器,流式布局FlowLayout 边界布局BorderLayout 盒式布局管理器BoxLayout 网格布局GridLayout 卡片布局CardLayout,1、流式布局FlowLayout,是一种最基本的布局管理器 是 java.awt.Applet、java.awt.Panel 和 javax.swing.JPanel的默认布局方式 在容器中,
24、从左到右依次放置GUI组件 当组件排到容器一行的末尾时,则从下一行开始接着排列组件 每行组件的对齐方式可以是: 左对齐、中间(默认对齐方式)和右对齐,FlowLayout的构造方法,public FlowLayout() public FlowLayout(int alignment) public FlowLayout(int alignment,int horizontalGap,int verticalGap)alignment参数的值必须是FlowLayout.LEFT、 Flowlayout.CENTER或FlowLayout.RIGHT。horizontalGap和vertical
25、Gap参数指定了组件间隔距离(以像素为单位)。 FlowLayout的默认间隔值为5。,例6:FlowLayout的使用方法,import java.awt.*; import javax.swing.*; public class FlowLayoutDemo extends JFrame public FlowLayoutDemo() Container c=getContentPane();c.setLayout(new FlowLayout();c.add(new JLabel(“Buttons:“);c.add(new JButton(“Button 1“);c.add(new JB
26、utton(“2“);c.add(new JButton(“Button 3“);c.add(new JButton(“Long-Named Button 4“);c.add(new JButton(“Button 5“); public static void main(String args) FlowLayoutDemo window = new FlowLayoutDemo();window.setTitle(“FlowLayout Demo“);window.pack();/窗口大小设置为适合组件最佳尺寸与布局所需的空间window.setVisible(true); ,2、边界布局
27、BorderLayout,是容器JFrame和JApplet的默认布局方式 将容器分成五个区域, NORTH (顶部) SOUTH (底部) WEST (左侧) EAST (右侧) CENTER (中间) 每个区域最多只能1个组件,BorderLayout的方法,构造方法: BorderLayout() 构造一个组件之间没有间距的新边界布局。 BorderLayout(int hgap, int vgap) 用指定的组件之间的水平间距构造一个边界布局。将组件添加到BorderLayout布局的容器中的方法 add(new Button(“ South “), BorderLayout.SOUT
28、H); add(new Button(“South“),“South“); add(“South“,new Button(“South“);,例7: BorderLayout的使用方法,import java.awt.*; import javax.swing.*; public class BorderLayoutDemo extends JFrame public BorderLayoutDemo() Container c=getContentPane();c.setLayout(new BorderLayout(5,5); c.add(new JButton(“North“), “No
29、rth“); c.add( new JButton(“South“),“South“);/c.add(“South“,new Button(“South“);/c.add(new Button(“ South “), BorderLayout.SOUTH); c.add( new JButton(“East“),“East“);c.add( new JButton(“West“),“West“);c.add( new JButton(“Center“),“Center“);public static void main(String args) BorderLayoutDemo window
30、= new BorderLayoutDemo(); window.setTitle(“BorderLayout Demo“);window.pack();window.setVisible(true); ,3、盒式布局管理器BoxLayout,允许多个组件在容器中沿水平方向或竖直方向排列 容器的大小发生变化时,组件占用的空间不会发生变化,BoxLayout的方法,构造方法:BoxLayout(Container target, int axis) 创建一个将沿给定轴放置组件的布局管理器。轴的方向:BoxLayout.X_AXIS:指定组件应该从左到右放置BoxLayout.Y_AXIS:指定组
31、件应该从上到下放置,例8: BoxLayout使用的例子,import java.awt.Container; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; public class BoxLayoutDemopublic static void main(String args )JFrame app = new JFrame( “盒式布局管理器例程“ );app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);app.se
32、tSize( 220, 130 );Container c = app.getContentPane( );c.setLayout( new BoxLayout( c, BoxLayout.X_AXIS ) );String s;JButton b;for (int i=0; i3; i+)s = “按钮“ + (i+1);b = new JButton( s );c.add( b ); app.setVisible( true ); ,4、网格布局GridLayout,布局管理器GridLayout按行与列将容器等分成网格 每个组件占用具有相同宽度和高度的网格 添加组件占用网格的顺序: 从上
33、到下,从左到右 当一行满了,则继续到下一行,仍然是从左到右,GridLayout类的构造方法,GridLayout() 创建默认值的网格布局,即每个组件占据一行一列。GridLayout(int rows, int cols) 创建具有指定行数和列数的网格布局GridLayout(int rows, int cols, int hgap, int vgap) 创建具有指定行数和列数的网格布局。,例9: GridLayout的使用方法,import java.awt.*; import javax.swing.*; public class GridLayoutDemo JFrame f;pub
34、lic GridLayoutDemo(String str)f=new JFrame(str);Container c=f.getContentPane();c.setLayout(new GridLayout(3,2);for(int i=1;i=6;i+)c.add(new JButton(i+“);f.pack( ) ;f.setVisible(true);public static void main(String args)new GridLayoutDemo(“GridLayout Demo“); ,5、卡片布局管理器CardLayout,CardLayout的布局方式有点象码“扑
35、克牌” 一个组件压在另一个组件的上面,所以每次一般只能看到一个组件,布局管理器嵌套,实际上是容器的嵌套,被嵌套的容器可以具有不同的布局管理器 在嵌套的布局管理器中 JPanel 通常起到了 “桥”的作用,例10:复杂GUI的布局,例10:实现GUI的步骤分析,GUI的设计步骤,先设计一个窗口,如JFrame 确定布局管理器 在窗口中添加所需组件 增加事件处理,7.4事件处理模型,GUI是由事件(event)驱动的 当用户与GUI交互可以产生事件(events) 一些常见的交互方式 移动鼠标 用鼠标点击按钮 在文本框中输入数据 关闭窗口等,事件处理机制,主要涉及三种对象 事件源(An event
36、 source) 事件对象(An event object) 事件监听器(event listener(s),事件处理机制,事件源 可供用户进行交互的GUI组件 事件对象 封装了包含所发生的各种事件的有效信息 信息包括: 事件源的引用、以及事件监听器在处理事件时所需要的其它各种信息 事件信息被包含在类AWTEvent或其子类的实例对象中 事件监听器 接受事件对象,并处理事件对象,事件处理机制,包含事件处理的程序应该包括以下四部分内容: 1、引入系统事件类包,如import java.awt.event.*。 2、在事件处理类的声明中指定要实现的监听器名,如:public class MyCla
37、ss implements ActionListener 3、注册事件源对象的事件监听者,如btn.addActionListener (this)。 4、实现监听器中的接口如实现按钮事件监听接口ActionListener :public void actionPerformed(ActionEvent e) ./响应某个动作的代码. ,事件分类与监听器接口,1、事件分类,java.util.EventObject,Java.awt.AWTEvent,ActionEvent AdjustmentEvent ComponentEvent ItemEvent TextEvent,Containe
38、rEvent FocusEvent WindowEvent PaintEvent InputEvent,MouseEvent,KeyEvent,2、监听器接口,对于每种类型的事件,都定义了相应的事件处理接口; XXXEvent对应的事件处理接口通常为XXXListener。,java.util.EventListener,ActionListener ItemListener WindowListener KeyListener MouseListener MouseMotionListener ,事件接口及处理方法,事件接口及处理方法(续),例11:按钮事件的示例(方法1),import j
39、ava.awt.*; import java.awt.event.* ; import javax.swing.*; public class TestJButton implements ActionListenerpublic TestJButton()JFrame f = new JFrame(“Test Button Event!“);Container c=f.getContentPane();JButton b = new JButton(“Press Me!“); b.addActionListener(this);c.add(b, “Center“);f.setSize(200
40、,100);f.setVisible(true);public void actionPerformed(ActionEvent e)System.out.println(“Action occurred“);System.out.println(“Buttons label is:“+e.getActionCommand();public static void main(String args )new TestJButton(); ,方法1:采用同一个类中实现事件接口的方法,例:按钮事件的示例(方法2),import java.awt.*; import java.awt.event.*
41、 ; import javax.swing.*; public class TestJButtonDemopublic TestJButtonDemo()JFrame f = new JFrame(“Test Button Event!“);Container c=f.getContentPane();JButton b = new JButton(“Press Me!“); b.addActionListener(new ButtonHandler();c.add(b, “Center“);f.setSize(200,100);f.setVisible(true);public static
42、 void main(String args )new TestJButtonDemo(); ,例11:按钮事件的示例(方法2),import java.awt.event.*; public class ButtonHandler implements ActionListener public void actionPerformed(ActionEvent e)System.out.println(“Action occurred“);System.out.println(“Buttons label is:“+e.getActionCommand(); ,方法2:采用另一个类中实现事件
43、接口的方法,例11:按钮事件的示例(方法3),import java.awt.*; import java.awt.event.* ; import javax.swing.*; public class TestInnerButtonDemopublic TestInnerButtonDemo()JFrame f = new JFrame(“Test Button Event!“);Container c=f.getContentPane();JButton b = new JButton(“Press Me!“); b.addActionListener(new ActionListene
44、r()public void actionPerformed(ActionEvent e)System.out.println(“Action occurred“);System.out.println(“Buttons label is:“+ e.getActionCommand(););c.add(b, “Center“);f.setSize(200,100);f.setVisible(true);public static void main(String args )new TestInnerButtonDemo(); ,方法3:采用匿名内部类实现事件接口的方法,如何监听多个组件事件?
45、,例12:编写一个允许学生在文本字段中输入一个数的程序。创建一个每当用户单击一次就将此数加一的按钮。创建另一个每当用户单击一次就将此数减一的按钮。 界面效果如下图所示。,import java.awt.*; import java.awt.event.*; import javax.swing.*; class Incrementor implements ActionListenerJTextField numberTxf;JButton incrementBtn,decrementBtn;public void makeGUI()JFrame frm = new JFrame(“Incre
46、mentor“);Container c=frm.getContentPane();c.setLayout(new FlowLayout();numberTxf = new JTextField(“0“,5);c.add(numberTxf);incrementBtn = new JButton(“Increment“);c.add(incrementBtn);incrementBtn.addActionListener(this);decrementBtn= new JButton(“Decrement“);c.add(decrementBtn);decrementBtn.addAction
47、Listener(this);frm.setSize(300,100);frm.setVisible(true);,public void actionPerformed(ActionEvent e) int oldNum = Integer.parseInt(numberTxf.getText();int newNum = oldNum;if (e.getActionCommand().equals(“Increment“)newNum+;else if (e.getActionCommand().equals(“Decrement“) newNum-;numberTxf.setText(S
48、tring.valueOf(newNum);public static void main(String args) Incrementor i = new Incrementor();i.makeGUI();,if(e.getSource()=incrementBtn),else if(e.getSource()=decrementBtn),选项事件ItemEvent的处理,可触发选项事件的组件有:JCheckBox,JRadioButton,JComboBox注册事件的方法:public void addItemListener(ItemListener e)处理事件的接口ItemList
49、ener,仅含有方法:public void itemStateChanged(ItemEvent e),例:选项事件ItemEvent的处理例子,用JComboBox和JCheckBox来演示可选项目事件接口,界面如下图所示:,import java.awt.*; import java.awt.event.* ; import javax.swing.*; public class ItemDemo implements ItemListenerJFrame f;JPanel p1,p2,p3;JLabel birthPlace,hobby;JComboBox place;JCheckBo
50、x hobby1,hobby2,hobby3;public ItemDemo(String title)f=new JFrame(title);p1=new JPanel();birthPlace=new JLabel(“出生地:“);place=new JComboBox();place.addItemListener(this);place.addItem(“杭州“);place.addItem(“宁波“);place.addItem(“温州“);place.addItem(“绍兴“);p1.add(birthPlace);p1.add(place);f.add(p1,“North“);,