简体   繁体   English

在Java中使用JFrame的侦听器

[英]Listener using JFrame in Java

I'm learning right now the basics of the ActionListeners and I've been searching for help over here but can't quite find/figure what I'm doing wrong. 我现在正在学习ActionListeners的基础知识,并且一直在这里寻求帮助,但无法完全找到/弄清楚我做错了什么。

I've got a class (Client) which implements the main call: 我有一个实现主调用的类(客户端):

...
public static void main(String[] args) {

    Myframe test = new Myframe();

    N = test.setVisible(); // N is an integer

...
}

Then the code from my frame: 然后从我的框架中的代码:

public class test extends JFrame {

    private JPanel contentPane;
    private int N;

    public int setVisible(){

        this.setVisible(true);
        return N;

    }

    /**
     * Create the frame.
     */
    public test() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JButton btnOk = new JButton("OK");
        btnOk.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                N=5;
                dispose();

            }
        });
        contentPane.add(btnOk, BorderLayout.SOUTH);
    }

}

And the problem: the program doesn't wait for the button to be pressed before keep going and N results in some trash value thus giving error. 问题是:程序在继续前进之前不等待按钮被按下,N导致某个垃圾值,从而产生错误。 What should I do to make it handle correctly it without sleeping the thread? 我应该怎么做才能使其正确处理而不休眠线程?

Some ways to fix this. 解决此问题的一些方法。 Use a JDialog - provides modal blocking by default, Listener mechanism - call back with value later, or make your code blocking 使用JDialog-默认情况下提供模式阻止,侦听器机制-稍后使用值进行回调,或进行代码阻止

JDialog 的JDialog

public class test extends JDialog {
    ...    
    private int N;

    public int setVisible() {
        this.setVisible(true);
        return N;
    }

    public test() {
        super(null, ModalityType.APPLICATION_MODAL); 
        // <== pass parent window here if you have one, you don't seem to.. 
        ...
    }

Blocking example 封锁范例

  • Use java.util.concurrent.CountDownLatch 使用java.util.concurrent.CountDownLatch

Code

public class test extends JFrame {
    ....    
    private CountDownLatch latch;
    private int N;

    public int setVisible() throws InterruptedException{

        latch = new CountDownLatch(1);
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                setVisible(true);
            }
        });

        latch.await();   // <== block until countDown called
        return N;
    }

    public test() {           
        ...
        btnOk.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                N=5;
                latch.countDown();   <== will unblock await() call
                dispose();

            }
        });
        ...
    }

}

Listener 倾听者

public class test extends JFrame {
    ... 
    private Listener listener;

    public static interface Listener {
        void setN(int n);
    }

    public void setVisible(Listener listener) throws InterruptedException {
        this.listener = listener;   // <== save reference to listener
        setVisible(true);
    }

    public test() {
        ...
        btnOk.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                listener.setN(5);  // <== call listener
                dispose();

            }
        });
    }

Use a modal JDialog instead of a JFrame , which are designed to block at the point they are made visible until they are closed... 使用模式JDialog而不是JFrame ,它们旨在在使其可见之前进行阻塞,直到将其关闭为止。

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }


    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JDialog frame = new JDialog();
                TestPane testPane = new TestPane();
                frame.setTitle("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(testPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                System.out.println("The value was - " + testPane.getValue());
            }
        });
    }

    public class TestPane extends JPanel {

        private int n;

        public TestPane() {
            JButton btnOk = new JButton("OK");
            btnOk.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {

                    n = 5;
                    SwingUtilities.windowForComponent(TestPane.this).dispose();

                }
            });
        }

    }

    public int getValue() {
        return n;
    }

}

Take a look at How to Make Dialogs for more details 查看更多如何制作对话框的详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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