Swing window 在 x 次后没有 return 值

Swing window doesn't return value after x time

我正在尝试在 Swing 中做一个呼叫模拟器,但出于某种原因 window 不会让步。

我的目标是打开一个单独的 window,如果按下一个按钮或另一个按钮,则 returns true 或 false。用户应该有 15 秒的时间做某事,否则它 returns false 并执行一个动作。

当它 returns 时,它应该完成它的执行。该函数被main的另一个函数部分调用。

但是,由于我缺乏经验和愚蠢,它不起作用。相反,它会打开一个 window(空白),该 window(空白)在应该关闭时永远不会自行关闭...

代码如下:

public static boolean callWindow(Telephone src, Telephone dst) {

        Timer t1 = new Timer(15000, e-> {
            DateTime date = new DateTime();
            Call c = new Call(date, src.getTelephone(), dst.getTelephone(), 0);
            dst.addLostCall(c);
        });

        //Janela para atender
        JFrame window = new JFrame();
        window.setTitle("Incoming Call");

        JLabel telephones = new JLabel();
        telephones.setText("From: " + src.getTelephone() + "    To: " + dst.getTelephone() );

        JButton answerCall = new JButton("Answer");
        JButton denyCall = new JButton("Decline");

        JLabel status = new JLabel();
        answerCall.addActionListener( e -> status.setText("answer") );
        denyCall.addActionListener( e -> status.setText("no answer") );

        answerCall.setBackground(Color.GREEN);
        denyCall.setBackground(Color.RED);

        JPanel callInfo = new JPanel();
        callInfo.add(telephones);

        JPanel callOptions = new JPanel();
        callOptions.add(answerCall);
        callOptions.add(denyCall);

        Container container = window.getContentPane();
        container.add(callInfo, BorderLayout.NORTH);
        container.add(callOptions);

        window.setSize(350,120);
        window.setVisible(true);

        t1.start();
        while (t1.isRunning()) {
            if (status.getText().equals("answer")) return true;
            if (status.getText().equals("no answer")) return false;
        }

        return false;

    }

我很想知道它是如何工作的以及如何消除这个可怕的代码。

我用 JDialog 来演示如何在 15 秒后关闭 window。

这是我创建的 GUI JFrame

这是我创建的JDialog

JDialog 将在 15 秒后处理。如果呼叫被接听,isAnswered 方法将 return 为真,如果呼叫被拒绝,JDialog 通过左键单击 X 关闭,或者当 15 秒用完时,则为假.

这是完整的可运行代码。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class JDialogTimedGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new JDialogTimedGUI());
    }
    
    private JFrame frame;

    @Override
    public void run() {
        frame = new JFrame("JDialog Timed GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createMainPanel(), BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(
                75, 100, 75, 100));
        panel.setPreferredSize(new Dimension(400, 200));

        JButton button = new JButton("Open JDialog");
        button.addActionListener(new ButtonListener());
        panel.add(button);

        return panel;
    }
    
    public class ButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent event) {
            IncomingCall ic = new IncomingCall(frame, "Incoming Call", 
                    "555-1212", "555-2323");
            System.out.println("Incoming call: " + ic.isAnswered());
        }

    }
    
    public class IncomingCall extends JDialog {
        
        private static final long serialVersionUID = 1L;
        
        private boolean answered;
        
        private Timer timer;

        public IncomingCall(JFrame frame, String title, 
                String sourcePhone, String destinationPhone) {
            super(frame, true);
            this.answered = false;
            
            setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            setTitle(title);

            add(createMainPanel(frame, sourcePhone, destinationPhone));
            pack();
            setLocationRelativeTo(frame);
            
            timer = new Timer(15000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent event) {
                    setVisible(false);
                    dispose();
                    timer.stop();
                }
            });
            timer.start();
            
            setVisible(true);
        }
        
        private JPanel createMainPanel(JFrame frame, 
                String sourcePhone, String destinationPhone) {
            JPanel panel = new JPanel(new BorderLayout(5, 5));
            panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            
            String s = "From: " + sourcePhone + "    To: " + destinationPhone;
            JLabel telephones = new JLabel(s);
            panel.add(telephones, BorderLayout.BEFORE_FIRST_LINE);
            
            JPanel callOptions = new JPanel();
            
            CallButtonListener listener = new CallButtonListener(this);
            
            JButton answerCall = new JButton("Answer");
            answerCall.addActionListener(listener);
            answerCall.setBackground(Color.GREEN);
            callOptions.add(answerCall);
            
            JButton denyCall = new JButton("Decline");
            denyCall.addActionListener(listener);
            denyCall.setBackground(Color.RED);
            callOptions.add(denyCall);
            
            panel.add(callOptions, BorderLayout.CENTER);
            
            return panel;
        }

        public void setAnswered(boolean answered) {
            this.answered = answered;
        }

        public boolean isAnswered() {
            return answered;
        }
        
    }
    
    public class CallButtonListener implements ActionListener {
        
        private IncomingCall incomingCall;

        public CallButtonListener(IncomingCall incomingCall) {
            this.incomingCall = incomingCall;
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            JButton button = (JButton) event.getSource();
            if (button.getText().equals("Answer")) {
                incomingCall.setAnswered(true);
            } else {
                incomingCall.setAnswered(false);
            }
            incomingCall.dispose();
        }
        
    }

}