您好,我如何从多个JComboBox获取int值并在JTextBox中设置这些数字的总和

时间:2018-03-18 12:48:19

标签: java swing jtextfield jcombobox

这是我正在处理的代码示例。我可以得到JComboBox中包含的数字,但我有问题将它们的总和添加到JtextField

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JComboBox;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JTextField;
import java.awt.Color;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import javax.swing.event.PopupMenuListener;
import javax.swing.event.PopupMenuEvent;

public class Sample {

  private JFrame frame;

  public JTextField totalVal;

  public int valASet;

  public int valBSet;

  public int totalSum;

  /* Launch the application.
   */
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        try {
          Sample window = new Sample();
          window.frame.setVisible(true);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }

  /**
   * Create the application.
   */
  public Sample() {
    initialize();
  }

  /**
   * Initialize the contents of the frame.
   */
  private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 425, 185);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setLayout(null);

    JPanel Panel = new JPanel();
    Panel.setBorder(new LineBorder(new Color(0, 0, 0), 2, true));
    Panel.setBounds(121, 41, 211, 42);
    frame.getContentPane().add(Panel);
    Panel.setLayout(null);

将JComboBox#1的值赋予第一个整数var

    JComboBox valA = new JComboBox();
    valA.addPopupMenuListener(new PopupMenuListener() {
      public void popupMenuCanceled(PopupMenuEvent e) {}
      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
        String valANum = (String) valA.getSelectedItem();
        valASet = Integer.parseInt(valANum);

      }
      public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
    });

将JComboBox#2的值赋予第二个整数var

    JComboBox valB = new JComboBox();
    valB.addPopupMenuListener(new PopupMenuListener() {
      public void popupMenuCanceled(PopupMenuEvent e) {}
      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
        String valBNum = (String) valB.getSelectedItem();
        valBSet = Integer.parseInt(valBNum);

      }
      public void popupMenuWillBecomeVisible(PopupMenuEvent e) {}
    });
    valA.setModel(new DefaultComboBoxModel(new String[] {
      "0",
      "1",
      "2",
      "3",
      "4"
    }));
    valA.setBounds(77, 11, 57, 20);
    Panel.add(valA);

尽管totalSum识别+10 int值,但它不会添加其他两个变量。

    totalVal = new JTextField();
    totalVal.setEditable(false);
    totalVal.setBounds(10, 11, 57, 20);
    Panel.add(totalVal);
    totalSum = valASet + valBSet + 10;
    String totalString = Integer.toString(totalSum);
    totalVal.setText(totalString);
    totalVal.setColumns(10);


    valB.setModel(new DefaultComboBoxModel(new String[] {
      "0",
      "1",
      "2",
      "3",
      "4"
    }));
    valB.setBounds(144, 11, 57, 20);
    Panel.add(valB);
  }
}

1 个答案:

答案 0 :(得分:1)

当前代码中的任何位置都没有对值进行任何求和,这需要在事件监听器中完成 - 它需要在用户更改其中一个GUI的JComboBox的状态时发生。

您需要为每个JComboBox添加一个ActionListener,并且相同的侦听器将起作用。在侦听器中,您只需遍历JComboBox,提取它们保存的值,使用它来更新sum变量,然后设置JTextField。最好将JComboBox放入ArrayList中,以便更轻松地执行此迭代。例如,像这样的MCVE

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.*;

@SuppressWarnings("serial")
public class Sample2 extends JPanel {
    private static final int COMBO_COUNT = 6;
    private static final Integer[] ITEMS = {0, 1, 2, 3, 4};

    // ArrayList that holds all JComboBoxes
    private List<JComboBox<Integer>> combos = new ArrayList<>();
    private JTextField resultField = new JTextField(10);

    public Sample2() {
        resultField.setFocusable(false); // don't allow editing of this

        // single ActionListener added to all JComboBoxes
        ActionListener comboListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int sum = 0;
                // iterate through the list, adding the values
                for (JComboBox<Integer> jComboBox : combos) {
                    Integer selection = (Integer) jComboBox.getSelectedItem();
                    sum += selection == null ? 0 : selection;
                }
                resultField.setText(String.valueOf(sum));
            }
        };
        add(resultField);

        for (int i = 0; i < COMBO_COUNT; i++) {
            JComboBox<Integer> combo = new JComboBox<>(new DefaultComboBoxModel<>(ITEMS));
            // add the ActionListener to the combo box
            combo.addActionListener(comboListener);
            // add the combo box to the list
            combos.add(combo);
            // add it to the GUI
            add(combo);
        }
    }

    private static void createAndShowGui() {
        Sample2 mainPanel = new Sample2();

        JFrame frame = new JFrame("Sample2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

另外,一个侧面问题:你应该避免使用null布局和使用setBounds(...)进行组件放置,因为这会使GUI非常不灵活,虽然它们在一个平台上看起来很好但在大多数其他平台上看起来很糟糕屏幕分辨率很难更新和维护。

那么为什么要经历这个布局管理器呢?假设我想“美化”我的GUI并让它看起来有点像你的,JTextField和JComboBoxes周围的内边框,我可以通过嵌套JPanels,使用布局(参见注释)来做到这一点:

import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;

@SuppressWarnings("serial")
public class Sample2 extends JPanel {
    private static final int COMBO_COUNT = 6;
    private static final Integer[] ITEMS = { 
            -10, -9, -8, -7, -6, 
            -5, -4, -3, -2, -1, 
            0, 1, 2, 3, 4, 5, 
            6, 7, 8, 9, 10 };
    private static final int GAP1 = 15;
    private static final int GAP2 = 30;
    private static final int TXTFLD_COLS = 5;

    // ArrayList that holds all JComboBoxes
    private List<JComboBox<Integer>> combos = new ArrayList<>();
    private JTextField resultField = new JTextField("0", TXTFLD_COLS);

    public Sample2() {
        // inner JPanel to hold the JComboBoxes and text field
        // give it a grid layout, 1 row, variable # cols
        JPanel innerPanel = new JPanel(new GridLayout(1, 0, GAP1/2, 0));
        // give it a line border with some padding 
        Border outerBorder = BorderFactory.createLineBorder(Color.BLUE);
        Border innerBorder = BorderFactory.createEmptyBorder(GAP1, GAP1, GAP1, GAP1);
        Border combinedBorder = BorderFactory.createCompoundBorder(outerBorder, innerBorder);

        innerPanel.setBorder(combinedBorder);
        resultField.setFocusable(false); // don't allow editing of this

        // single ActionListener added to all JComboBoxes
        ActionListener comboListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                int sum = 0;
                // iterate through the list, adding the values
                for (JComboBox<Integer> jComboBox : combos) {
                    Integer selection = (Integer) jComboBox.getSelectedItem();
                    sum += selection == null ? 0 : selection;
                }
                resultField.setText(String.valueOf(sum));
            }
        };
        innerPanel.add(resultField);

        for (int i = 0; i < COMBO_COUNT; i++) {
            JComboBox<Integer> combo = new JComboBox<>(new DefaultComboBoxModel<>(ITEMS));
            combo.setSelectedItem(0);
            // add the ActionListener to the combo box
            combo.addActionListener(comboListener);
            // add the combo box to the list
            combos.add(combo);
            // add it to the GUI
            innerPanel.add(combo);
        }

        // GridBagLayout is one way to allow us to add 
        // the inner JPanel in the very center
        setLayout(new GridBagLayout());
        setBorder(BorderFactory.createEmptyBorder(GAP2, GAP2, GAP2, GAP2));
        add(innerPanel);
    }

    private static void createAndShowGui() {
        Sample2 mainPanel = new Sample2();

        JFrame frame = new JFrame("Sample2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

现在说我想将JComboBox的数量从6改为10.如果我设置了界限,我必须使用绝对位置和大量组件的大小,使得一堆不必要的额外工作增加错误/错误的风险。但是使用我的代码,我需要更改单行,更改此内容:

private static final int COMBO_COUNT = 6;

创建:

small GUI

到此:

private static final int COMBO_COUNT = 10;

创建了这个:

enter image description here

布局经理会为我做所有的事情。