1

I have the following code to get 2 input from user through JCombo box, then I return the value s of the obtained input to the calling function but the problem is that this code displays the frame to obtain user input but before user can press the 'Ok' button it returns the null value to the calling function.I am looking to halt the code in this method till user presses 'Ok' button. Please suggest something.

package io;

import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener;
import java.awt.Insets; 
import java.io.FileNotFoundException;

public class SrcAndTargLangInput implements ActionListener {
    public static JFrame frame;
    public static JComboBox sourcLang;
    public static JComboBox targLang;
    public static JLabel setSrcLang;
    public static JLabel setTargLang;
    public static JButton ok;
    static String[] lang=new String[2];

    public SrcAndTargLangInput(){
        ok = new JButton("Ok");
        ok.setBounds(150,150,100,50);


        frame = new JFrame();
        frame.getContentPane().setLayout(null);

        frame.getContentPane().add(ok);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        Insets ins = frame.getInsets();
        frame.setSize(400+ins.left+ins.right, 200+ins.bottom+ins.top);
        setSrcLang=new JLabel("Source Language");
        frame.getContentPane().add(setSrcLang);
        setSrcLang.setBounds(50, 50, 100, 40);
        setTargLang=new JLabel("Target Language");
        frame.getContentPane().add(setTargLang);
        setTargLang.setBounds(50, 100, 100, 40);
        String[] srcLangList={"English","Spanish","French"};
        sourcLang = new JComboBox(srcLangList);
        frame.getContentPane().add(sourcLang);
        sourcLang.setBounds(250,50,100,40);
        String[] targLangList={"English","Spanish","French"};
        targLang = new JComboBox(targLangList);
        frame.getContentPane().add(targLang);
        targLang.setBounds(250,100,100,40);
        frame.setVisible(true);
        ok.addActionListener(this);

    }
    public static String[] langInfo(){
        SrcAndTargLangInput ob = new SrcAndTargLangInput();
        return lang;
    }

    public void actionPerformed(ActionEvent e){
        lang[0]=(sourcLang.getSelectedItem().toString());
        lang[1]=(targLang.getSelectedItem().toString());
        frame.setVisible(false);
    }
}

The calling function is :

String[] lg = new String[2];
lg = io.SrcAndTargLangInput.langInfo();
System.out.println(lg[0]);
System.out.println(lg[1]);
dic19
  • 17,821
  • 6
  • 40
  • 69

2 Answers2

0

In your code you can add a boolean variable with a default value as false.

In the actionPerformed method set that value to true. Update your logInfo method to make the thread sleep till no action is performed. Look at the code below.

import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.Insets; 
import java.io.FileNotFoundException;

public class SrcAndTargLangInput implements ActionListener {
    public static JFrame frame;
    public static JComboBox sourcLang;
    public static JComboBox targLang;
    public static JLabel setSrcLang;
    public static JLabel setTargLang;
    public static JButton ok;
    static String[] lang=new String[2];
    boolean actionPerformed = false;

    public SrcAndTargLangInput(){
        ok = new JButton("Ok");
        ok.setBounds(150,150,100,50);


        frame = new JFrame();
        frame.getContentPane().setLayout(null);

        frame.getContentPane().add(ok);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        Insets ins = frame.getInsets();
        frame.setSize(400+ins.left+ins.right, 200+ins.bottom+ins.top);
        setSrcLang=new JLabel("Source Language");
        frame.getContentPane().add(setSrcLang);
        setSrcLang.setBounds(50, 50, 100, 40);
        setTargLang=new JLabel("Target Language");
        frame.getContentPane().add(setTargLang);
        setTargLang.setBounds(50, 100, 100, 40);
        String[] srcLangList={"English","Spanish","French"};
        sourcLang = new JComboBox(srcLangList);
        frame.getContentPane().add(sourcLang);
        sourcLang.setBounds(250,50,100,40);
        String[] targLangList={"English","Spanish","French"};
        targLang = new JComboBox(targLangList);
        frame.getContentPane().add(targLang);
        targLang.setBounds(250,100,100,40);
        frame.setVisible(true);
        ok.addActionListener(this);

    }
    public static String[] langInfo() throws InterruptedException{
        SrcAndTargLangInput ob = new SrcAndTargLangInput();
        while(!ob.actionPerformed) {
            Thread.sleep(1000);
        }
        return lang;
    }

    public void actionPerformed(ActionEvent e){
        lang[0]=(sourcLang.getSelectedItem().toString());
        lang[1]=(targLang.getSelectedItem().toString());
        actionPerformed = true;
        frame.setVisible(false);
        Thread.currentThread().interrupt();
    }
}
jsjunkie
  • 559
  • 3
  • 7
  • 2
    there are 2 mistakes in your code, *1st* **dont** recommend using `null layout` instead recommend a [Layout Manager](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html). *2nd* avoid using `Thread.sleep()` instead use [`Timers`](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html). And *extra*, for `ActionListeners` don't use timers till something happens, instead, use events. This goes for OP: [How to add `ActionListener` to a `JButton`](http://stackoverflow.com/questions/284899/how-do-you-add-an-actionlistener-onto-a-jbutton-in-java) – Frakcool Jul 03 '14 at 19:41
0

Based on these lines:

String[] lg = new String[2];
lg = io.SrcAndTargLangInput.langInfo();

The problem is your SrcAndTargLangInput class uses a JFrame to ask the user for the input. Having said this, JFrame is not modal and thus it doesn't block the current thread waiting for an input as you wish. You have to use a modal JDialog or JOptionPane(which displays a modal dialog) instead in order to wait until users confirm their input.

Take a look to these topics:

Off-topic

As many developers have already said, Swing is designed to be used with Layout Managers and you should avoid methods such as setBounds(), setLocation() or setSize(). You may want to take a look to these topics too:

Example (using JOptionPane)

Note the text field's text doesn't change until you confirm your input.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Demo {

    private void createAndShowGui() {

        final JTextField textField = new JTextField(10);
        textField.setEditable(false);

        JButton button = new JButton("Show dialog");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JComboBox languagesComboBox = new JComboBox(new Object[]{"English","Spanish","French"});
                JPanel dialogPanel = new JPanel();
                dialogPanel.add(new JLabel("Please select an option:"));
                dialogPanel.add(languagesComboBox);

                int option = JOptionPane.showConfirmDialog(null, dialogPanel, "Select an input"
                                                        , JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);

                if(option == JOptionPane.OK_OPTION) {
                    String selectedInput = (String)languagesComboBox.getSelectedItem();
                    textField.setText(selectedInput);
                }
            }
        });


        JPanel content = new JPanel();
        content.add(new JLabel("User input:"));
        content.add(textField);
        content.add(button);

        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }


    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().createAndShowGui();
            }
        }); 
    }

}
Community
  • 1
  • 1
dic19
  • 17,821
  • 6
  • 40
  • 69