- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我制作了一个利用 JComboBox 的程序。我添加了一个项目监听器,如下所示:
wellbox.addItemListener(
new ItemListener(){
@Override
public void itemStateChanged(ItemEvent ie) {
if (ie.getStateChange() == ItemEvent.SELECTED){
well = (wellbox.getSelectedIndex()-1);
if (well >=0){selected = true;}
}
}
}
);
wellbox 是 JComboBox 变量well 是一个 int,selected 是一个 boolean。
现在,项目监听器在第一次执行时就可以工作,没有问题。但是,在程序结束时,我有一个选项提示用户是否要再次运行该程序。整个代码本质上包含在一个 while(true) 循环中,如果用户拒绝,他们不想再次运行,该循环就会中断。如果再次运行,项目监听器将停止工作,并且 getSelectedIndex() 不再返回所选索引。有谁知道为什么吗?
再次运行时,JCombo Box 会再次初始化
我希望我已经提供了足够的信息来获得解决方案。
更新:
根据建议,我会尽力更好地提出我的问题
我有三个 public void 方法
首次运行程序时,扩展 JFrame 的公共(public)“类名”方法会初始化第一个 part1 方法,该方法构建第一个 JPanel 并将其添加到 JFrame 中。单击按钮后,第一个 JPanel 将从 JFrame 中删除,第一个方法将我们带到第二个方法
在第二种方法中,构建了第二个 JPanel,并将其添加到 JFrame 中。单击另一个按钮后,第二个 JPanel 将从 JFrame 中删除,第二个方法将我们带到第三个方法
第三种方法构建第三个 JPanel 并将其添加到 JFrame 中。然后,一旦单击按钮,所有内容都会使用以下代码删除:
part1.removeAll();
part2.removeAll();
part3.removeAll();
第三种方法然后从 JFrame 中删除第三个 JPanel。如果用户单击表示希望再次运行的按钮,第三种方法将再次带我们到第一种方法,再次重建 JPanel 并添加它们...
在第二种方法中,在第二个 JPanel 中,我有一个 JComboBox 正在初始化并添加到第二个 JPanel 中。第一次,它按预期运行,项目监听器返回正确的索引。但是,如前所述,一旦再次运行,在删除所有内容然后重建之后,项目监听器将不再返回索引值。有谁知道为什么吗?
如果需要,这几乎是我的代码。任何我没有描述过的、我正在使用的方法都是不重要的。我取出了一堆与这个问题完全无关的代码。
主类:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class ReportCardGenerator {
public static void main(String[] args) {
debugReportGUI f = new debugReportGUI();
f.setVisible(true);
}
}
debugReportGUI 类
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.*;
public class debugReportGUI extends JFrame
{
JPanel part1 = new JPanel ();
JPanel part2 = new JPanel ();
JPanel part3 = new JPanel ();
JComboBox wellbox;
JButton cont = new JButton ("Continue");
int buttonW = 110, buttonL = 30, well = -1;
Actions AL = new Actions ();
String[] skills = {"", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};
public debugReportGUI ()
{
super ("JFrame");
setLayout (new BorderLayout ());
setSize (800, 700);
setLocationRelativeTo (null);
setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
setResizable (false);
add (part1, BorderLayout.CENTER);
Part1 ();
}
public void Part1 ()
{
part1.setLayout (null);
part1.add (cont);
cont.addActionListener (AL);
cont.setBounds (325, 630, buttonW, buttonL);
cont.setToolTipText ("Once all fields have been completed press to continue to next part of Generator");
}
private class Actions implements ActionListener
{
public void actionPerformed (ActionEvent ae)
{
if (ae.getSource () == cont)
{
part1.setVisible(false);
add (part2, BorderLayout.CENTER);
part2.setVisible (true);
Part2 ();
}
}
}
public void Part2 ()
{
part2.setLayout (null);
wellbox = new JComboBox (skills);
part2.add (wellbox);
wellbox.setLocation (75, 120);
wellbox.setSize (650, 40);
wellbox.addItemListener (
new ItemListener ()
{
//@ Override
public void itemStateChanged (ItemEvent ie)
{
if (ie.getStateChange () == ItemEvent.SELECTED)
{
well = (wellbox.getSelectedIndex () - 1);
System.out.println (well);
/*Initialized value of well is -1*/
}
}
}
);
JButton cont2 = new JButton ("Continue");
cont2.setBounds (345, 625, buttonW, buttonL);
cont2.setToolTipText ("When the skill for the ''well done'' comment and all failed items have been selected, press button ");
cont2.addActionListener (
new ActionListener ()
{
//@ Override
public void actionPerformed (ActionEvent ae)
{
if (well >= 0)
{
part2.setVisible(false);
add (part3, BorderLayout.CENTER);
part3.setVisible (true);
Part3 ();
}
else{
JOptionPane.showMessageDialog(null,"must select an option in the JComboBox","",JOptionPane.ERROR_MESSAGE);
}
}
}
);
part2.add (cont2);
}
public void Part3 ()
{
part3.setLayout (null);
JButton again = new JButton ("Write Another");
again.setBounds (530, 550, buttonW + 30, buttonL);
again.setToolTipText ("If you are finished with report card you can write another one for another student by clicking this button");
again.addActionListener (
new ActionListener ()
{
//@ Override
public void actionPerformed (ActionEvent ae)
{
well = -1;
part1.removeAll ();
part2.removeAll ();
part3.removeAll ();
remove (part3);
add (part1, BorderLayout.CENTER);
part1.setVisible (true);
Part1 ();
}
}
);
part3.add(again);
}
}
最佳答案
The entire code is essentially wrapped in a while(true) loop that breaks if the user says no, they do not want to run again.
虽然这对于简单的线性控制台(纯文本)程序来说很好,但这种结构不适用于事件驱动的程序。相反,您应该将 GUI 的组件重新设置为原始状态(如何执行此操作的详细信息将取决于程序的结构和组件,这是我们还不知道的事情)并摆脱该 while (true)
阻止。
If run again for a second time, the item listener stops working and the getSelectedIndex() is no longer returning the selected index.
我的猜测是您的引用资料不正确。当您重新运行代码时,显示的 JComboBox 与正在监听的 JComboBox 不同。为什么?很难说您到目前为止发布的信息,但您可能会创建一个新的 JComboBox,这会以某种方式导致引用解除关联。
I hope I have provided enough information to get a solution.
只是一个通用的解决方案,例如我上面发布的。如需更详细的解决方案,您需要创建并发布您的 Minimal, Complete, and Verifiable example .
<小时/>编辑:一个小型可运行程序,它使用上面发布的代码,但不会重现您遇到的问题。请注意,您的代码以及我对您的代码的推导存在一些不相关的问题,但我尚未修复:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class ReportGUI extends JFrame {
JPanel part1 = new JPanel();
JPanel part2 = new JPanel();
JPanel part3 = new JPanel();
// !! added
private JComboBox<String> wellbox;
protected int well;
protected boolean selected;
private String[] DUMMY_DATA = { "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday" };
public ReportGUI() {
super("Report Card Generator");
setLayout(new BorderLayout());
setSize(800, 700);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
// v.lvl = 10; add(part2, BorderLayout.CENTER); Part2();
add(part1, BorderLayout.CENTER);
Part1();
}
public void Part1() {
JButton nextPartBtn = new JButton("Next Part");
nextPartBtn.addActionListener(new Actions());
part1.add(nextPartBtn);
}
private class Actions implements ActionListener {
public void actionPerformed(ActionEvent ae) {
remove(part1);
add(part2, BorderLayout.CENTER);
part2.setVisible(true);
Part2();
//!!
revalidate();
repaint();
}
}
public void Part2() {
/* building JPanel part2 */
// !! wellbox = new JComboBox(v.wellskills[v.lvl]);
wellbox = new JComboBox<>(DUMMY_DATA);
part2.add(wellbox);
wellbox.setLocation(75, 120);
wellbox.setSize(650, 40);
wellbox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent ie) {
if (ie.getStateChange() == ItemEvent.SELECTED) {
well = (wellbox.getSelectedIndex() - 1);
System.out.println(well);
if (well >= 0) {
selected = true;
}
}
}
});
/* rest of building JPanel part2 */
//!!
JButton showPart3Btn = new JButton(new AbstractAction("Show Part 3") {
@Override
public void actionPerformed(ActionEvent arg0) {
remove(part2);
add(part3, BorderLayout.CENTER);
part3.setVisible(true);
Part3();
revalidate();
repaint();
}
});
part2.add(showPart3Btn);
}
public void Part3() {
/* building JPanel part3 */
part1.removeAll();
part2.removeAll();
part3.removeAll();
remove(part3);
add(part1, BorderLayout.CENTER);
// part1.setVisible(true);
Part1();
revalidate();
repaint();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ReportGUI().setVisible(true);
}
});
}
}
<小时/>
编辑
使用最新的代码,添加一些调试行,包括:
private class Actions implements ActionListener {
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == cont) {
ActionListener[] listeners = ((AbstractButton) cont).getActionListeners();
System.out.println("number of listeners added to cont: " + listeners.length);
part1.setVisible(false);
add(part2, BorderLayout.CENTER);
part2.setVisible(true);
Part2();
}
}
}
和
public void Part2() {
part2.setLayout(null);
wellbox = new JComboBox(skills);
System.out.println("wellbox created. hashcode: " + wellbox.hashCode());
part2.add(wellbox);
wellbox.setLocation(75, 120);
wellbox.setSize(650, 40);
wellbox.addItemListener(new ItemListener() {
// @ Override
public void itemStateChanged(ItemEvent ie) {
if (ie.getStateChange() == ItemEvent.SELECTED) {
System.out.println("wellbox state change. hashcode: " + wellbox.hashCode());
well = (wellbox.getSelectedIndex() - 1);
System.out.println(well);
}
}
});
当您运行此命令时,您将看到 cont 按钮未重新创建,并且添加了多个 ActionListener,因此显示的 JComboBox 不是经过测试的 JComboBox。我建议简化您的代码结构,并坚持下去......
<小时/>编辑2
下面是 MCVE 的一种更加 OOP 的实现,它使用 CardLayout。它仍然可以通过使其更加 MVC 风格来改进,将 View 与控制与模型分离:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
@SuppressWarnings("serial")
public class DebugReport2 extends JPanel {
private static final int PREF_W = 800;
private static final int PREF_H = 700;
public static final String PART_1 = "part 1";
public static final String PART_2 = "part 2";
public static final String PART_3 = "part 3";
private CardLayout cardLayout = new CardLayout();
private Part1Panel part1Panel = new Part1Panel(this);
private Part2Panel part2Panel = new Part2Panel(this);
private Part3Panel part3Panel = new Part3Panel(this);
public DebugReport2() {
setLayout(cardLayout);
System.out.println(Part1Panel.class.getName());
add(part1Panel, PART_1);
add(part2Panel, PART_2);
add(part3Panel, PART_3);
}
// public method to allow other classes to swap views
public void showCard(String key) {
cardLayout.show(this, key);
}
public void part2Reset() {
part2Panel.reset();
}
public void setPart3SelectedOptionText(String selectedItem) {
part3Panel.setSelectedOptionText(selectedItem);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
DebugReport2 mainPanel = new DebugReport2();
JFrame frame = new JFrame("Debug Report 2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
@SuppressWarnings("serial")
class BaseContinueAction extends AbstractAction {
private String key;
private DebugReport2 debugReport2;
public BaseContinueAction(String name, DebugReport2 debugReport2, String key) {
super(name);
int mnemnoic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemnoic); // first letter is mnemonic alt-key press.
this.key = key;
this.debugReport2 = debugReport2;
}
public String getKey() {
return key;
}
public DebugReport2 getDebugReport2() {
return debugReport2;
}
@Override
public void actionPerformed(ActionEvent e) {
debugReport2.showCard(key);
}
}
@SuppressWarnings("serial")
class Part1Panel extends JPanel {
private DebugReport2 debugReport2;
public Part1Panel(DebugReport2 debugReport2) {
this.debugReport2 = debugReport2;
setBorder(BorderFactory.createTitledBorder("Part 1 Panel")); // for debug purposes
JPanel bottomPanel = new JPanel();
bottomPanel.add(new JButton(new ContinueAction("Continue", debugReport2, DebugReport2.PART_2)));
setLayout(new BorderLayout());
add(bottomPanel, BorderLayout.SOUTH);
}
private class ContinueAction extends BaseContinueAction {
public ContinueAction(String name, DebugReport2 debugReport2, String key) {
super(name, debugReport2, key);
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
getDebugReport2().part2Reset();
}
}
}
@SuppressWarnings("serial")
class Part2Panel extends JPanel {
private static final String[] DEFAULT_DATA = {"0", "1", "2", "3", "4", "5", "6"};
private DebugReport2 debugReport2;
private ComboBoxModel<String> comboModel = new DefaultComboBoxModel<>();
private JComboBox<String> skillsCombo = new JComboBox<>(comboModel);
public Part2Panel(DebugReport2 debugReport2) {
((DefaultComboBoxModel<String>)comboModel).addElement("");
for (String item : DEFAULT_DATA) {
((DefaultComboBoxModel<String>)comboModel).addElement("Selection " + item);
}
this.debugReport2 = debugReport2;
setBorder(BorderFactory.createTitledBorder("Part 2 Panel")); // for debug purposes
JPanel centerPanel = new JPanel(); // uses default FlowLayout
centerPanel.add(skillsCombo);
JPanel bottomPanel = new JPanel(); // again default FlowLayout
bottomPanel.add(new JButton(new ContinueAction("Continue", debugReport2, DebugReport2.PART_3)));
setLayout(new BorderLayout());
add(centerPanel, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
// if you need outside classes to be able to change the combo box model
// also resets selected index to -1
public void setComboModel(ComboBoxModel<String> comboModel) {
// reset combobox selection to -1, but remove listeners before doing so, and then
// re-add them afterwards
ItemListener[] itemListeners = skillsCombo.getItemListeners();
for (ItemListener itemListener : itemListeners) {
skillsCombo.removeItemListener(itemListener);
}
this.comboModel = comboModel;
skillsCombo.setModel(comboModel);
skillsCombo.setSelectedIndex(-1);
for (ItemListener itemListener : itemListeners) {
skillsCombo.addItemListener(itemListener);
}
}
public void reset() {
ComboBoxModel<String> model = skillsCombo.getModel();
setComboModel(model);
}
private class ContinueAction extends BaseContinueAction {
private String selectedItem = "";
public ContinueAction(String name, DebugReport2 debugReport2, String key) {
super(name, debugReport2, key);
}
@Override
public void actionPerformed(ActionEvent e) {
selectedItem = (String) skillsCombo.getSelectedItem();
if (selectedItem == null || selectedItem.trim().isEmpty()) {
Component parent = debugReport2;
String title = "Option Not Selected";
String message = "You must select an option before continuing";
int type = JOptionPane.ERROR_MESSAGE;
JOptionPane.showMessageDialog(parent, message, title, type);
} else {
// show the next view in the card layout
super.actionPerformed(e);
getDebugReport2().setPart3SelectedOptionText(selectedItem);
}
}
}
}
@SuppressWarnings("serial")
class Part3Panel extends JPanel {
private DebugReport2 debugReport2;
private JTextField selectedOptionField = new JTextField(10);
public Part3Panel(DebugReport2 debugReport2) {
this.debugReport2 = debugReport2;
setBorder(BorderFactory.createTitledBorder("Part 3 Panel")); // for debug purposes
add(new JLabel("Selected Option:"));
add(selectedOptionField);
add(new JButton(new BaseContinueAction("Continue", debugReport2, DebugReport2.PART_1)));
}
public void setSelectedOptionText(String text) {
selectedOptionField.setText(text);
}
}
关于java - JComboBox getSelectedIndex 不工作两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32668254/
我正在尝试组合 2 个 jcomboboxes。 1 组合框用于显示费用类别。第二个组合框正在从文本文件中读取文件以显示产品类型。如果我更改第一个组合框,我希望第二个组合框会根据用户在第一个组合框中选
我希望一个 JComboBox 的值根据另一个 JComboBox 的值进行更改。在一个 JComboBox 中,我显示了从数据库检索的医生名称。根据该名称,我想在另一个 JComboBox 中显示医
我有课 public class Speciality { String specName; String eduProgram; } 和 TreeMap Map> treeM
我有一个 JComboBox。我希望它能够工作,以便如果选择某个项目(“其他”),立即在同一个组合框中显示更多项目(类似于子菜单,但在组合框内)。我很难让这个工作发挥作用。 有人对如何做到这一点有任何
如何从 JComboBox 中进行选择,删除或添加选择到另一个 JComboBox? 更具体地说,我有一个 JComboBox,其中包含一年中的月份作为选择。我还有另一个,里面有这个月的日子。虽然 3
我有一个用例(在 Java Swing 中),其中某个 JTable 列必须可以通过 JComboBox 编辑器进行编辑,但可选择的值列表取决于该行的域对象(我使用自定义 TableModel)。 C
我们可以在执行 jFrame 后根据点击另一个 jcomboBox 的项目来启用 jcomboBox 吗?这可能吗? 最佳答案 JComboBox comboBox_1 = new JComboBox
我有 7 个 jcombobox,它们都以相同的默认选择开头。如果在前面的 jcombobox 中选择了默认值以外的内容,如何启用下一个? if ( ! (custData1.equa
我有 2 个 JComboBox,在第一个 JComboBox 上选择一个项目后,第二个会从数据库中填充。问题是,每次我输入一个字母时,第二个 jcombobox 都会填充。我想让第二个 jcombo
您好,我正在尝试将一个对象从一个组合框传输到另一个组合框,反之亦然。为了实现这一目标,我使用 actionListeners 或 ItemListeners,不幸的是它们没有回答我的问题,或者可能只是
当我从 JComboBox A 中选择项目时,我尝试在 JComboBox B 中显示值。到目前为止,当我从 JComboBox A 中选择一个值时,没有任何反应。这是我的数据和代码。例如,如果我从
我写了这个简单的程序: import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.tab
我正在制作一个医疗药物软件程序,我希望用户能够从由类别数组填充的 jcombo 框中选择疾病类别(呼吸系统疾病、心血管疾病等)。 选择此类别后,我希望另一个 jcombobox 仅填充与该类别相关的药
这段代码很草率,我也欢迎一些反馈。 我正在尝试根据另一个 JComboBox 的值更改 JComboBox 的值。还有一个额外的复杂性,因为我使用一个额外的类来确定要返回的字符串数组(请参阅我之前的问
我已经加载了对象的 JComboBox,这些对象有自己的“toString”方法。该组合框用于选择并通过该组合框上的“ActionListener”返回该对象。一切工作正常,直到我决定添加通过在此组合
所以我的问题是 JComboBoxs 和 ActionListeners。我将制作一个新的简化代码来尝试代表我的原始代码中的问题。我想要一个 JComboBox 添加一个 JComboBox,然后 J
我的转换器程序中有 3 个 JCombobox,其中一个用于类别,两个用于选择要执行的功能;我希望程序做的是,当用户在一个 JCombobox 中选择一个类别时,两个 JCombobox 将自动更改与
所以,这就是问题所在:我需要 3 个或更多 jComboBox(都具有相同的项目)相互连接,这样当我在任何 jComboBox 中选择一个项目时,该项目将在所有其他 jComboBox 中消失。具体例
我用这样的东西制作了一个图形用户界面: String[] days29 = {"1",....."29"}; String[] days30 = {"1",....."30"}; String[] d
我有一个小应用程序,它通过 JPA 从 MySQL 数据库生成统计图表。为了选择要包含在统计信息中的数据库组件,我安装了 2 个 JComboBoxes。第一个 JComboBox 填充了 Categ
我是一名优秀的程序员,十分优秀!