Tom Lenc
Tom Lenc

Reputation: 765

How to set Combobox value to one of the choices in the list

I need to change the value of the current JComboBox value.

I got this in my Settings gui class used by Main.class:

package com.tominocz.cookieclicker;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

@SuppressWarnings({ "serial", "rawtypes", "unchecked" })
public class Settings extends JFrame {

    private String[] choiceList = { "Default (Arial)", "Comic Sans MS" };

    public class ChoiceComboListener implements ActionListener {
        public void actionPerformed(ActionEvent ev) {
            JComboBox cb = (JComboBox) ev.getSource();
            String currentComboSelection = (String) cb.getSelectedItem();
            if (currentComboSelection.equals(choiceList[0])) {
                Main.SelectedFont = "Arial";
                Main.refreshGame();
                Main.opt.setSize(240, 105);
                Save.saveGame(Main.save);
            }
            if (currentComboSelection.equals(choiceList[1])) {
                Main.SelectedFont = "Comic Sans MS";
                Main.refreshGame();
                Main.opt.setSize(240, 107);
                Save.saveGame(Main.save);
            }
        }
    }

    public Settings() {
        super("Settings");
        setLayout(new FlowLayout());

        Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (int) (((screen.getWidth()) - this.getWidth()) / 2 - 200);
        int y = (int) (((screen.getHeight()) - this.getHeight()) / 2 - 100);
        this.setLocation(x, y);
        this.setAlwaysOnTop(true);

        this.setIconImage(((ImageIcon) Main.SettingsIcon).getImage());

        JPanel northPanel = new JPanel();
        northPanel.setIgnoreRepaint(true);
        northPanel.setBorder(new LineBorder(Color.GRAY));
        this.getContentPane().add(northPanel, BorderLayout.NORTH);
        JComboBox choiceCombo = new JComboBox(choiceList);
        northPanel.add(Main.ChooseFont);
        northPanel.add(choiceCombo);
        choiceCombo.addActionListener(new ChoiceComboListener());

        // LOOK HEREEEEEEEEEEEEEEEEEEEEEEE
        if (Main.SelectedFont.equals("Comic Sans MS")) {
            [the current JComboBox value(may be the default one - choiceList[0])] = choiceList[1];
        }
        // LOOK HEREEEEEEEEEEEEEEEEEEEEEEE

        Main.OK.setBorder(null);
        Main.OK.setBorderPainted(false);
        Main.OK.setContentAreaFilled(false);
        add(Main.OK);
        Main.OK.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Object source = e.getSource();
                if (source instanceof JButton) {
                    Main.opt.dispose();
                }
            }
        });
    }
}

Now how do I change the currentComboSelection value if i'm not available to use it in:

public Settings() {

...

?

Upvotes: 0

Views: 8492

Answers (2)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

Suggestions:

  • You can set the JComboBox's selected item one of two ways: via setSelectedIndex(int index) or setSelectedItem(Object item) where the first way, you choose the index of the desired selection and the 2nd way you choose the object held by the JComboBox (here they are Strings) that is supposed to be selected.

Other issues:

  • you look to be getting data from the Main class by directly accessing a field, possibly a static field at that. Don't do this as it will make your code tightly coupled, a set up for hard to find bugs, and difficult to enhance or change. Use tightly controlled getter methods instead. i.e., give Main a public Font getSelectedFont() method so that this class can call the method in a non-static way without directly fiddling with Main's fields, without making Main fields static that shouldn't be static.
  • The same goes for your directly changing Main's state in this Settings class -- that's not how to do Java safely for the same reasons above. Good OOPs principles don't get thrown out the window just because you're creating an event-driven GUI.
  • It looks like this is supposed to be a secondary window that is displayed from a main GUI window. If so, this should be displayed as a dialog, such as a JDialog or JOptionPane and not a JFrame. This will prevent the display another icon on the OS's toolbar, will guarantee that this window is on top of the main window, and will allow this window to be displayed in a modal fashion if need be.
  • You're setting the layout of your contentPane to FlowLayout, and yet you are trying to add a JPanel to its BorderLayout.NORTH position. This obviously won't work.

For example, simple code similar to yours that uses a JOptionPane for the secondary dialog window:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class TestSettingsPanel {

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

      JFrame frame = new JFrame("Test Settings");
      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();
         }
      });
   }
}

class MainPanel extends JPanel {
   private static final long serialVersionUID = 1L;
   public static final String[] CHOICE_LIST = { "Default (Arial)",
         "Comic Sans MS", "Courier", "Times New Roman" };
   private static final int PREF_W = 500;
   private static final int PREF_H = 400;
   private JTextField fontField = new JTextField(10);
   private SettingsPanel settingsPanel;

   public MainPanel() {
      fontField.setFocusable(false);
      fontField.setText(CHOICE_LIST[0]);

      add(new JLabel("Font: "));
      add(fontField);
      add(new JButton(new SettingsAction("Change Settings")));
   }

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

   private class SettingsAction extends AbstractAction {
      private static final long serialVersionUID = 1L;

      public SettingsAction(String name) {
         // give our button / Action some text
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic); // set alt-key combination short-cut
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         // create our settingsPanel in a lazy fashion
         if (settingsPanel == null) {
            settingsPanel = new SettingsPanel();
         }

         // set the combo selection by calling the setSetting method:
         settingsPanel.setSetting(fontField.getText());

         // create a JOptionPane and dsiplay the settingsPanle inside of it
         Component parentComponent = MainPanel.this;
         String title = "Change Font Settings";
         int optionType = JOptionPane.OK_CANCEL_OPTION;
         int messageType = JOptionPane.PLAIN_MESSAGE;
         // display JOptionPane here
         int result = JOptionPane.showConfirmDialog(parentComponent,
               settingsPanel, title, optionType, messageType);
         // find out what button user pressed
         if (result == JOptionPane.OK_OPTION) {
            // if OK button pressed, extract information from settingsPanel
            String fontType = settingsPanel.getFontType();
            fontField.setText(fontType);
         }
      }
   }
}

// note that SettingsPanel is completely ignorant about the GUI that displays it. 
class SettingsPanel extends JPanel {
   private static final long serialVersionUID = 1L;
   private JComboBox<String> choiceListCombo = new JComboBox<>(MainPanel.CHOICE_LIST);

   public SettingsPanel() {
      add(new JLabel("Select Font:"));
      add(choiceListCombo);
   }

   // to allow outside classes to set the combo's selected item 
   public void setSetting(String text) {
      if (text != null && !text.trim().isEmpty()) {
         choiceListCombo.setSelectedItem(text);
      }
   }

   // allow outside classes to extract the selected item from combo
   public String getFontType() {
      return (String) choiceListCombo.getSelectedItem();
   }

}

Upvotes: 4

Nikos Kyr
Nikos Kyr

Reputation: 3246

You can get and set the selected Item (Object) of your Combobox by using the methods:

choiceCombo.getSelectedItem();

and

choiceCombo.setSelectedItem(anObject);

Upvotes: 0

Related Questions