How to change selected index in JComboBox when refreshing panel? - java

I am making a simple sudoku and when I want to start a new game, I reload the panel. I first remove it and then add it to the frame. The problem is that I can choose the difficulty for new game, but it always selects the first "Easy" dificulty, not selected. So if I change it in JComboBox to "medium", when page is reloaded it will load the game with "Easy", not "medium".
What should I do so my refreshed panel will accept changed difficulty?
Here are methods that are used for this in my program:
JComboBox difficulty = new JComboBox();
DefaultComboBoxModel difficultyModel = new DefaultComboBoxModel();
difficultyModel.addElement("Easy");
difficultyModel.addElement("Medium");
difficultyModel.addElement("Hard");
difficulty.setModel(tezavnostModel);
difficulty.setSelectedIndex(0);
difficulty.setPreferredSize(new Dimension(100, 25));
newGame.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
mainFrame.reloadSudokuBoard();
sudokuBoard.pickDifficulty(getDifficulty()));
}
});
public String getDifficulty() {
return (String)difficulty.getSelectedItem();
}
public void board(int[][] numbers, int zeros) {
int numberZeros = setDifficulty(sudokuForm.getDifficulty());
int[][] boardNumbers = gameNumbers();
public void reloadSudokuBoard() {
String newDifficulty = (sudokuForm.getDifficulty());
remove(sudokuBoard);
sudokuBoard.board(sudokuBoard.gameNumbers(), sudokuBoard.setDifficulty(newDifficulty ));
add(sudokuBoard, BorderLayout.WEST);
SwingUtilities.updateComponentTreeUI(sudokuBoard);
}

Hope this helps.
public void reloadSudokuBoard() {
int index = difficulty.getSelectedIndex();
String newDifficulty = (sudokuForm.getDifficulty());
remove(sudokuBoard);
sudokuBoard.board(sudokuBoard.gameNumbers(), sudokuBoard.setDifficulty(newDifficulty ));
add(sudokuBoard, BorderLayout.WEST);
SwingUtilities.updateComponentTreeUI(sudokuBoard);
difficulty.setSelectedIndex(index);
}
Before removing components, you can use the getSelectedIndex to get the index that was selected. After the element have been added, the setSelectedIndex will fix it

Related

Why do my buttons wont show up?

I want to build a bingo got the following source code, which should create a JFrame with 25 buttons placed in a 5x5 matrix. But none of my button gets drawn on the window in any kind.
I ve created a Jpanel on which the buttons are placed, the locations and such are not specific, finetuning will come later, first thing is to even get them drawn on the window.
Bingo Buttons is a class which extends JFrame and simply adds two methods, one to toggle its status from true to false and the other way around and also an method (isSet) to check if the buttons is currently true or false.
bingoField is an String Array which holds nothing but the data which the buttons should get.
I dont get why it does nothing, please help me out. Any kind of help is highly appreciated!
public class BingoFrame extends JFrame {
public static final int BINGOSIZE=25;
public static final int BUTTON_X=50;
public static final int BUTTON_Y=50;
public BingoFrame() {
setResizable(false);
String[] bingoField = null;
BingoButton[] buttons=new BingoButton[25];
try {
bingoField = Utils.getRandomBingoField("Test");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
this.setTitle("BS Bingo");
this.setResizable(false);
this.setLocation(50, 50);
this.setSize(600, 800);
this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(null);
JPanel buttonPanel = new JPanel();
buttonPanel.setBounds(0, 0, 594, 772);
getContentPane().add(buttonPanel);
buttonPanel.setLayout(null);
for(int i=0;i<BINGOSIZE;i++) {
buttons[i] = new BingoButton("Text");
}
//decorate buttons and add an action listener
for(int i=0;i<BINGOSIZE;i++) {
final BingoButton temp = buttons[i];
temp.setText(bingoField[i]);
temp.setBackground(Color.white);
temp.setForeground(Color.blue);
temp.setPreferredSize(new Dimension(BUTTON_X,BUTTON_Y));
temp.addActionListener(new ActionListener() {
boolean toggle = false;
#Override
public void actionPerformed(ActionEvent e) {
if (!temp.isSet()) {
temp.setBackground(Color.blue);
temp.setForeground(Color.white);
} else {
temp.setBackground(Color.white);
temp.setForeground(Color.blue);
}
temp.toggle();
}
});
buttons[i]=temp;
}
//set Location for the buttons
for(int i=0;i<5;i++) {
buttons[i].setLocation(100,(50*i)+10*(i+1));
}
for(int i=5;i<10;i++) {
buttons[i].setLocation(160,(50*i)+10*(i+1));
}
for(int i=10;i<15;i++) {
buttons[i].setLocation(220,(50*i)+10*(i+1));
}
for(int i=15;i<20;i++) {
buttons[i].setLocation(280,(50*i)+10*(i+1));
}
for(int i=20;i<25;i++) {
buttons[i].setLocation(340,(50*i)+10*(i+1));
}
//add buttons to the panel
for(int i=0;i<BINGOSIZE;i++) {
buttonPanel.add(buttons[i]);
}
this.setVisible(true);
I got the answer.
I ve changed the Layout of the Panel to Grid Layout. This alligns the buttons just where they should be in a 5x5 matrix and also with the wanted gap between. This makes also the code for the positioning completly obsolete.
By simply changing the Layout to GridLayout all of my Problems were gone.

Reordering JRadioButtons

I'm creating a matching style game in java that displays a group of thumbnails which expand into picture with 3 radio buttons, 1 correct and 2 incorrect. Currently I have the 1st rb displaying the correct answer, it should be able to display on the second or 3rd but I can't figure out how to get it there.
So the possibilities would be (CII, ICI, or IIC)
(the rb text gets pulled from the filenames of the pictures)
final JTextArea textArea = new JTextArea();
add(textArea);
JRadioButton rb1 = new JRadioButton(rb1Text);
add(rb1);
rb1.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
textArea.setText("Correct");
}
});
JRadioButton rb2 = new JRadioButton(rb2Text);
add(rb2);
rb2.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
textArea.setText("Guess Again");
}
});
JRadioButton rb3 = new JRadioButton(rb3Text);
add(rb3);
rb3.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
textArea.setText("Guess Again");
}
});
ButtonGroup group = new ButtonGroup();
group.add(rb1);
group.add(rb2);
group.add(rb3);
Figured it out: I changed the setBounds to include a one of the 3 desired y values pulled from a shuffled collection.
ArrayList<String> obj = new ArrayList<String>();
obj.add("250");
obj.add("300");
obj.add("350");
Collections.shuffle(obj);
int rand1 = Integer.parseInt(obj.get(0));
int rand2 = Integer.parseInt(obj.get(1));
int rand3 = Integer.parseInt(obj.get(2));
rb1.setBounds(400, rand1, 200, 15);
rb2.setBounds(400, rand2, 200, 15);
rb3.setBounds(400, rand3, 200, 15);
So every time the next or previous button is pressed it puts the correct answer in a different spot.
Thanks for the ideas Hovercraft Full Of Eels!

How to get items from JList in the order they are selected?

I have a JList with MULTIPLE_INTERVAL_SELECTION enabled and I'd like to pass the order in which the items are selected to another process.
I've tried using a MouseListener on the JList and checking if getClickCount() == 1 then add it to an array, however, this will not add new items that are below the selected item, it only adds items that are above the currently selected item in the JList.
For example if my list looks like this:
1
2
3
4
5
If I click number 1 first, then the below code will only show 1 for every subsequent click. If I click 3 first and then click 5 the number that pops up is 3. If I click 3 and then click 2 or 1, those numbers will popup correctly.
So I never actually get to the part of adding data to an array because I cannot get the data to display based up an action correctly.
Here is sample code from the listener:
private class ListBoxListener implements ListSelectionListener, MouseListener {
#Override
public void valueChanged(ListSelectionEvent e) {
if(e.getSource().equals(aList)) {
System.out.println(aList.getSelectedValue());
}
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
if(arg0.getClickCount() == 1) {
JOptionPane.showMessageDialog(null, aList.getSelectedValue());
}
}
}
Is there anything glaringly wrong with what I'm trying to do?
you should try this code
JFrame frame = new JFrame("JList Test");
frame.setLayout(new FlowLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
String[] selections = {"Java", "C++", "C", "Scala", "JavaScript"};
JList list = new JList(selections);
frame.add(new JScrollPane(list));
frame.pack();
frame.setVisible(true);
MouseListener mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent mouseEvent) {
if (mouseEvent.getClickCount() == 1) {
int index = list.locationToIndex(mouseEvent.getPoint());
if (index >= 0) {
Object obj = list.getModel().getElementAt(index);
JOptionPane.showMessageDialog(null, obj);
}
}
}
};
list.addMouseListener(mouseListener);
}
I understoud that you want to add an item listener to jList. So here is a simple code to show you how to do it:
ArrayList<String> list = new ArrayList<>();
jList1.addListSelectionListener(new ListSelectionListener(){
#Override
public void valueChanged( ListSelectionEvent e){
if(! e.getValueIsAdjusting()){
list.add(jList1.getSelectedValue());
}
}
});

Generalize several text fields for selecting the entire text when focus is gained

I want each of several text fields in a panel to have center alignment and to have a focus listener that will select the entire field when focus is gained.
txtSelection = new JTextField("", 9);
txtInclusion = new JTextField("", 9);
txtExclusion = new JTextField("", 9);
...
I know how to do it one by one:
txtSelection.setHorizontalAlignment(JTextField.CENTER);
txtSelection.addFocusListener(new FocusAdapter() {
public void focusGained(FocusEvent e) {
txtSelection.select(0, 9);
}
});
But I'd rather not repeat that structure for all the text fields.
I tried this (and a couple of varieties) but the code seems to do nothing:
pnlConditions = new JPanel();
pnlConditions.setLayout(new GridBagLayout());
for(final Component c : pnlConditions.getComponents()) // compiler insisted on 'final'
{
((JTextField)c).setHorizontalAlignment(JTextField.CENTER);
if(c instanceof JTextField)
{
c.addFocusListener
(new FocusAdapter()
{
#Override public void focusGained(FocusEvent e)
{
((JTextField)c).select(0,9); // compiler suggested cast to JTextComponent; no difference
}
}
);
}
}
The entire field is not selected; alignment is left (the default). I guess my first clues that it wouldn't work are the compiler's insisting that c must be final in the for and for suggesting that the cast should have been to JTextComponent in the statement with select; but it didn't make that suggestion on the statement with setHorizontal....
I'm sure this can be done; but how?
Here's the entire method containing the snippets above:
static void makePnlConditions(){
JLabel lblSelections = new JLabel("Select ONLY combos with ALL of:");
JLabel lblInclusions = new JLabel("DE-select combo NOT containing one or more of:");
JLabel lblExclusions = new JLabel("DE-select combo containing ANY of:");
txtSelection = new JTextField("", 9);
txtInclusion = new JTextField("", 9);
txtExclusion = new JTextField("", 9);
pnlConditions = new JPanel();
pnlConditions.setLayout(new GridBagLayout());
for(final Component c : pnlConditions.getComponents())
{
((JTextField)c).setHorizontalAlignment(JTextField.CENTER);
if(c instanceof JTextField)
{
c.addFocusListener
(new FocusAdapter()
{
#Override public void focusGained(FocusEvent e)
{
((JTextField)c).select(0,9);
}
}
);
}
}
pnlConditions.add(lblSelections);
pnlConditions.add(txtSelection);
pnlConditions.add(lblInclusions);
pnlConditions.add(txtInclusion);
pnlConditions.add(lblExclusions);
pnlConditions.add(txtExclusion);
}
First add the components into JPanel otherwise pnlConditions.getComponents() will return an empty array and no listener will be added for JTextField.
If you want to select entire text then use JTextComponent#selectAll() method.
Sample code:
JPanel pnlConditions = new JPanel();
pnlConditions.setLayout(new GridBagLayout());
pnlConditions.add(lblSelections);
pnlConditions.add(txtSelection);
pnlConditions.add(lblInclusions);
pnlConditions.add(txtInclusion);
pnlConditions.add(lblExclusions);
pnlConditions.add(txtExclusion);
for (final Component c : pnlConditions.getComponents()) {
if (c instanceof JTextField) {
((JTextField) c).setHorizontalAlignment(JTextField.CENTER);
...
}
}
I want each of several text fields in a panel to have center alignment and to have a focus listener that will select the entire field when focus is gained.
Create a custom class that extends JTextField, provide all default implementation and use it everywhere in your application to make it centralized.
Sample code:
class MyJTextField extends JTextField {
// Initialization block that is called for all the constructors
{
this.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
selectAll();
}
});
this.setHorizontalAlignment(JTextField.CENTER);
}
public MyJTextField() {}
public MyJTextField(String text) {super(text);}
public MyJTextField(int columns) {super(columns);}
public MyJTextField(String text, int columns) {super(text, columns);}
}

When adding class in DefaultListModel, did it save the value of toString or the entire class?

Newbie here.
When I added an element in the DefaultListModel, I used a class with an overriden toString.
Based on the sample code below, I want to display the selected item's ID when I click the button btnid.
The commands under displayID doesn't seem to work. Help please. Thanks!
class SomeClass {
JFrame f = new JFrame("Sample");
JScrollPane sp = new JScrollPane();
DefaultListModel dlm = new DefaultListModel();
JList lst = new JList(dlm);
public SomeClass() {
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton btnadd = new JButton("Add");
JButton btnid = new JButton("View ID");
Container p = f.getContentPane();
sp.getViewport().add(lst,null);
p.add(sp, BorderLayout.WEST);
p.add(btnadd, BorderLayout.EAST);
p.add(btnid, BorderLayout.SOUTH);
btnadd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dlm.addElement(new ElementDisplay(dlm.getSize(),"Element " + dlm.getSize()));
}
});
btnid.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
displayID();
}
});
f.pack();
f.setVisible(true);
}
private void displayID() {
ElementDisplay ed;
ed = dlm.getElementAt(lst.getSelectedIndex());
System.out.println(ed.elementID);
}
public static void main(String args[]) {
SomeClass sc = new SomeClass();
}
class ElementDisplay {
public int elementID;
private String elementDescription;
public ElementDisplay(int pid, String pdesc) {
elementID=pid;
elementDescription=pdesc;
}
#Override
public String toString() {
return elementDescription;
}
}
}
Works fine for me. What makes you think it doesn't work? You need to actually have an item selected in the list for the button press to work, you will get ArrayIndexOutOfBoundException
Instead of depending on a button press, just add a listener to the JList. That way only when the item in the JList is selected, does it print. No need for the button and trying to avoid the ArrayIndexOutOfBoundException
lst.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
JList list = (JList)e.getSource();
DefaultListModel model = (DefaultListModel)list.getModel();
ElementDisplay ed = (ElementDisplay) model.getElementAt(lst.getSelectedIndex());
System.out.println(ed.elementID);
}
}
});
See How to Write Event Listeners where you will run into possible listeners you can use for different components. As GUIs are event driven, you should take time to learn most of them.

Categories

Resources