s.matthew.english s.matthew.english - 1 month ago 5
Java Question

GUI dialog box that can accept user input as text or open a file to process

I'm trying to write a GUI dialogue box that will pop up when my programme starts and offer the user the option of inputting text, directly to a 'text input box' or alternatively to locate a text file somewhere on their machine.

The programme subsequently processes this input to determine what human language it's written in.

At this point I have this code which enables the user to choose a file, but it's not very easily navigable:

//GET THE USER INPUT

JFileChooser chooser = new JFileChooser();

int returnValue = chooser.showOpenDialog( null ) ;

File file = null;
if( returnValue == JFileChooser.APPROVE_OPTION )
{
file = chooser.getSelectedFile() ;
}
if(file != null)
{
String filePath = file.getPath();
}

//put the input in a useful way
Scanner s = new Scanner( file );
ArrayList<String> input_text = new ArrayList<String>();
while (s.hasNext()){
input_text.add(s.next());
}
s.close();


Before I was just having users input text to the console in this way:

Scanner in = new Scanner(System.in);

System.out.println("Please enter a sentence: ");

String[] input_text = in.nextLine().split("\\s");


or possibly like this:

Scanner scanner = new Scanner(System.in);
System.out.print("Enter a file name: ");
System.out.flush();
String filename = scanner.nextLine();
File file = new File(filename);


Is there a way to synthesize these two processes, the direct input of text & the selection of a file, into a single usable GUI?

Maybe it would be better to first have them choose if they want to use the file chooser or to input text- but that's so inelegant.

Answer

The short answer is "yes". The long answer, is a little more complicated

What you need is a component that is capable of asking the user where they would like the text to come from. While you could use a JComboBox, JRadioButtons make a better choice, as, depending on what the user selects, the way in which you get the text will be different.

Each time the user changes the selection, you can enable/disable the components based on your needs.

Finally, you provide a method by which, when the dialog is dismissed (hopefully by pressing [OK]), you can get the text...

Show me the text

This example uses Swing, but conceptually, it would work the same for any UI framework

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
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();
                }

                UserInputPane userInputPane = new UserInputPane();
                int result = JOptionPane.showConfirmDialog(null, userInputPane, "Sentence", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
                if (result == JOptionPane.OK_OPTION) {
                    try {
                        List<String> text = userInputPane.getText();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        });
    }

    public class UserInputPane extends JPanel {

        private JTextField fldText;
        private JTextField fldFileName;
        private JButton browseFileButton;

        private File selectedFile;

        private JRadioButton rbText;
        private JRadioButton rbFile;

        public UserInputPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();

            rbText = new JRadioButton("Text: ");
            rbFile = new JRadioButton("File: ");
            ButtonGroup bg = new ButtonGroup();
            bg.add(rbText);
            bg.add(rbFile);

            fldText = new JTextField(10);
            fldFileName = new JTextField(10);
            fldFileName.setEditable(false);
            browseFileButton = new JButton("...");

            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.WEST;
            add(rbText, gbc);
            gbc.anchor = GridBagConstraints.EAST;
            gbc.gridx++;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            add(fldText, gbc);

            gbc.gridwidth = 1;
            gbc.fill = GridBagConstraints.NONE;
            gbc.gridx = 0;
            gbc.gridy++;
            gbc.anchor = GridBagConstraints.WEST;
            add(rbFile, gbc);
            gbc.anchor = GridBagConstraints.EAST;
            gbc.gridx++;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            add(fldFileName, gbc);
            gbc.gridx++;
            gbc.fill = GridBagConstraints.NONE;
            add(browseFileButton, gbc);

            fldText.setEnabled(false);
            fldFileName.setEnabled(false);
            browseFileButton.setEnabled(false);

            ActionListener listener = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    fldText.setEnabled(rbText.isSelected());
                    fldFileName.setEnabled(!rbText.isSelected());
                    browseFileButton.setEnabled(!rbText.isSelected());

                    if (rbText.isSelected()) {
                        fldText.requestFocusInWindow();
                    }
                }
            };

            rbFile.addActionListener(listener);
            rbText.addActionListener(listener);

            browseFileButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    JFileChooser chooser = new JFileChooser();

                    int returnValue = chooser.showOpenDialog(null);

                    if (returnValue == JFileChooser.APPROVE_OPTION) {
                        selectedFile = chooser.getSelectedFile();
                        fldFileName.setText(selectedFile.getName());
                    }
                }
            });

        }

        public List<String> getText() throws IOException {
            List<String> text = new ArrayList<>(25);
            if (rbText.isSelected()) {
                text.add(fldText.getText());
            } else if (selectedFile != null) {

                try (BufferedReader br = new BufferedReader(new FileReader(selectedFile))) {
                    String value = null;
                    while ((value = br.readLine()) != null) {
                        text.add(value);
                    }
                }

            }
            return text;
        }

    }

}

Take a closer look at How to Use Buttons, Check Boxes, and Radio Buttons and How to Make Dialogs for more details