简体   繁体   English

Java从另一个类获取选定的组合框

[英]Java Get Selected Combobox from Another Class

newbie here. 新手在这里。 First I'm sorry if this post doesn't abide the rules of stackoverflow. 首先,很抱歉,如果这篇文章不遵守stackoverflow的规则。 I want to ask the same question (I think it has wrong answer) from 3 years ago from this source: stackoverflow source 我想从这个来源询问3年前的同一个问题(我认为答案有误): stackoverflow源

How to get the selected item of ComboBox from one class and use the value of that selected item in new class. 如何从一个类中获取ComboBox的选定项目,以及如何在新类中使用该选定项目的值。

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. 我想从其他类的源类中打印项目3(ComboBox中的第三项)。

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)? 当我使用javax.swing.JFrame(我使用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. 假设我在Source类中选择了Item 3。 So will it get item 3 at Other class? 那么它将在其他班级获得第3项吗? Or I do wrong constructor? 还是我做错构造函数? Sorry for the inconvenience. 抱歉给你带来不便。

I want to ask the same question (it has wrong answer) from 3 years ago ... 我想问3年前的同一个问题(答案有误)...

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. 如何从一个类中获取ComboBox的选定项目,以及如何在新类中使用该选定项目的值。

Again, Reimeus tells you how to do it correctly. 同样,Reimeus会告诉您如何正确进行操作。

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. 我想从其他类的源类中打印项目3(ComboBox中的第三项)。

Not sure what you mean by "item 3" , but if it's another selected item, again the answer you refer to is correct . 不知道"item 3"是什么意思,但是如果它是另一个选择的项目,那么您所指的答案也是正确的

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 . 它将为您提供一个全新的GUI参考,一个未显示的 GUI参考。 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: 例如:请注意,以下代码具有两个JButton,一个JButton在其ActionListener中正确地执行操作(实际上是AbstractAction,但具有相似的构造),而另一个错误地执行操作:

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. 在这里,我更改了用于JDialog的超级构造函数,使其具有APPLICATION_MODAL,具有上述行为。 The dialog is then opened inside the main window's butotn's ActionListener. 然后在主窗口的按钮的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. 我添加了一个名为SubmitButton的新JButton,它所做的只是关闭当前窗口。 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. 如果需要,您可以将ActionListener添加到JComboBox中,以便在做出选择后关闭它的窗口,但这不允许用户改变主意,因此我更喜欢使用提交按钮。

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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