在ActionListener之外访问JButton ActionListener内部所做的更改

时间:2015-05-30 21:35:53

标签: java swing jbutton actionlistener jcombobox

我将稍微解释一下我的代码:

我有一个带有项目列表的JComboBox 当按下JButton“Select”时,它会记录JComboBox中最后一个选定项的最后一个索引。

现在我需要在main中访问这个索引。

这是我的代码:

public static final JComboBox c = new JComboBox();

private static final JButton btnNewButton = new JButton("Select");

JButton ActionListener是:

btnNewButton.addActionListener(new ActionListener(){

  public void actionPerformed(ActionEvent e)
  {
       ind = c.getSelectedIndex();
        frame.setVisible(false);
    }
  });      

因此按下按钮后,框架关闭

但是现在当我尝试通过

访问main中的ind时
public static void main(String[] args) {
System.out.println(ind);}

我得到的返回值为ind = 0

我知道这是因为它已被初始化为0

static ind = 0 

但是,如何在JButton ActionListener之外访问此索引?

我需要在我的代码中进一步使用此索引。

修改

这是我的MCVE

import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SpringLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.UIManager;

public class MinimalExProgram
{
private static String[] description = { "One", "Two", "Three"};

static int ind;

public static final JComboBox c = new JComboBox(description);

private static final JButton btnNewButton = new JButton("Select");


public static void main(String[] args) {

JFrame frame = new JFrame();
frame.getContentPane().setForeground(UIManager.getColor("ComboBox.disabledBackground"));
frame.getContentPane().setBackground(UIManager.getColor("EditorPane.disabledBackground"));
SpringLayout springLayout = new SpringLayout();
springLayout.putConstraint(SpringLayout.NORTH, btnNewButton, 5, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, c, -6, SpringLayout.WEST, btnNewButton);
springLayout.putConstraint(SpringLayout.EAST, btnNewButton, -10, SpringLayout.EAST, frame.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, c, 6, SpringLayout.WEST, frame.getContentPane());
springLayout.putConstraint(SpringLayout.NORTH, c, 6, SpringLayout.NORTH, frame.getContentPane());
frame.getContentPane().setLayout(springLayout);
frame.setSize(500, 150);
frame.setLocation(400, 200);
frame.setResizable(false);
c.setBackground(UIManager.getColor("ComboBox.disabledBackground"));


btnNewButton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e)
{
      System.out.print("What I want:");
      ind = c.getSelectedIndex();
      System.out.println(ind);
        frame.setVisible(false);
}
});      

frame.getContentPane().add(c);
btnNewButton.setForeground(UIManager.getColor("ComboBox.buttonDarkShadow"));
btnNewButton.setBackground(UIManager.getColor("EditorPane.disabledBackground    "));

frame.getContentPane().add(btnNewButton);
frame.setVisible(true);
System.out.print("What I get: ");
System.out.println(ind);
}
}

如前所述,我需要访问main中的ind 在我打印出ind时,尽管我在组合框内做出了任何选择,但我得到零。

1 个答案:

答案 0 :(得分:4)

好的,我猜是因为你还没有向我们展示足够的信息来做更多的事情,但我假设

  • 您正在显示第二个窗口作为主窗口的对话框
  • 这个第二个窗口是一个JFrame,它包含你的JComboBox和按钮
  • 你按下按钮,使其不可见
  • 你试图从组合框中获取信息,但它总是0
  • 这可能是因为您在用户有机会与第二个窗口进行互动之前获取信息。

如果是这样,解决方案是使第二个窗口成为模态 对话框窗口,例如模态JDialog而不是JFrame。这样,调用代码将准确知道第二个窗口何时不再可见,因为调用代码的代码流将被阻塞,直到第二个窗口不再可见。

修改

概念验证:更改您的代码:

  final JFrame frame = new JFrame();

为:

  // rename frame variable to dialog for clarity
  final JDialog dialog = new JDialog();
  dialog.setModalityType(ModalityType.APPLICATION_MODAL);

它有效。

但是,我再次摆脱了不必要的静态,并摆脱了在主方法中做太多代码。例如,......

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;

@SuppressWarnings("serial")
public class MinimalExProgram3 extends JPanel {
   private static void createAndShowGui() {
      MainPanel mainPanel = new MainPanel();

      JFrame frame = new JFrame("MinimalExProgram3");
      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 MainPanel extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;
   private JTextField field = new JTextField(8);
   private ComboPanel comboPanel = new ComboPanel();
   JDialog dialog = null;

   public MainPanel() {
      field.setFocusable(false);

      add(field);
      add(new JButton(new ShowComboAction("Show Combo")));
   }

   @Override // make it bigger
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class ShowComboAction extends AbstractAction {
      public ShowComboAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         Window mainWin = SwingUtilities.getWindowAncestor(MainPanel.this);
         if (dialog == null) {
            dialog = new JDialog(mainWin, "Dialog", ModalityType.APPLICATION_MODAL);
            dialog.add(comboPanel);
            dialog.pack();
            dialog.setLocationRelativeTo(null);
         }

         dialog.setVisible(true);

         // code called here after dialog no longer visible
         String text = comboPanel.getText();
         field.setText(text);
      }
   }
}

@SuppressWarnings("serial")
class ComboPanel extends JPanel {
   private static final String[] DESCRIPTION = { "One", "Two", "Three" };
   private int ind;
   private JComboBox<String> combo = new JComboBox<>(DESCRIPTION);
   private String text;
   private SelectionAction selectionAction = new SelectionAction("Select");
   private JButton selectionButton = new JButton(selectionAction);

   public ComboPanel() {
      add(combo);
      add(selectionButton);

      combo.setAction(selectionAction);
   }

   public int getInd() {
      return ind;
   }

   public String getText() {
      return text;
   }

   private class SelectionAction extends AbstractAction {
      public SelectionAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         ind = combo.getSelectedIndex();
         if (ind >= 0) {
            text = combo.getSelectedItem().toString();
         }
         Window win = SwingUtilities.getWindowAncestor(ComboPanel.this);
         win.dispose();
      }
   }
}