1

2 つのテキスト ファイルから情報を収集してデータベースのテーブルに追加するプログラムを作成しています。ユーザーが自分のファイルを選択できるようにするために、クラスをchooseFile()使用してa を表示するという非静的メソッドを作成しました(静的メソッドとしても試してみましたが、同じ結果が得られました。推測しているように聞こえる場合は、あなたは正しいです-私はプログラミングについてはまあまあです)。JFileChoosershowOpenDialog

私の理解では、Swing クラスへの呼び出しは をmain()使用して行う必要がありますinvokelater。これは、 への 1 回の呼び出しではすべて正常に機能しました (JVM は正常に終了しました)chooseFile()が、2 回目の呼び出しを JVM に追加するとchooseFile()、JVM は無期限に実行され続けます。chooseFile()ただし、を使用せずに実行すると、プログラムは両方の呼び出しで正常に終了しますinvokelaterSystem.exit(0)2 番目の呼び出しの後に追加するとinvokelater、プログラムを正常に終了させることもできます。

私が収集できたものから、プログラムはすべての (非デーモン) スレッドが閉じられるまで終了しません。invokelaterただし、スレッドセーフでない Swing 関連のすべてのアクティビティを EDT にプッシュすることが使用の目的であると考えました。ここでベストプラクティスを使用しSystem.exit(0)ていますか、それとも他に知っておくべきことがありますか?

これが私のSSCCEです:

package ptMngr;

import java.io.IOException;
import java.nio.file.Path;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

public class ParticipantManager {

    private Path chooseFile() throws IOException{
        JFileChooser chooser = new JFileChooser();
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Text Files", "txt","csv");
        chooser.setFileFilter(filter);
        int returnVal = chooser.showOpenDialog(null);
        if(returnVal == JFileChooser.APPROVE_OPTION) {
            System.out.println("You chose to open this file: " +
                chooser.getSelectedFile().getName());
        }
        Path path = chooser.getSelectedFile().toPath();
        return path;
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args){
    //        ParticipantManager pm =  new ParticipantManager();
    //        try {
    //            pm.chooseFile();
    //            pm.chooseFile();
    //
    //        } catch (IOException ex) {
    //            Logger.getLogger(ParticipantManager.class.getName()).log(Level.SEVERE, null, ex);
    //        }

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                ParticipantManager pm =  new ParticipantManager();
                try {

                    pm.chooseFile();
                    pm.chooseFile();
                    System.exit(0);
                } catch (IOException ex) {
                    Logger.getLogger(ParticipantManager.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }
}
4

1 に答える 1

1

への呼び出しで、の親コンポーネントとしてshowOpenDialog(null)渡します。で作業してからしばらく経ちましたが、 が渡されたときに「魔法の」JFrame が構築される可能性があることを覚えているようです。このユースケースでは、2 つの「魔法の」JFrame が作成され、それらが終了。nullJFileChooserJFileChoosernull

自動フレームを作成しないようにJFrame、両方の の親として機能する を作成してみてください。JFileChooser

編集:

私の最初のテイクはこれです:

public static class ParticipantManager {
    JFrame frame;

    private JFrame getFrame() {
        if (frame==null) {
            frame = new JFrame();
            frame.setSize(600, 400);
            frame.setLocationRelativeTo(null);
            // frame.setVisible(true); // <---- worked for me without this call too
        }
        return frame;
    }

    private void close() {
        frame.dispose();
    }

    private Path chooseFile() throws IOException{
        JFrame f = getFrame();
        ...
        int returnVal = chooser.showOpenDialog(f);
    ...

    ...
                pm.chooseFile();
                pm.chooseFile();
                pm.close(); // <----- close the frame
    ...
于 2015-11-18T21:42:47.457 に答える