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

来源:互联网 发布:mac镜像下载 编辑:程序博客网 时间:2024/06/10 05:38
------- 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的条目转换成listList<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> bundleContentbundleContent.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
原创粉丝点击