Java从另一个类中获取选定的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项吗? 或者我做错了构造函数? 抱歉给你带来不便。

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

不,那个答案完全正确。

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

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

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

不确定"item 3"是什么意思,但如果它是另一个选定的项目,那么你所指的答案也是正确的

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

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

例如:请注意以下代码有两个JButton,一个在其ActionListener中正确执行操作(实际上是一个AbstractAction,但是一个类似的构造),以及一个不正确地执行操作的JButton:

 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 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中打开对话框。 由于组合窗口是modal dialog – 程序在关闭之前不会从组合窗口中提取信息 – 这一点非常重要。 这样你的主程序就会得到用户的选择,而不是总是combobox中的第一项。 我添加了一个名为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 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(); } }