Как забрать данные из ActionListener и использовать их в BufferedReader без Thread.sleep

У меня есть код, который ищет одинаковые строки в двух файлах формата csv. Я хочу добавить функцию, где человек может указать путь к файлу, а не прописывать заранее его в коде. Для этого использую библиотеки Swing.

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

public class PanelInput extends JFrame{
    //Поля для теста
    JTextField inputFileOne;
    JTextField inputFileTwo;

    //Кнопка для ввода
    JButton button;

    //Переменные для сохранения вписаного текста и передачи в BufferedReader
    private static String filePathOne;
    private static String filePathTwo;

    public static String getFilePathOne() {return filePathOne;}
    public static String getFilePathTwo() {return filePathTwo;}

    public static void setFilePathOne(String filePathOne) {PanelInput.filePathOne = filePathOne;}
    public static void setFilePathTwo(String filePathTwo) {PanelInput.filePathTwo = filePathTwo;}
    PanelInput(String filePathOne, String filePathTwo){
        this.filePathOne =filePathOne;
        this.filePathTwo =filePathTwo;
    }

    //Создаем окно ввода
    public void windowInput() {
        //окно ввода
        JFrame frame = new JFrame();
        //Инициализация переменных и кнопки
        inputFileOne = new JTextField();
        inputFileTwo = new JTextField();
        button = new JButton("Data entry");
        //Выводинм на экран поля и кнопки
        frame.getContentPane().add(BorderLayout.BEFORE_FIRST_LINE, inputFileOne);
        frame.getContentPane().add(BorderLayout.CENTER, inputFileTwo);
        frame.getContentPane().add(BorderLayout.SOUTH, button);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Определяем размер окна и выводим его на экран
        frame.setSize(500, 200);
        frame.setVisible(true);
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                filePathOne = inputFileOne.getText();
                filePathTwo = inputFileTwo.getText();
            }
        });
    }
    public static void main(String[] args) throws InterruptedException {
        PanelInput panelInput = new PanelInput(filePathOne,filePathTwo);
        panelInput.windowInput();
        Thread.sleep(10000);
        System.out.println(panelInput.getFilePathOne());
        System.out.println(panelInput.getFilePathTwo());


    }
}

Выше код, где открывается панель для ввода адреса к файлу. В полях inputFileOne и inputFileTwo вводятся пути к файлам, в ActionListener я смотрю, что было записано и передаю в переменные filePathOne и filePathTwo.

При попытке через main их вывести у меня выводит null.

В интернете много прочитал форумов и все советуют поставить Thread.sleep, т.к. в данных переменных пусто и поэтому программа выводит null, не успевая записать информацию, которую я ввожу в поля ввода.

Как сделать, чтобы введенная информация выводилась в System.out.println или передавалась в BufferedReader после нажатия кнопки button, а не до её нажатия?


Ответы (2 шт):

Автор решения: Roman C

Вместо того, чтобы использовать JFrame , в котором создаются поля для ввода значений, нужно использовать JDialog, который следует показывать в модальном режиме.

Как это делается, можно почитать здесь.

А для выбора файла(ов) можно использоват JFileChooser. Вот примерный код

JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle("Выбери файл...");
chooser.showOpenDialog(null);
file = chooser.getSelectedFile();                    
→ Ссылка
Автор решения: Nowhere Man

Судя по вопросу, требуется обеспечить модальный ввод данных из двух полей в контексте метода main с использованием Swing.

Это можно реализовать гораздо проще при помощи кастомизированного диалога JOptionPane с двумя (или более) полями ввода, который можно вызвать в отдельном методе getFilenames() и данный метод вернёт экземпляр некоего класса, содержащего оба названия файлов:

import javax.swing.*;

public class Main {
    // класс-контейнер для данных, возвращаемых из диалога
    static class InputFiles {
        private final String fileOne, fileTwo;

        public InputFiles(String one, String two) {
           this.fileOne = one;
           this.fileTwo = two;
        }

        public String fileOne() { return fileOne; }
        public String fileTwo() { return fileTwo; }
    }   

    public static void main(String ... args) {
        InputFiles result = getFilenames();
        
        if (null == result) {
            System.out.println("File data not entered, exiting...");
            System.exit(0);
        }
        
        // обработка введенных данных
        System.out.println("Processing file1: " + result.fileOne());
        System.out.println("Processing file2: " + result.fileTwo());
    }
    
    private static InputFiles getFilenames() {
        JTextField pathOne = new JTextField();
        JTextField pathTwo = new JTextField();
        
        Object[] message = {
            "First file:  ", pathOne,
            "Second file: ", pathTwo
        };

        int option = JOptionPane.showConfirmDialog(null, message, "Input file names", JOptionPane.OK_CANCEL_OPTION);
        if (option == JOptionPane.OK_OPTION) {
            return new InputFiles(pathOne.getText(), pathTwo.getText());
        }
        return null;
    }
}

введите сюда описание изображения

F:\SO>java Main
Processing file1: aaa.csv
Processing file2: bbb.csv
→ Ссылка