3 Replies - 2454 Views - Last Post: 12 September 2012 - 06:44 AM Rate Topic: -----

#1 RedVillian  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 11-September 12

Waiting for user input via a JOptionPane within a JFrame

Posted 11 September 2012 - 10:59 PM

Hi! I'm a former coder trying to get back into it, and I'm having a terrible time dealing with waiting for user input. My JFrame is basically a large text area currently, and when user input is needed, I want the buttons to appear along the bottom of the screen. Once a button has been clicked, I want the buttons cleared and the text to continue outputting to the text area as it was previously.

This is the troublesome method:
static int getOption(String[] options){
        JOptionPane optionPane = new JOptionPane();

        JPanel panel = new JPanel();                          //create the dialog panel
        panel.setLayout(new GridLayout(options.length,1));
        JButton[] buttons = new JButton[options.length];
        for (int i = 0; i < options.length; i++)              //populate the panel with options
        {
            buttons[i] = new JButton(options[i]);
            panel.add(buttons[i]);
        }
        optionPane.setOptionType(JOptionPane.DEFAULT_OPTION);
        optionPane.add(panel,1);
        gui.add(optionPane);                                  //load it onto the gridBagLayout panel
        optionPane.setSelectionValues(null);
        optionPane.setWantsInput(true);
        
        Object selectedValue = optionPane.getValue();         //get input from the buttons
        
        gui.remove(optionPane);                               //dispose of the used button panel
        
        for(int counter = 0, maxCounter = options.length;     //find the chosen button and report it
           counter < maxCounter; counter++) {
           if(options[counter].equals(selectedValue))
           return counter;
        }
        return -1;                                            //else, report an error value
    }



I pass in my array of options, but the program just races right by the buttons such that they do not appear and the default input is used instead.

Not only that, if I take off the "remove(optionPane)" portion, I can see two more curious things: first that the option buttons appear behind the text area and that there is an additional "OK" button tagged onto my other buttons.

I don't think this is pertinent, but this is the rest of my code for both the GUI class:

package storyteller;

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

public class StorytellerGui extends JPanel implements ActionListener {
    public JTextArea textArea;
    public int input;
    public Object inputLock = new Object();
    
    public StorytellerGui() {
        super( new GridBagLayout());
        
        input = -1;
        
        textArea = new JTextArea(25, 50);
        textArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(textArea);
 
        GridBagConstraints c = new GridBagConstraints();
        c.gridwidth = GridBagConstraints.REMAINDER;
 
        c.fill = GridBagConstraints.BOTH;
        c.weightx = 1.0;
        c.weighty = 1.0;
        add(scrollPane, c);
    }
    
    protected void print(String s) {
        System.out.print(s);
        textArea.append(s);
        //gui.textArea.setCaretPosition(gui.textArea.getDocument().getLength());
    }
    
    public void actionPerformed(ActionEvent e) {
        //stub
    }

    void addButton(final int i, String text) {
        Button button = new Button(text);
        this.add(button);
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                input = i;
            }
        } );

    }

    int getInput() {
        return input;
    }
    
}



and for my main class:
package storyteller;

import java.io.*;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.awt.*;
import java.awt.event.*; 
import java.applet.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.JOptionPane; 

public class Storyteller {
    protected static JFrame frame;
        
    protected static StorytellerGui gui = new StorytellerGui();

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {  
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
                gui.print("Welcome to Storyteller\n\n");
                if ( checkSaves() ) { chooseSave(); }
                else { createCharacter(); };
            }
        });
    }

    /*
     * True if there are save files in the save directory
     */
    private static boolean checkSaves() {
        boolean areSaves = true;
        String saveDir = getSaveDir();
        
        if ( getSaves(saveDir).length == 0 ) {
            areSaves = false;
        };
        
        return areSaves;
    }
    
    /*
     * Returns an array of all Storyteller save Files in the directory provided
     */
    private static File[] getSaves( String dirName){
        File dir = new File(dirName);

        return dir.listFiles(new FilenameFilter() { 
                 public boolean accept(File dir, String filename)
                      { return filename.endsWith(".sts"); } 
        } );

    }

    private static void chooseSave() {
        File[] saves = getSaves(getSaveDir());
        
        gui.print("Do you want to start a new character? \n");
        String[] options = {"No", "Yes"};
        if (getOption(options) == 1) { createCharacter(); }
        
        else {
            gui.print("Select a file:\n");
            displaySaves(saves);
            gui.print("(Enter the number of the save file to open)... ");
        }
    }
    
    /*
     * Displays all save files found and when they were last modified
     * Requires a File array of save files
     */
    private static void displaySaves(File[] saves) {
        SimpleDateFormat sdf = new SimpleDateFormat("hh:mm, MMM d, yyyy");
        
        for (int i = 0; i < saves.length; i++) {
            gui.print( i+1 + ": " + saves[i].getName() + " - " + 
                   sdf.format( new Date( saves[i].lastModified() ) ) + "\n");
        }
    }
    
    /*
     * returns the save file directory
     * For now: it is the derectory where the jar is running
     */
    private static String getSaveDir() {
        return Storyteller.class.getProtectionDomain().getCodeSource().getLocation().getPath();
    }

    private static void createCharacter() {
        throw new UnsupportedOperationException("Not yet implemented");
    }
    
    /*
     * create and show the JFrame gui
     */
    private static void createAndShowGUI() {
    //Create and set up the window.
    frame = new JFrame("Storyteller");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Add contents to the window.
    frame.add(gui);

    //Display the window.
    frame.pack();
    frame.setVisible(true);
    }

    private static boolean getInput() {
        throw new UnsupportedOperationException("Not yet implemented");
    }
    
    static int getOption(String[] options){
        JOptionPane optionPane = new JOptionPane();

        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(options.length,1));
        JButton[] buttons = new JButton[options.length];
        for (int i = 0; i < options.length; i++)
        {
            buttons[i] = new JButton(options[i]);
            panel.add(buttons[i]);
        }
        optionPane.setOptionType(JOptionPane.DEFAULT_OPTION);
        optionPane.add(panel,1);
        gui.add(optionPane);
        optionPane.setSelectionValues(null);
        optionPane.setWantsInput(true);
        
        Object selectedValue = optionPane.getValue();
        
        gui.remove(optionPane);
        
        for(int counter = 0, maxCounter = options.length;
           counter < maxCounter; counter++) {
           if(options[counter].equals(selectedValue))
           return counter;
        }
        return -1;
    }
}



I know it's mostly stubs, so if there is a good tutorial for managing user input in Java, I'm not too proud for you to just say: "Hey, go look here, and figure it out yourself!"

Is This A Good Question/Topic? 0
  • +

Replies To: Waiting for user input via a JOptionPane within a JFrame

#2 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8343
  • View blog
  • Posts: 31,890
  • Joined: 06-March 08

Re: Waiting for user input via a JOptionPane within a JFrame

Posted 12 September 2012 - 05:29 AM

Never add/remove/add JComponent. Make them setVisible(false) if you do not want to show them.

In your actionPerformed() you set input = i;
but who informs the rest of the GUI that the value of input changed ?

Never seen adding a JOptionPane to a GUI... asctually wonder how you can do that
JOptionPane are Modal and appears in the top of a JFrame with the focus, they are not part of a underlying JFrame
Was This Post Helpful? 0
  • +
  • -

#3 RedVillian  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 11-September 12

Re: Waiting for user input via a JOptionPane within a JFrame

Posted 12 September 2012 - 05:47 AM

Yeah, I was afraid of that... I know how modal dialogs usually work, but I assumed that SURELY having them embedded in the same panel or frame should be possible.

As for that actionPerformed() method: more than anything that's a stub from a previous attempt. The JOptionPane should be listening for its own changes, though, I believe.

Lastly, I wouldn't add/remove and then add others, but I need the content to change. Would it be helpful to setVisible(false), then change the contents, then setVisible(true), instead? Seemed like a more cumbersome way of coding it.
Was This Post Helpful? 0
  • +
  • -

#4 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8343
  • View blog
  • Posts: 31,890
  • Joined: 06-March 08

Re: Waiting for user input via a JOptionPane within a JFrame

Posted 12 September 2012 - 06:44 AM

View PostRedVillian, on 12 September 2012 - 08:47 AM, said:

Lastly, I wouldn't add/remove and then add others, but I need the content to change. Would it be helpful to setVisible(false), then change the contents, then setVisible(true), instead? Seemed like a more cumbersome way of coding it.

This the way to do it. So you do not screw up the LayoutManager. It has just to handle if a component is visible or not, not where (like in a GridLayout) it should be displayed
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1