新手在这里。首先,如果这篇文章不符合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项吗?或者我做错了构造函数?很抱歉给您带来不便。
答案 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();
}
}