黑马程序员——GUI(2)对话框

------- android培训java培训、期待与您交流! ----------

我认为对话框是一个延迟加载的窗体。并且是有条件加载的。对话框的使用方法和Frame相比基本相同。当然,两者本身就都是容器类。


但是对话框并不是程序运行就存在的,而是出发某些条件后产生的。比如要求输入数字结果输入了其他字符,这时候可能就会弹出一个对话框来。但是awt在这方面做得有点让人用的不方便。Windows编程里面可以比较方便的弹一个MessageBox,但是awt里面只能自己手写了,真痛苦....


1.创建对话框Dialog d=new Dialog(Container);//对话框不能独立存在,创建对话框必须传入一个窗体作为其依赖对象。这是和Frame相比很大的不同。


2.设置对话框 

d.setBounds(x,y,w,h);

d.setLayout(null);

3.添加组件

Label lbl=new Label("hello!");

d.add(lbl);

4.注册监听器

d.addWinowListener(new windowAdapter(){

public void windowClosing(WindowEvent e){}

});

5.设置可见

d.setVisible(true);

大致上都和Frame一致。

【补充】Dialog在初始化时可以传入一个Boolean参数表示其模式,如果为true则当对话框存在时不可以操作其他窗体,比如警告信息;为false则可以同时操作对话框和原来的窗体,比如文本文档的搜索。

如何与调用Dialog的invoker互动。

1.当前我是把需要传递的信息封装在整个大类上,在大类初始化时创建一个相应的对象,类似于全局变量,这样大类内所有方法都可以使用。但是总觉得这样有违数据封装的理念。相信后期高级工具里面会有相应的解决办法。

2.利用组件的名字。通过getName(),setName()来传递信息。


在下面的示例代码中,我将搜索结果用Label动态显示在了对话框里。设置显示文字的同时,设置了Label的名字为数据String值。然后给Label注册了双击的监听器,当双击时,监听器方法会通过e.getComponent()方法获取产生事件的组件,也就是被双击的标签,然后再调用getName()就获取到了事先设置好的数据,然后再将数据存入全局的一个集合中。这时候再在监听器中关闭对话框返回原来的主界面,这时候再向主界面上的TextArea添加刚才获取到的数据,完成信息的传递。






InitWrongDlg提示错误信息的对话框
<span style="font-family: Arial, Helvetica, sans-serif;">InitNormalDlg是显示搜索结果的对话框</span>

在主界面的代码中增加一个监听器,当在TextField中按下了回车则调用searchGameByName();搜索输入的关键字。

		// TextField增加一个按键监听器。如果按下回车相当于点了“查询”
		tfSearch.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e) {
				if (KeyEvent.VK_ENTER == e.getKeyCode()) {
					keyWords = tfSearch.getText();// 获取TextField中的文本。					
					searchGameByName();
					tfSearch.setText("");				
				}
			}
		});


	private void searchGameByName() {
		if(keyWords.equals(""))//如果输入为空则直接返回,不进行下一步
			return;
		matchResults.clear();//“全局”的TreeMap<String, Integer> matchResults;//这里清空以存放本次的搜索结果。
		//dbMap是加载到内存的“全局”的游戏信息“数据库”TreeMap<String, GameInfo> 
		//这里使用的GameSearchModule是一个工具类,使用的是单例设计模式。以后再说。
		GameSearchModule engine = GameSearchModule.getInstance(dbMap.keySet());
		//public int searchGame(String keyWords,TreeMap<String, Integer> matchResults)
		//参数是搜索的关键字和用于存放搜索结果的Map,返回值是表示搜索结果状态的整数。为了方便使用我将返回的整数设置为常量。
		//判断搜索结果,如果是BAD_KEYWORDS和NO_RESULT则弹出提示错误信息的对话框。如果是NORMAL_RESULTS则弹出列有搜索结果的对话框。
		switch (engine.searchGame(keyWords,matchResults)) {
		case GameSearchModule.BAD_KEYWORDS:
			InitWrongDlg(new String("InValid words with your search:\""
					+ keyWords + "\"."));
			break;
		case GameSearchModule.NO_RESULT:
			InitWrongDlg("Could not find the result with your search:\""
					+ keyWords + "\".");
			break;
		case GameSearchModule.NORMAL_RESULTS:
			InitNormalDlg(matchResults);
			break;
		}
	}
	//显示错误信息,没啥好说的。
	private void InitWrongDlg(String info) {
		int screenWidth = (int) Toolkit.getDefaultToolkit().getScreenSize().width;
		int screenHeight = (int) Toolkit.getDefaultToolkit().getScreenSize().height;
		Dialog dlgErr = new Dialog(fBase, "Error", true);
		dlgErr.setBounds(screenWidth / 8 * 3, screenHeight / 8 * 3,
				screenWidth / 4, screenHeight / 4);
		dlgErr.setLayout(new FlowLayout());
		Label lblErr = new Label(info);
		Button btnConfirm = new Button("Confirm");
		btnConfirm.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dlgErr.setVisible(false);
			}
		});
		dlgErr.add(lblErr);
		dlgErr.add(btnConfirm);
		dlgErr.setVisible(true);
	}


private void InitNormalDlg(TreeMap<String, Integer> matchResults) {
		int screenWidth = (int) Toolkit.getDefaultToolkit().getScreenSize().width;
		int screenHeight = (int) Toolkit.getDefaultToolkit().getScreenSize().height;

		dlgSearchResult = new Dialog(fBase, "Search Result", true);
		dlgSearchResult.setBounds(screenWidth / 4, screenHeight / 4,
				screenWidth / 2, screenHeight / 2);
		// setLayout()设置窗体的布局。
		dlgSearchResult.setLayout(null);
		
		//提示语标签
		Label lblIntro = new Label(
				"Here are the results listed by relevance with your search:\""
						+ keyWords
						+ "\",please double click the label of the game that you are looking for!",
				Label.LEFT);
		dlgSearchResult.add(lblIntro);
		lblIntro.setBounds(screenWidth / 80, screenHeight / 40,
				screenWidth / 2, screenHeight / 20);
		
		
		
		// 这是之前做的正则表达式(2)中练习的代码。我抽取出来了。
		// 将匹配结果按照标记次数排列,已备之后由用户选择匹配出的结果。
		// 也就是把MAP按照value降序排列
		// 先将map的条目转换成list
		List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(
				matchResults.entrySet());
		// 用sort排序,自定义一个比较器
		Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
			@Override
			// 让value大的排在前面。
			public int compare(Map.Entry<String, Integer> arg0,
					Map.Entry<String, Integer> arg1) {
				return arg1.getValue().compareTo(arg0.getValue());
			}
		});		
		/*动态加载搜索结果
		 * 输入:List<Map.Entry<String, Integer>>//String表示数据库中的游戏名称,Integer表示游戏名称与所搜索的关键字中的所有单词的匹配次数。
		 * 输出:标签Label
		 * 步骤:
		 * 1.新建一个标签。同时加上标签所显示的内容
		 * 2.设置标签的名字为游戏名称,以便之后传递给其他。
		 * 3.注册双击的监听器
		 * 4.添加到对话框
		 * 5.设置标签的位置。
		 * 双击思路:在mouseClicked(MouseEvent e)中,事件对象中有许多相关信息,其中就有点击次数的信息。- 查找事件的相关信息应当去看Event的API
		 * 调用e.getClickCount()即可获取。		 * 
		 * */
		//将将要显示搜索结果限制在10个以内。
		int cntResults = 10;
		Label[] lblResults = new Label[cntResults+1];
		int id=0;
		String name=null;
		for (Map.Entry<String, Integer> me : list) {			
			++id;
			name=me.getKey();
			//1.新建一个标签。同时加上标签所显示的内容
			lblResults[id]=new Label(id + ":\t[" + name+ "]......with [" + me.getValue() + "] relevance.");
			//2.设置标签的名字为游戏名称
			lblResults[id].setName(name);		
			//3.注册双击的监听器
			lblResults[id].addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent e)
				{
					if(2==e.getClickCount())
					{
						String newKey=e.getComponent().getName();
						//System.out.println(e.getComponent().getName());
						//dlgSearchResult.setName(e.getComponent().getName());						
						GameInfo newGame=dbMap.get(newKey);
						//将用户选择的搜索结果所包含的信息打印在主界面的TextArea上。
						taInfo.append(newGame.toString()+"\r\n");
						//将搜索结果添加到统计信息的集合中。ArrayList<GameInfo> bundleContent
						bundleContent.add(newGame);
						//清空搜索结果的Map,待下次搜索使用。
						matchResults.clear();
						dlgSearchResult.setVisible(false);
					}
				}				
			});
			//4.添加到对话框
			dlgSearchResult.add(lblResults[id]);
			//5.设置标签的位置。
			lblResults[id].setBounds(screenWidth / 80,
					screenHeight / 200 * (15 + 8 * id - 8), screenWidth / 40 * 19,
					screenHeight / 200 * 8);
			
			// 为了控制输出内容的数量,可以做个限制
			if (id >= cntResults) {	break; }
		}



		dlgSearchResult.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				dlgSearchResult.setVisible(false);
			}
		});

		dlgSearchResult.setVisible(true);
	}





























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值