JComboBox getSelectedIndex没有工作两次?

时间:2015-09-19 12:32:13

标签: java swing jcombobox itemlistener

所以我创建了一个使用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是一个布尔值。

现在,项侦听器第一次执行时没问题。但是,在程序结束时,我有一个选项,提示用户查看是否要再次运行程序。整个代码基本上包含在一个while(true)循环中,如果用户拒绝,它们就不会再次运行。如果再次运行,则项侦听器停止工作,并且getSelectedIndex()不再返回所选索引。有人知道为什么吗?

再次运行时,再次初始化JCombo Box btw

我希望我提供了足够的信息来获得解决方案。

更新:

根据建议,我会尝试更好地提出我的问题

我有三个公共无效方法

首次运行程序时,公共"类名称"扩展JFrame的方法初始化第一个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);
}
}

1 个答案:

答案 0 :(得分:2)

  

整个代码基本上都包含在while(true)循环中,如果用户拒绝,则会中断,他们不想再次运行。

虽然这对于简单的线性控制台(纯文本)程序来说很好,但这种构造对于事件驱动的程序不会很好。相反,您应该将GUI的组件重新设置为其原始状态(有关如何执行此操作的详细信息取决于程序的结构和组件,我们还不知道的事情)并删除{{1}阻止。

  

如果再次运行,则项侦听器停止工作,并且getSelectedIndex()不再返回所选索引。

我的猜测是你的错误引用。重新运行代码时,显示的JComboBox与正在侦听的代码不同。为什么?很难说你到目前为止发布的信息,但你可能会创建一个新的JComboBox,它会以某种方式导致引用的解除关联。

  

我希望我提供了足够的信息来获得解决方案。

只是一个通用的解决方案,例如我上面发布的。要获得更详细的解决方案,您需要创建并发布Minimal, Complete, and Verifiable example

编辑:一个小型的可运行程序,它使用上面发布的代码,但不能重现您遇到的问题。请注意,您的代码存在无关的问题以及我尚未修复的代码派生问题:

while (true)

修改

使用您的最新代码,添加一些调试行,包括:

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

当你运行它时,你会看到没有重新创建cont按钮并添加了多个ActionListener,因此显示的JComboBox不是被测试的那个。我建议简化你的代码结构,并坚持下去......

编辑2
这是MCVE的更多OOP实现,使用CardLayout。它仍然可以通过使其更多MVC-ish来改进,将视图与控件分离:

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