Java从另一个类中获取选定的Combobox

时间:2016-01-01 03:31:48

标签: java swing combobox

新手在这里。首先,如果这篇文章不符合stackoverflow的规则,我很抱歉。我想从3年前从这个来源问同样的问题(我认为它有错误的答案): stackoverflow source

如何从一个类中获取所选的ComboBox项,并在新类中使用该选定项的值。

让我们说,源类和其他类。我想从其他类的源类打印项目3(ComboBox中的第三项)。

我已经使用了上面的答案。然而,它只返回第一个项目。因为我认为每次从源类调用构造函数时,它都会将所选项重新启动到第一项。

当我使用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();
}

另一堂课:

public class Other extends javax.swing.JFrame{

public Other(){

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

System.out.println(var);
}
}

假设我在Source类中选择了Item 3。那么它会在其他课上获得第3项吗?或者我做错了构造函数?很抱歉给您带来不便。

1 个答案:

答案 0 :(得分:2)

  

我想问3年前同样的问题(它有错误的答案)......

不,答案完全正确。

  

如何从一个类中获取ComboBox的选定项目,并在新类中使用该选定项目的值。

再一次,Reimeus告诉你如何正确地做到这一点。

  

让我们说,源类和其他类。我想从其他类的源类打印项目3(ComboBox中的第三项)。

不确定"item 3"的含义,但是如果它是另一个选定的项目,那么您所指的答案是正确的

  

我已经使用了上面的答案。然而,它只返回第一个项目。因为我认为每次从源类调用构造函数时,它都会将所选项重新启动到第一项。

这正是你的问题 - 你不应该重新调用构造函数,因为这会给你错误的引用。它将为您提供一个全新的GUI参考,一个是未显示的GUI。您需要引用当前查看的感兴趣的类。你如何做到这将取决于你的程序结构 - 请显示更多。

例如:请注意以下代码有两个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();
    }

}

修改
阅读完最新帖后,我现在看到您正在尝试打开包含组合窗口的窗口作为一个窗口,呈现给用户以获取主程序在运行时使用的信息。在这种情况下,最好的办法是使用 模态 对话框,这是一个对话框,在对话框打开后冻结主窗口中的程序流,而不是在对话框打开时允许用户与主窗口交互,然后在关闭对话窗口时恢复程序流和用户交互。

请查看下面我的示例程序的更改。在这里,我使用上述行为更改用于JDialog的超级构造函数,使其成为APPLICATION_MODAL。然后在主窗口的butotn的ActionListener中打开对话框。由于组合窗口是模态对话框 - 程序在关闭之前不会从组合窗口中提取信息 - 这一位非常很重要。这样你的主程序就会得到用户的选择,而不是总是组合框中的第一项。我添加了一个名为submitButton的新JButton,它只关闭当前窗口。如果需要,您可以将ActionListener添加到JComboBox,以便在进行选择时关闭其窗口,但这不允许用户改变主意,所以我更喜欢使用提交按钮。

请注意,更改标有\\ !!条评论。

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

}