1

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.

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:

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

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

I get a return value of ind = 0

I understand that this is because it has been initialized to 0 as

static ind = 0 

But then how do I access this index outside the JButton ActionListener?

I need to use this index further in my code.

EDIT

Here's my 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.

newbie2015
  • 581
  • 5
  • 29
  • I'm surprised that your code compiles. The `ind` variable is a local variable within the JComboBox's ActionListener and thus should not be visible anywhere else in your program. I suspect that you have declared this variable more than once and are shadowing it in the ActionListener. Your code also looks to over-use the static modifier. If you need more specific help, then you first, please tell us more of the details and show us your pertinent code, preferably as a [minimal example program or MCVE](http://stackoverflow.com/help/mcve). – Hovercraft Full Of Eels May 30 '15 at 21:38
  • Did you try `ind = c.getSelectedIndex();` (without the `int`) declaration within `cActionListener`? It seems that you're _hiding_ the `ind` variable (by re-declaring it) within the anonymous `ActionListener` instance. – Mick Mnemonic May 30 '15 at 21:39
  • Note that if the key event is the pressing of the button, and if the comob box's selection only matters when the button has been pressed, then your JComboBox doesn't even need an ActionListener. – Hovercraft Full Of Eels May 30 '15 at 21:40
  • yes I have declared a global ind as well The ind inside the JComboBox is not used for anything I need to be able to make changes to a global static variable through JButton ActionListener and then access the changed variable inside main – newbie2015 May 30 '15 at 21:40
  • OK, then 1) get rid of the JComboBox's ActionListener since it's doing nothing useful and is not needed. 2) Get rid of most of your static modifiers as they're not needed (trust me on this), and yes, 3) create and post your minimal example program. – Hovercraft Full Of Eels May 30 '15 at 21:42
  • I removed the local declaration of ind as well as the actionlistener for the JComboBox. But yet I am not able to access the changes made to ind in main. It returns 0 itself – newbie2015 May 30 '15 at 21:43
  • You don't want to directly access any fields within main. Instead if you need to find a field's value, give the class that holds it a getter method, and call this method on the class instance. Good OOP techniques don't get ignored just because this is a Swing GUI. But **again** the devil exists in the details. If you need more specific help, then you first, please tell us more of the details and show us your pertinent code, preferably as a [minimal example program or MCVE](http://stackoverflow.com/help/mcve). At this point, all we can do is guess what *might* be wrong. – Hovercraft Full Of Eels May 30 '15 at 21:44
  • Please post more code so that anyone can test and reproduce your exact problem. – Mick Mnemonic May 30 '15 at 21:45
  • Sir, I have editted my question and added the MCVE as requested. Please help me understand how do I access the ind in the main. As it can be seen when we run the code that the system prints out 0 since that is what ind was initialized to. But I need to access the incremented value of ind. – newbie2015 May 30 '15 at 22:00

1 Answers1

4

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
  • That you're making it invisible on button push,
  • That you try to get the information from the combobox, but it's always 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. 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. 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();
      }
   }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373