简体   繁体   中英

How to add ActionListeners to a modal JDialog?

I wanted to create a JDialog which responds to mouse and key actions. The dialog holds a jTable where I want him to select a record. He should be able to select it by double click or by pressing a key (eg "2").

So I started by this:

public showDialog(TableModel model) {
    super(new JFrame(), "Please select a record..."); 
    table = new JTable(model);

    //add JTable with ScrollPane
    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setPreferredSize(new Dimension(800, Math.min(table.getPreferredSize().height+60, 800)));
    scrollPane.getViewport().add(table);
    add(scrollPane);

    //display
    setAlwaysOnTop(true);
    toFront();
    pack();
    setVisible(true);

    //mouse
    table.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(java.awt.event.MouseEvent evt) {
            System.out.println("clicked");
        }
    });

    //keys
    table.addKeyListener(new KeyAdapter() {

        @Override
        public void keyTyped(java.awt.event.KeyEvent evt) {}

        @Override
        public void keyReleased(java.awt.event.KeyEvent evt) {}

        @Override
        public void keyPressed(java.awt.event.KeyEvent evt) {
            System.out.println(evt.getKeyChar() + " pressed");
        }
    });
}

This works flawlessly.

However if I do the same thing with the statement setModal(true); , the listeners stop working.

How can I make my JDialog modal without losing the functionality of my listeners?

Simple solution: when the JDialog is modal, then setVisible() blocks the current thread, ie the Dialog's Constructor. Thus the Listeners are never added (actually only when the Dialog is closed). Therefore no events.

Solution: set 'setVisible(true);' to the end of the CTOR

BTW you should not to modal locking in the CTOR, having an extra method like 'void showTheDialog();' is better. If you had done this from the beginning, the listeners would have been there and everything would have worked ;-) Edit: Or use something like a Factory method, that's even better.

BTW PLEASE PLEASE stick to naming conventions, it took me 10 seconds to figure out that with 'public showDialog(TableModel model) {' you had not forgotten the method return type but that this would actually have been the CTOR itself :-)

I think this can cause a problem:

super(new JFrame(), "Please select a record...");

Why are you creating a new JFrame , you have to specify an existing one.

Btw, you should call super in constructor of your class which extends JDialog , not in some other method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM