簡體   English   中英

Java Swing程序-從GUI到Main的輸入被卡住

[英]Java Swing Program- Input from GUI to Main getting stuck

我有一個Java程序,打算從GUI接收輸入,以后再使用該輸入在main()進行處理。 我正在使用Eclipse
我正在將HW對象(稱為HWObj )發送到GUI JFrame ,並檢查對象中的boolean字段以繼續在main()進行處理。

InputWindow是自定義對象,該對象擴展了JPanel實現的ActionListener它包含對當前JFrame (parentFrame)的引用。 在InputWindow中單擊JButton時,我編寫了一個自定義ActionListenerHWObj HWObj .check的值設置為true並放置了parentFrame。 這將導致執行在main()恢復。
HW類的代碼如下:

import java.awt.*;
import javax.swing.*;
public class HW {

    //globals
    boolean check;
    public HW() {
        //initialisations
        check = false;
    }

    public static void main(String args[]) { 
        final HW problem = new HW();
        try {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    //Create and set up the window.
                    JFrame frame = new JFrame("Select folders");
                    frame.setPreferredSize(new Dimension(640, 480));
                    frame.setResizable(false);
                    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    InputWindow Directories = new InputWindow(problem, frame);
                    Directories.setOpaque(true);
                    frame.add(Directories);
                    //Display the window.
                    frame.pack();
                    frame.setVisible(true);
                }
            });
        } catch(Exception e) {
            System.out.println("Exception:"+e.getLocalizedMessage());
        }
        while(!problem.finish);
        //Do processing on problem
        System.out.println("Done");
    } 
}

Actionlistener在GUI如下:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class InputWindow extends JPanel
                implements ActionListener {

    private static final long serialVersionUID = 4228345704162790878L;

    HW problem;
    JFrame parentFrame;
    //more globals

    public InputWindow(HW problem, JFrame parentFrame) {
        super();
        this.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        this.parentFrame = parentFrame;
        this.problem = problem;

        JButton finishButton = new JButton("Finish");
        finishButton.setActionCommand("fin");
        finishButton.addActionListener(this);
        gbc.gridx = 0;
        gbc.gridy = 0;
        this.add(finishButton, gbc);

        //Initialize buttons and text areas and labels
        //Code removed for ease of reading

    }

    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        if(command.equals("fin")) {
            //Do a lot of stuff, then   
            this.removeAll();
            parentFrame.dispose();
            problem.check = true;
        }
    }
}

我已經檢查過,對該功能的控制通常在單擊按鈕時進行。

現在,我希望它返回main ,退出while循環,然后繼續處理。 這不會發生。 eclipse中的調試器僅顯示正在運行的主線程,當我嘗試暫停它時,我看到該線程卡在while循環中。 但是,如果我嘗試逐步執行,它將按預期退出while循環,然后繼續。 但是,它一直停留在while循環中,直到我手動嘗試對其進行調試為止。
問題是什么? 為什么不按預期方式恢復main thread 我該如何解決這個問題?

您的問題與Java內存模型的工作方式有關。 在你的主線程的循環將被檢查的陳舊值check

當您進入調試器時,將強制更新內存,因此這就是為什么它開始工作的原因。

如果將變量標記為volatile ,將強制JVM確保所有線程都使用最新值:

volatile boolean check;

您可以在文檔中閱讀有關volatile和Java內存模型的更多信息

看起來您正在使用JFrame,而應該使用模式JDialog。 如果將模式JDialog用於輸入窗口,您將確切知道何時“完成”,因為從設置對話框可見后的立即開始,調用流將恢復代碼流。

或者,或者如果您嘗試交換視圖,則使用CardLayout交換視圖,並使用觀察者類型模式偵聽狀態變化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM