0

newbie here. First I'm sorry if this post doesn't abide the rules of stackoverflow. I want to ask the same question (I think it has wrong answer) from 3 years ago from this source: stackoverflow source

How to get the selected item of ComboBox from one class and use the value of that selected item in new class.

Let's say, source class and other class. I want to print item 3 (third item in a ComboBox) from source class at other class.

I already used the answer from above source. Yet, it only return the first item. Because I think each time I call the constructor from the source class, it will restarted the selected item to the first item.

How to do it when I'm using javax.swing.JFrame (I use Netbeans)?

public class Source extends javax.swing.JFrame{

final JComboBox test = new JComboBox();
test.setModel(new DefaultComboBoxModel(new String[] {"Item 1", "Item 2", "Item 3"}));

...

public String getSelectedItem() {
   return (String) test.getSelectedItem();
}

The other class:

public class Other extends javax.swing.JFrame{

public Other(){

Source sc = new Source();
String var = sc.getSelectedItem();

System.out.println(var);
}
}

Let's say I chose Item 3 at Source class. So will it get item 3 at Other class? Or I do wrong constructor? Sorry for the inconvenience.

Community
  • 1
  • 1
Arbintoro Mas
  • 47
  • 2
  • 8

1 Answers1

2

I want to ask the same question (it has wrong answer) from 3 years ago ...

No, that answer was completely right.

How to get the selected item of ComboBox from one class and use the value of that selected item in new class.

Again, Reimeus tells you how to do it correctly.

Let's say, source class and other class. I want to print item 3 (third item in a ComboBox) from source class at other class.

Not sure what you mean by "item 3", but if it's another selected item, again the answer you refer to is correct.

I already used the answer from above source. Yet, it only return the first item. Because I think each time I call the constructor from the source class, it will restarted the selected item to the first item.

And that's exactly your problem -- you shouldn't be re-calling constructors as that will give you the wrong reference. It will give you a completely new GUI reference, one to a GUI that is not displayed. You need the reference to the currently viewed class of interest. How you do this will depend on the structure of your program -- please show more.

For example: note the following code has two JButtons, one that does thing correctly within its ActionListener (actually, an AbstractAction, but a similar construct), and one that does things incorrectly:

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class GetCombo extends JFrame {
    // the displayed ClassWithCombo object
    private ClassWithCombo classWithCombo = new ClassWithCombo(this);;
    private int columns = 10;
    private JTextField textField1 = new JTextField(columns);
    private JTextField textField2 = new JTextField(columns);

    public GetCombo() {
        classWithCombo.pack();
        classWithCombo.setLocationByPlatform(true);
        classWithCombo.setVisible(true);

        setLayout(new FlowLayout());

        add(textField1);
        add(new JButton(new AbstractAction("Doing It Right") {

            @Override
            public void actionPerformed(ActionEvent e) {
                // use the ClassWithCombo reference that is already displayed
                String selectedString = classWithCombo.getSelectedItem();
                textField1.setText(selectedString);
            }
        }));
        add(textField2);
        add(new JButton(new AbstractAction("Doing It Wrong") {

            @Override
            public void actionPerformed(ActionEvent e) {
                // create a new non-displayed ClassWithCombo reference.
                ClassWithCombo classWithCombo = new ClassWithCombo(GetCombo.this);
                String selectedString = classWithCombo.getSelectedItem();
                textField2.setText(selectedString);
            }
        }));
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            GetCombo getCombo = new GetCombo();
            getCombo.setTitle("Get Combo Example");
            getCombo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            getCombo.pack();
            getCombo.setLocationRelativeTo(null);
            getCombo.setVisible(true);
        });
    }
}

@SuppressWarnings("serial")
class ClassWithCombo extends JDialog {
    private static final String[] DATA = { "Mon", "Tues", "Wed", "Thurs", "Fri" };
    private JComboBox<String> combo = new JComboBox<>(DATA);

    public ClassWithCombo(JFrame frame) {
        super(frame, "Holds Combo Dialog", ModalityType.MODELESS);
        setLayout(new FlowLayout());
        setPreferredSize(new Dimension(300, 250));
        add(combo);
    }

    public String getSelectedItem() {
        return (String) combo.getSelectedItem();
    }

}


Edit
After reading your latest post, I now see that you are trying to open the combo containing window as a window that is presented to the user to get information from to be used by the main program as it's running. In this situation your best bet is to use a modal dialog, that is a dialog that freezes program flow in the main window after the dialog has been opened, that doesn't allow user interaction with the main window while the dialog has been open, and that then resumes program flow and user interaction when the dialog window has been closed.

Please look at the changes to my example program below. Here I change the super constructor used for the JDialog to make it APPLICATION_MODAL, with the behaviors described above. The dialog is then opened inside the main window's butotn's ActionListener. Since the combo window is a modal dialog -- the program doesn't extract information from the combo window until it has been closed -- this bit is very important. And this way your main program gets the user's selection and not always the first item in the combobox. I've added a new JButton called the submitButton, that all it does is close the current window. If desired you could instead add the ActionListener to the JComboBox so that it closes its window when a selection has been made, but this doesn't allow the user to change his mind, so I prefer using a submit button.

Please note changes are marked by a \\ !! comment.

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class GetCombo2 extends JFrame {
    // the displayed ClassWithCombo object
    private ClassWithCombo classWithCombo = new ClassWithCombo(this);;
    private int columns = 10;
    private JTextField textField1 = new JTextField(columns);

    public GetCombo2() {
        classWithCombo.pack();
        classWithCombo.setLocationByPlatform(true);

        // !! don't do this here
        // classWithCombo.setVisible(true);

        setLayout(new FlowLayout());

        textField1.setFocusable(false);
        add(textField1);
        add(new JButton(new AbstractAction("Open Combo as a Dialog") {

            @Override
            public void actionPerformed(ActionEvent e) {
                // open combo dialog as a **modal** dialog:
                classWithCombo.setVisible(true);

                // this won't run until the dialog has been closed
                String selectedString = classWithCombo.getSelectedItem();
                textField1.setText(selectedString);
            }
        }));
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            GetCombo2 getCombo = new GetCombo2();
            getCombo.setTitle("Get Combo Example");
            getCombo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            getCombo.pack();
            getCombo.setLocationRelativeTo(null);
            getCombo.setVisible(true);
        });
    }
}

@SuppressWarnings("serial")
class ClassWithCombo extends JDialog {
    private static final String[] DATA = { "Mon", "Tues", "Wed", "Thurs", "Fri" };
    private JComboBox<String> combo = new JComboBox<>(DATA);

    public ClassWithCombo(JFrame frame) {
        // !! don't make it MODELESS
        // !! super(frame, "Holds Combo Dialog", ModalityType.MODELESS);
        // !! note the change. Made it APPLICATION_MODAL
        super(frame, "Holds Combo Dialog", ModalityType.APPLICATION_MODAL);

        JButton submitButton = new JButton(new AbstractAction("Submit") {
            // !! add an ActionListener to close window when the submit button
            // has been pressed.

            @Override
            public void actionPerformed(ActionEvent e) {
                ClassWithCombo.this.setVisible(false);
            }
        });

        setLayout(new FlowLayout());
        setPreferredSize(new Dimension(300, 250));
        add(combo);
        add(submitButton);
    }

    public String getSelectedItem() {
        return (String) combo.getSelectedItem();
    }

}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Thank you. Sorry for my bad post (still learning). I already edited it. How is it? – Arbintoro Mas Jan 01 '16 at 04:14
  • @ArbintoroMas: I can't compile and run your posted code, so I can't tell you how to fix it. The key is understanding what a reference is -- you **must** call the `getSelectedItem()` method (per Reimeus's answer) on a reference that refers to the visualized GUI that holds the JComboBox. A good test to see that you're doing this right is that `new Source()` should only appear once in your whole combined program. If you're seeing it more than once, then you're likely doing things wrong. – Hovercraft Full Of Eels Jan 01 '16 at 04:21
  • @ArbintoroMas: please see code example added to answer. And don't use two JFrames since your GUI should have only one JFrame. If you have multiple windows, one should be a JFrame and the other JDialogs. – Hovercraft Full Of Eels Jan 01 '16 at 04:38
  • So I must not use two JFrames sir? I already posted the compile able code below. I use two JFrames because I'm using Netbeans. Sorry before for the inconvenience. *I'm checking your code example (thank you) – Arbintoro Mas Jan 01 '16 at 04:49
  • @ArbintoroMas: please note edit to answer. Also note that your "answer" should not be posted as an answer since that is not what it is. Instead you should edit your main question and provide this information in there. Also please avoid asking anyone to correct your code. We are volunteers and like to help you correct your code, but we're not here to write code for you. Hopefully my answer will help you do just this. – Hovercraft Full Of Eels Jan 01 '16 at 13:27
  • @ArbintoroMas: Also, in the future, please try to include all pertinent information with your original question. There really was no reason this was made into two questions as it could have been answered quickly and correctly had you supplied all we need to know to understand the problem right from the beginning. – Hovercraft Full Of Eels Jan 01 '16 at 13:59
  • Sorry I didn't connect to internet for 2 days sir. I already followed your code and I'm following sir Mayur for another question. You suggest using JDialog and in the other post, MadProgrammer suggest using JPanel. I'm still a newbie and still learning sir I'm sorry. But thanks to you two, I figured how to get my apps done with your help. Thank you very much sir. And I'm very sorry for my misbehaviour. – Arbintoro Mas Jan 03 '16 at 18:35