zoukankan      html  css  js  c++  java
  • 冯志霞201771010107《面向对象程序设计(java)》第十三周学习

    实验十三  图形界面事件处理技术

    实验时间 2018-11-22

    1、实验目的与要求

    (1) 掌握事件处理的基本原理,理解其用途;

    (2) 掌握AWT事件模型的工作机制;

    (3) 掌握事件处理的基本编程模型;

    (4) 了解GUI界面组件观感设置方法;

    (5) 掌握WindowAdapter类、AbstractAction类的用法;

    (6) 掌握GUI程序中鼠标事件处理技术。

    2、实验内容和步骤

    实验1: 导入第11章示例程序,测试程序并进行代码注释。

    测试程序1:

    l  在elipse IDE中调试运行教材443页-444页程序11-1,结合程序运行结果理解程序;

    l  在事件处理相关代码处添加注释;

    l  用lambda表达式简化程序;

    l  掌握JButton组件的基本API;

    l  掌握Java中事件处理的基本编程模型。

    package button;
    
    import java.awt.*;
    import javax.swing.*;
    
    /**
     * @version 1.34 2015-06-12
     * @author Cay Horstmann
     */
    public class ButtonTest
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             JFrame frame = new ButtonFrame();
             frame.setTitle("ButtonTest");
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }
    

      

    package button;
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class ButtonFrame extends JFrame {
    	private JPanel buttonPanel;// buttonPanel内容窗格对象
    	private static final int DEFAULT_WIDTH = 300;
    	private static final int DEFAULT_HEIGHT = 200;
    
    	public ButtonFrame() {
    		setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);// 用于显示窗格大小
    
    		// 创建按钮对象
    		/*JButton yellowButton = new JButton("Yellow");// 带有string参数显示text文本
    		JButton blueButton = new JButton("Blue");
    		JButton redButton = new JButton("Red");
    		JButton GreenButton = new JButton("Greeen");*/
    		// 必须要放在容器中
    		buttonPanel = new JPanel();
    
    		/*
    		 * // 将按钮组件添加到面板,,,只有容器组件有ADD方法 buttonPanel.add(yellowButton);
    		 * buttonPanel.add(blueButton); buttonPanel.add(redButton);
    		 */
    		// add panel to frame
    		add(buttonPanel);
    
    		/*
    		 * create button actions ColorAction yellowAction = new
    		 * ColorAction(Color.gray);//类名调用Color.gray ColorAction blueAction = new
    		 * ColorAction(Color.BLUE); ColorAction redAction = new
    		 * ColorAction(Color.RED);//3监听器
    		 * 
    		 * // associate actions with buttons
    		 * yellowButton.addActionListener(yellowAction);//zhucejizhi
    		 * blueButton.addActionListener(blueAction);//注册监听器类对象的为事件源
    		 * redButton.addActionListener(redAction);
    		 */
    
    		makeButton("yellow", Color.YELLOW);
    		makeButton("Blue", Color.BLUE);
    		makeButton("Red", Color.RED);
    		makeButton("Green", Color.green);
    
    	}
    
    	public void makeButton(String name, Color backgroundColor) {
    		JButton button = new JButton(name);
    		buttonPanel.add(button);
    		//ColorAction action = new ColorAction(backgroundColor);
    		//button.addActionListener(action);
    		button.addActionListener((e)->          //匿名内部类不需要定义监听器类
    				{
    
    					
    						buttonPanel.setBackground(backgroundColor);
    				
    
    	});
    	}
    
    	/**
    	 * An action listener that sets the panel's background color.
    	 */
    	/*private abstract class ColorAction implements ActionListener// 自定义类实现监听器接口才可以创建见监听器对象,此为监听器类coloraction
    	{
    		private Color backgroundColor;
    
    		public ColorAction(Color c) {
    			backgroundColor = c;
    		}
    
    		public void actionPerformed(ActionEvent event)// 实现响应
    		{
    			buttonPanel.setBackground(backgroundColor);
    		}
    	}*/
    }
    

      

    测试程序2:

    l  在elipse IDE中调试运行教材449页程序11-2,结合程序运行结果理解程序;

    l  在组件观感设置代码处添加注释;

    l  了解GUI程序中观感的设置方法。

    package plaf;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import javax.swing.UIManager;
    
    /**
     * A frame with a button panel for changing look-and-feel
     */
    public class PlafFrame extends JFrame
    {
       private JPanel buttonPanel;
    
       public PlafFrame()
       {
          buttonPanel = new JPanel();
    
          UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();
          for (UIManager.LookAndFeelInfo info : infos)
             makeButton(info.getName(), info.getClassName());
    
          add(buttonPanel);
          pack();
       }
    
       
       private void makeButton(String name, String className)
       {
          //将按钮添加到面板中
    
          JButton button = new JButton(name);
          buttonPanel.add(button);
    
          // 通过监听器对象给按钮添加动作事件
    
          button.addActionListener(event -> {
             // button action: switch to the new look-and-feel
             try
             {
                UIManager.setLookAndFeel(className);
                SwingUtilities.updateComponentTreeUI(this);
                pack();
             }
             catch (Exception e)
             {
                e.printStackTrace();
             }
          });
       }
    }
    

      

    package plaf;
    
    import java.awt.*;
    import javax.swing.*;
    
    /**
     * @version 1.32 2015-06-12
     * @author Cay Horstmann
     */
    public class PlafTest
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             JFrame frame = new PlafFrame();
             frame.setTitle("PlafTest");
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }
    

      

                                      

    测试程序3:

    l  在elipse IDE中调试运行教材457页-458页程序11-3,结合程序运行结果理解程序;

    l  掌握AbstractAction类及其动作对象;

    l  掌握GUI程序中按钮、键盘动作映射到动作对象的方法。

    package action;
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    /**
     * A frame with a panel that demonstrates color change actions.
     */
    public class ActionFrame extends JFrame
    {
       private JPanel buttonPanel;
       private static final int DEFAULT_WIDTH = 300;
       private static final int DEFAULT_HEIGHT = 200;
    
       public ActionFrame()
       {
          setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    
          buttonPanel = new JPanel();
    
          // define actions
          Action yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"),//设置图标
                Color.YELLOW);
          Action blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE);
          Action redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED);
    
          // add buttons for these actions
          buttonPanel.add(new JButton(yellowAction));//将按钮添加到面板
          buttonPanel.add(new JButton(blueAction));
          buttonPanel.add(new JButton(redAction));
    
          // add panel to frame
          add(buttonPanel);//将面板加到容器中
    
          // associate the Y, B, and R keys with names
          InputMap imap = buttonPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);//InputMap 提供输入事件(目前只使用 KeyStroke)和 Object 之间的绑定。InputMap 通常与 ActionMap 一起使用,以确定按下键时执行一个 Action
          imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
          imap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue");
          imap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red");
    
          // associate the names with actions
          ActionMap amap = buttonPanel.getActionMap();//ActionMap 提供从 Object(称为键 或 Action 名)到 Action 的映射。当按下某一个键时,ActionMap 通常与 InputMap 一起使用来定位特定操作
          amap.put("panel.yellow", yellowAction);
          amap.put("panel.blue", blueAction);
          amap.put("panel.red", redAction);
       }
       
       public class ColorAction extends AbstractAction
       {
          
          public ColorAction(String name, Icon icon, Color c)
          {
        	  //putValue设置与指定键关联的 Value。指定者:接口 Action 中的 putValue 
    
             putValue(Action.NAME, name);
             putValue(Action.SMALL_ICON, icon);
             putValue(Action.SHORT_DESCRIPTION, "Set panel color to " + name.toLowerCase());//将此 String 中的所有字符都转换为小写
             putValue("color", c);
          }
    
          public void actionPerformed(ActionEvent event)
          {
             Color c = (Color) getValue("color");
             buttonPanel.setBackground(c);
          }
       }
    }
    

      

    package action;
    
    import java.awt.*;
    import javax.swing.*;
    
    /**
     * @version 1.34 2015-06-12
     * @author Cay Horstmann
     */
    public class ActionTest
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             JFrame frame = new ActionFrame();
             frame.setTitle("ActionTest");
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }
    

      

    测试程序4:

    l  在elipse IDE中调试运行教材462页程序11-4、11-5,结合程序运行结果理解程序;

    l  掌握GUI程序中鼠标事件处理技术。

    package mouse;
    
    import java.awt.*;
    import java.awt.event.*;
    import java.awt.geom.*;
    import java.util.*;
    import javax.swing.*;
    
    /**
     * A component with mouse operations for adding and removing squares.
     */
    public class MouseComponent extends JComponent
    {
       private static final int DEFAULT_WIDTH = 300;
       private static final int DEFAULT_HEIGHT = 200;
    
       private static final int SIDELENGTH = 10;
       private ArrayList<Rectangle2D> squares;
       private Rectangle2D current; // the square containing the mouse cursor
    
       public MouseComponent()
       {
          squares = new ArrayList<>();
          current = null;
    
          addMouseListener(new MouseHandler());//添加指定的鼠标侦听器,以接收发自此组件的鼠标事件。如果侦听器 l 为 null,则不会抛出异常并且不执行动作。 
          addMouseMotionListener(new MouseMotionHandler());
       }
    
       public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } //如果 preferredSize 已设置为一个非 null 值,则返回该值  
       
       public void paintComponent(Graphics g)
       {
          Graphics2D g2 = (Graphics2D) g;
    
          // draw all squares
          for (Rectangle2D r : squares)
             g2.draw(r);
       }
    
       /**
        * Finds the first square containing a point.
        * @param p a point
        * @return the first square that contains p
        */
       public Rectangle2D find(Point2D p)
       {
          for (Rectangle2D r : squares)
          {
             if (r.contains(p)) return r;
          }
          return null;
       }
    
       /**
        * Adds a square to the collection.
        * @param p the center of the square
        */
       public void add(Point2D p)
       {
          double x = p.getX();
          double y = p.getY();
    
          current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH,
                SIDELENGTH);
          squares.add(current);
          repaint();//重绘此组件。 
       }
    
       /**
        * Removes a square from the collection.
        * @param s the square to remove
        */
       public void remove(Rectangle2D s)
       {
          if (s == null) return;
          if (s == current) current = null;
          squares.remove(s);
          repaint();
       }
    
       private class MouseHandler extends MouseAdapter//接收鼠标事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象。
       {
          public void mousePressed(MouseEvent event)
          {
             // add a new square if the cursor isn't inside a square
             current = find(event.getPoint());
             if (current == null) add(event.getPoint());
          }
    
          public void mouseClicked(MouseEvent event)
          {
             // remove the current square if double clicked
             current = find(event.getPoint());
             if (current != null && event.getClickCount() >= 2) remove(current);
          }
       }
    
       private class MouseMotionHandler implements MouseMotionListener
       {
          public void mouseMoved(MouseEvent event)
          {
             // set the mouse cursor to cross hairs if it is inside
             // a rectangle
    
             if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor());
             else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
          }
    
          public void mouseDragged(MouseEvent event)
          {
             if (current != null)
             {
                int x = event.getX();//返回事件相对于源组件的水平 x 坐标
                int y = event.getY();//返回事件相对于源组件的垂直 y 坐标。
    
                // drag the current rectangle to center it at (x, y)
                current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);//将此 Rectangle2D 外部边界的位置和大小设置为指定矩形值。
                repaint();
             }
          }
       }   
    }
    

      

    package mouse;
    
    import javax.swing.*;
    
    /**
     * A frame containing a panel for testing mouse operations
     */
    public class MouseFrame extends JFrame
    {
       public MouseFrame()
       {
          add(new MouseComponent());
          pack();
       }
    }
    

      

    package mouse;
    
    import java.awt.*;
    import javax.swing.*;
    
    /**
     * @version 1.34 2015-06-12
     * @author Cay Horstmann
     */
    public class MouseTest
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             JFrame frame = new MouseFrame();
             frame.setTitle("MouseTest");
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }
    

      

    实验2:结对编程练习

    利用班级名单文件、文本框和按钮组件,设计一个有如下界面(图1)的点名器,要求用户点击开始按钮后在文本输入框随机显示2017级网络与信息安全班同学姓名,如图2所示,点击停止按钮后,文本输入框不再变换同学姓名,此同学则是被点到的同学姓名。

     结对人:孔维滢

    import java.util.*;
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    import java.awt.Frame;
    import java.io.File;
    import java.io.FileNotFoundException;
    
    
    public class 点名器1 extends JFrame implements ActionListener{
    	private JButton but ;
    
    	private JButton show;
    	private static boolean flag = true;
    	public static void main(String arguments []) {
    		 new 点名器1();
    
    		}
    
    public  点名器1(){
    
    but = new JButton("开始");
    but.setBounds(100,150,100,40);
    
    show = new JButton("随机点名");
    show.setBounds(80,80,180,30);
    show.setFont(new Font("楷体",Font.BOLD,30));
    
    add(but);
    
    add(show);
    
    setLayout(null);//布局管理器必须先初始化为空才能赋值
    setVisible(true);
    setResizable(false);
    setBounds(100,100,300,300);
    //setBackground(Color.red);不起作用
    this.getContentPane().setBackground(Color.cyan);
    setTitle("点名");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    but.addActionListener(this);
    }
    
    	public void actionPerformed(ActionEvent e){
        	int i=0;
        	String names[]=new String[50];
        	try {
    			Scanner in=new Scanner(new File("D:\studentnamelist.txt"));
    			while(in.hasNextLine())
    			{
    				names[i]=in.nextLine();
    				i++;
    			}
    		} catch (FileNotFoundException e1) {
    			
    			e1.printStackTrace();
    		}
    
    	
        	if(but.getText()=="开始"){  	
    
    	show.setBackground(Color.BLUE);
    	flag=true;
    	new Thread(){   
            public void run(){
                while(点名器1.flag){
                Random r = new Random(); 
                int i= r.nextInt(47);
                show.setText(names[i]);
                }
            }
        }.start();
        but.setText("停止");//更改文本内容
        but.setBackground(Color.YELLOW);
    }    
    else if(but.getText()=="停止"){
        flag = false;
        but.setText("开始");
        but.setBackground(Color.WHITE);
        show.setBackground(Color.red);
    }
    	}
    
    
    
    }
    

      

     理论知识总结:①创建容器

      首先要创建一个GUI应用程序,需要创建一个用于容纳所有其它GUI组件元素的载体,Java中称为容器。典型的包括窗口(Window)、框架(Frame/JFrame)、对话框(Dialog/JDialog)、面板(Panel/JPanel)等。只有先创建了这些容器,其它界面元素如按钮(Button/JButton)、标签(Label/JLabel)、文本框(TextField/JTextField)等才有地方放。

      ②添加组件

      为了实现GUI应用程序的功能,为了与用户交换,需要在容器上添加各种组件/控件。这需要根据具体的功能要求来决定用什么组件。例如,如果需要提示信息,可用标签(Label/JLabel);如果需要输入少量文本,可用文本框(TextField/JTextField);如果需要输入较多文本,可用文本区域(TextArea/JTextArea);如果需要输入密码,可用密码域(JPasswordField)等等。

      ③安排组件
      与传统的Windows环境下的GUI软件开发工具不同,为了更好地实现跨平台,Java程序中各组件的位置、大小一般不是以绝对量来衡量,而是以相对量来衡量。例如有时候,程序的组件的位置是按"东/East"、"西/West"、"南/South"、"北/North"、"中 /Center"这种方位来标识的。因此,在组织界面时,除了要考虑所需的组件种类外,还需要考虑如何安排这些组件的位置与大小。这一般是通过设置布局管理器(Layout Manager)及其相关属性来实现的。事实上上述按方位来安排组件就是采用了Java中多种布局管理器里的BorderLayout布局管理器。

      ④处理事件

      为了完成一个GUI应用程序所应具备的功能,除了适当地安排各种组件产生美观的界面外,还需要处理各种界面元素事件,以便真正实现与用户的交换,完成程序的功能。在Java程序中这一般是通过实现适当的事件监听者接口来完成的。比如如果需要响应按钮事件,就需要实现 ActionListener监听者接口;如果需要响应窗口事件,就需要实现WindowListener监听者接口。

    java采用的是事件源——事件监听器模型
    1:事件(event):是指一个状态的改变,或者一个活动的发生。例如,简单常见的是单击一个按钮,或者输入一个按键都是一个事件。
    2:事件源(event source):能够产生事件的对象称为事件源,如文本框,按钮,下拉列表等。
    3:事件监听器(event listener):需要一个对象对事件源进行监听,以便对发生的事件做出处理,该对象就是事件监听器。事件源通过调用相应的方法将某个对象作为自己的监听器。无论应用程序还是小程序都采用这一机制。
    例,对于按钮,注册监听器的方法是 addActionListener(监视器);:
    4: 事件源获得监听器之后,相应的操作就会导致事件的发生,并通知监听器,监听器就会做出相应的处理。
    5:处理事件的接口:监听器负责处理事件源发生的事件。为了处理事件源发生的事件,监听器会自动调用一个方法来处理事件,该方法定义在相应事件的接口中。

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    [转发]深入理解git,从研究git目录开始
    iOS系统网络抓包方法
    charles抓包工具
    iOS多线程中performSelector: 和dispatch_time的不同
    IOS Core Animation Advanced Techniques的学习笔记(五)
    IOS Core Animation Advanced Techniques的学习笔记(四)
    IOS Core Animation Advanced Techniques的学习笔记(三)
    IOS Core Animation Advanced Techniques的学习笔记(二)
    IOS Core Animation Advanced Techniques的学习笔记(一)
    VirtualBox复制CentOS后提示Device eth0 does not seem to be present的解决方法
  • 原文地址:https://www.cnblogs.com/fzx201626/p/10015972.html
Copyright © 2011-2022 走看看