简体   繁体   English

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

[英]Accessing changes made inside JButton ActionListener outside the ActionListener

I ll explain my code in a bit: 我将解释一下我的代码:

I have a JComboBox with a list of items And when the JButton "Select" is pressed, it registers the last index of the last selected item from JComboBox. 我有一个带有项目列表的JComboBox,并且当按下JButton“选择”时,它将注册JComboBox中最后一个选定项目的最后一个索引。

Now I need to access this index inside the main. 现在,我需要在主体内部访问此索引。

Here is my code : 这是我的代码:

public static final JComboBox c = new JComboBox();

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

And the JButton ActionListener is: JButton ActionListener是:

btnNewButton.addActionListener(new ActionListener() { btnNewButton.addActionListener(new ActionListener(){

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

So after the button is pressed, the frame closes 因此,按下按钮后,框架关闭

But now when I try to access this ind inside main simply by 但是现在当我尝试通过以下方式简单地访问main内部的此ind时

public static void main(String[] args) {
System.out.println(ind);}

I get a return value of ind = 0 我得到ind = 0的返回值

I understand that this is because it has been initialized to 0 as 我了解这是因为它已被初始化为0

static ind = 0 

But then how do I access this index outside the JButton ActionListener? 但是,如何在JButton ActionListener外部访问此索引?

I need to use this index further in my code. 我需要在代码中进一步使用此索引。

EDIT 编辑

Here's my MCVE 这是我的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);
}
}

I need to access the ind inside the main as mentioned before Here when I print out the ind I get zero despite whatever choice I make inside the combobox. 我需要访问如前所述的main内部的ind。这里,当我打印ind时,尽管我在组合框内做出了任何选择,我都将得到零。

OK, I'm going to guess since you've yet to show us enough information to do more than this, but I assume that: 好的,我会猜测,因为您尚未向我们显示足够的信息来做更多的事情,但是我认为

  • You're showing a 2nd window as a dialog off of a main window 您正在显示第二个窗口作为主窗口的对话框
  • That this 2nd window is a JFrame and holds your JComboBox and the button 该第二个窗口是一个JFrame,其中包含您的JComboBox和按钮
  • That you're making it invisible on button push, 您在按钮按下时使其不可见,
  • That you try to get the information from the combobox, but it's always 0 您尝试从组合框中获取信息,但始终为0
  • And this may be because you're getting the information before the user has had a chance to interact with the 2nd window. 这可能是因为您是在用户有机会与第二个窗口进行交互之前获取信息的。

If so, the solution is to make the 2nd window a modal dialog window such as a modal JDialog and not a JFrame. 如果是这样,解决方案是使第二个窗口成为模式 对话框窗口,例如模式JDialog,而不是JFrame。 This way, the calling code will know exactly when the 2nd window is no longer visible since the calling code's code flow will be blocked until the 2nd window is no longer visible. 这样,调用代码将确切知道何时不再显示第二个窗口,因为调用代码的代码流将被阻塞,直到第二个窗口不再可见为止。


Edit 编辑

Proof of concept: Change your code from: 概念验证:从以下位置更改代码:

  final JFrame frame = new JFrame();

to: 至:

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

and it works. 而且有效。


But again, I'd get rid of unnecessary statics and get rid of doing too much code in the main method. 但是,再次,我将摆脱不必要的静态变量,并摆脱在main方法中执行过多代码的过程。 For instance,... 例如,...

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM