黑马程序员技术交流社区

标题: GUI Esc退出程序怎么对所有组件起作用 [打印本页]

作者: 晓月残魂    时间: 2015-9-19 14:49
标题: GUI Esc退出程序怎么对所有组件起作用
刚刚写了个GUI小程序(就是毕老师的视频),想添加按Esc键退出程序,但是我只能实现针对某个组件(通过添加此组件的键盘监听器),比如面板或者按钮,但是这样当焦点不在这些组件上时,Esc就不能起作用,除非对每个组件都添加这样的键盘监听,但是太麻烦了,有没有比较好的方法,可以自写一次代码,可以实现对所有组件的监听,或者其他的什么方法?

下面是我的代码:


import java.awt.Button;
import java.awt.Event;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
/*
* 此程序:在文本框输入文件路径,点击“转到”按钮,可以将此路径下的所有文件和文件夹全部列举出来
* 要求:
* 1)文本框中直接回车,相当于点击“转到”按钮
* 2)按Esc按钮时,相当于退出程序
* 3)文本框中不能输入*?
*/

class MyFrameExample
{
        /*---------------声明全局变量,可以更好的分类各个事件----------*/
        private Frame f;
        private TextField txtf;
        private Button btn;
        private TextArea txta;
        /*--------  创建改类对象时就直接执行init()  -----------------------*/
        public MyFrameExample()
        {
                init();
        }
        /*--------- 只是单单的创建控件,以及布局 ------------------------*/
        public void init() //
        {
                f = new Frame("MyFrame");
                f.setVisible(true);
                f.setBounds(300, 200, 500, 300);
                f.setLayout(new FlowLayout());
                /*-----------------------------------------------------------------*/
                txtf = new TextField(50);
                btn = new Button("转到");
                txta = new TextArea(13, 57);
                /*-----------------------------------------------------------------*/
                f.add(txtf);
                f.add(btn);
                f.add(txta);
                /*----不要忘记去执行监听事件函数----------------------------*/
                myEvent();
        }
        /*---------------------------------------------------------------------*/
        private void fun()
        {
                String filePath = txtf.getText().trim();
                // System.out.println(filePath);
                if(filePath != null && !("".equals(filePath)))
                {
                        File dir = new File(filePath);
                        if(dir.exists() && dir.isDirectory())
                        {// 如果存在,并且是个目录
                                String[] files = dir.list();// 获取目录下的文件名
                                txta.setText("");
                                for(String file : files)
                                {
                                        txta.append(file + "\r\n");// 追加到行末
                                }
                        }
                }
                txtf.setText("");
        }
        /*---------- 监听事件  事件的触发   --------------------------------*/
        private void myEvent()
        {
                // 因为监听器是接口,并且里面有众多抽象方法,直接实现太麻烦,所以用适配器(监听器只要有3个和3个以上监听事件,就会有适配器)。
                // 适配器是一个抽象类,但是里面没有抽象方法,抽象的作用只是不让你直接创建对象,强制你用继承的方式去创建
                // 适配器已全部实现监视器的方法,但是是空方法,没有具体作用,所以用监听事件时就重写对应方法即可
                //
                /*----------为f窗口添加一个监听器的适配器-------------------*/
                f.addWindowListener(new WindowAdapter()
                {// 匿名内部类
                        @Override
                        public void windowClosing(WindowEvent e)
                        {// 只重写了适配器的Closing方法,指当发生点击关闭按钮事件时就会触发改函数
                                System.exit(0);
                        }
                });
                // 鼠标、键盘事件是共性事件,很多控件都有这两种事件
                // 鼠标事件:单击、按下,释放,进入,离开(可以从参数里获取按键按动次数、是左键还是右键)
                // 键盘事件:按下、释放、键入(可以从参数里获取具体按键)
                /*----------为f窗口添加一个键盘监听-------------------*/
                f.addKeyListener(new KeyAdapter()
                {
                        @Override
                        public void keyPressed(KeyEvent e)
                        {
                                if(e.getKeyCode() == Event.ESCAPE)
                                        System.exit(0); // 此监听,这能聚焦窗口时起作用,聚焦文本框就不起作用了
                        }
                });
                /*----------为按钮添加一个活动监听器------(没有适配器,因为此监听器只有一个方法)------------------*/
                btn.addActionListener(new ActionListener()
                {// 此事件不是鼠标事件,此事件是当控件被聚焦时触发(活动监听)
                        // 对按钮来说,活动监听没有单击事件具体,所以单击事件先触发
                        @Override
                        public void actionPerformed(ActionEvent e)
                        {
                                fun();
                        }
                });
                /*----------为文本框添加一个键盘监听器-------------------*/
                txtf.addKeyListener(new KeyAdapter()
                {
                        @Override
                        public void keyPressed(KeyEvent e)
                        {
                                // System.out.println(e.getKeyChar());
                                if(e.getKeyCode() == Event.ENTER)
                                {
                                        fun();
                                }
                        }
                });
        }
}

public class Main
{
        public static void main(String[] args)
        {
                new MyFrameExample();
        }
}


作者: fmi110    时间: 2015-9-19 16:11
本帖最后由 fmi110 于 2015-9-19 16:18 编辑
  1.   addKeyListener(new java.awt.event.KeyAdapter() {
  2.             public void keyPressed(java.awt.event.KeyEvent evt) {
  3.                 formKeyPressed(evt);
  4.             }
  5.         });
复制代码
  1. private void formKeyPressed(java.awt.event.KeyEvent evt) {                                
  2.         System.out.println("有按键按下");
  3.         char ch = evt.getKeyChar();
  4.         System.out.println(ch);
  5.     }   
复制代码
  1. 有按键按下
  2. i
  3. 有按键按下
  4. u
  5. 有按键按下
  6. q
  7. 有按键按下
  8. f
复制代码



作者: fmi110    时间: 2015-9-19 16:22
// 此监听,这能聚焦窗口时起作用,聚焦文本框就不起作用了

在文本框中也添加处理 遇到 esc 就退出呢
作者: 晓月残魂    时间: 2015-9-19 16:36
fmi110 发表于 2015-9-19 16:22
// 此监听,这能聚焦窗口时起作用,聚焦文本框就不起作用了

在文本框中也添加处理 遇到 esc 就退出呢 ...

意思是:把esc退出功能抽取成函数,然后给每个组件添加按键监听,调用此函数吗?
作者: fmi110    时间: 2015-9-19 17:02
晓月残魂 发表于 2015-9-19 16:36
意思是:把esc退出功能抽取成函数,然后给每个组件添加按键监听,调用此函数吗? ...

差不多吧,我觉得在文本框不起作用 应该是文本框的监听优先级比窗口监听高,所以按键处理不起作用
应该有更好的方法 不过没想到
作者: 晓月残魂    时间: 2015-9-19 18:53
fmi110 发表于 2015-9-19 17:02
差不多吧,我觉得在文本框不起作用 应该是文本框的监听优先级比窗口监听高,所以按键处理不起作用
应该有 ...

好吧。
谢啦~~~~
文本框监听Esc键可以的~




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2