简体   繁体   中英

Java Get Selected Combobox from Another Class

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.

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();
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM