How to get the selected index (from a number of jcheckbox added to the screen using for loop) of JCheckbox?.
// for some t values:
checkBoxes[t] = new JCheckBox("Approve");
checkBoxes[t].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean selected = checkBoxes[t].isSelected();
System.out.println("Approved"+selected);
}
});
When i click the check box, i want to get the selected check box's index.
You have an array of JCheckBox, and you can simply iterate through your array and find out which JCheckBox has been selected.
Regarding:
When i click the check box, i want to get the selected check box's index.
Edit: You would find out which checkbox was selected by using the getSource() method of the ActionEvent passed into the ActionListener. For example you could change your ActionListener to as follows:
checkBoxes[t].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean selected = checkBoxes[t].isSelected();
System.out.println("Approved"+selected);
int index = -1;
for (int i = 0; i < checkBoxes.length; i++) {
if (checkBoxes[i] == e.getSource()) {
index = i;
// do something with i here
}
}
}
});
As far as I understand, you want to get the index of a selected JCheckBox in order to respond appropriately on a user's action.
If this is the case, you might want to consider a different approach: you can register an ItemListener for each of your checkboxes.
JCheckBox check = new JCheckBox("Approve");
check.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (check.isSelected()){
System.out.println(check.getName() + " is selected");
}
}
});
(inspired by java2s.com tutorial)
In this case the event will be fired immediately and you will always know which checkbox was just clicked.
Iterate throuh the Checkboxes and check the isSelected flag
I would try something like:
for (int i=0; i < checkBoxes.length; i++) {
if (checkBoxes[i].isSelected() == true) {
index = i; }
return index; }
From your question, this is what I gather that you are looking for.
EDIT:
My above previous method is flawed because it makes the very naive approach that one and only one box will be selected and that no box will be deselected.
Where 'e' is the ActionEvent object,
for (int i=0; i < checkBoxes.length; i++) {
if (checkBoxes[i] == e.getSource()) {
index = i; } }
return index;
This way the most recent selection or deselection check box is identified.
Related
After much time spent trying to get my actionlistener to do what I want, Ive come to a few issues debugging that Im just not comprehending.
After finding a correct pair in the game, the first correct pair works properly, disables the two selected buttons, and moves on. After this the comparisons stop working. I can't seem to find out why. After setting up System.out.print checks to see if the programming was progressing through the clicks again it was, but its not allowing another comparison to happen or button reset from the else statement.
Below I've listed my main actionlistener and my pause action listener. Thank you, and if you need more data id be happy to update.
ActionListener timerPause = new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i < jToggleLength; i++) {
jToggleButtons[i].setEnabled(true);
tempIconThree = ((ImageIcon)
jToggleButtons[i].getSelectedIcon()).getDescription();
//flip the selected buttons back over
if(jToggleButtons[i].isSelected()){
jToggleButtons[i].doClick();
}
}
}
};
/**
* sets the pause timer period to 1.5 seconds
* sets it to the actionListener Timerpause
*/
pause = new Timer(1500, timerPause);
public void actionPerformed(ActionEvent ae) {
//starts timer
//increments click on each action
pause.stop();
timer.start();
click++;
//if jtogglelength = 0 the user has completed the game and the timer stops
if (jToggleLength == 0) {
timer.stop();
click = 0;
}
//on first click the jtoggle button source is set to temp and the temp icon gets description
if (click == 1) {
temp = (JToggleButton) ae.getSource();
tempIcon = ((ImageIcon) temp.getSelectedIcon()).getDescription();
}
// on click two the jtoggle button source is set to tempTwo and the tempTwo icon gets description
if (click == 2) {
tempTwo = (JToggleButton) ae.getSource();
tempIconTwo = ((ImageIcon) tempTwo.getSelectedIcon()).getDescription();
//if the button is the same button set click to zero and do nothing else
if (temp == tempTwo) {
click = 0;
//if the temp icon descriptions are equivalent move forward
} else if (tempIcon.equals(tempIconTwo)) {
click = 0;
//this for loop sets tempIconThree in every loop to compare to my first two icon descriptions
//if they match, disable that button and set the button to null
//if the button is not null add it to an arraylist
for (int j = 0; j < jToggleLength; j++) {
tempIconThree = ((ImageIcon) jToggleButtons[j].getSelectedIcon()).getDescription();
if (tempIcon.equals(tempIconThree) || tempTwo.equals(tempIconThree)) {
jToggleButtons[j].setEnabled(false);
jToggleButtons[j] = null;
if (jToggleButtons[j] != null) {
arrayEdit.add(jToggleButtons[j]);
}
}
}
//reduce the length of the array by 2
//make a new version of the main jtogglebutton array with reduced length
//add the non null elements from the arrayList to the array
jToggleLength = -2;
for (int k = 0; k < jToggleLength; k++) {
jToggleButtons = new JToggleButton[jToggleLength];
jToggleButtons[k] = arrayEdit.get(k);
}
click = 0;
//if the icon descriptions did not match
//disable all buttons, pause for 1.5 seconds, flip the
selected buttons back up
} else {
for (int i = 0; i < jToggleLength; i++) {
jToggleButtons[i].setEnabled(false);
}
pause.start();
click = 0;
}
}
I have 9 (+ default) selectable options (all the same for the 20) for my JComboBoxes.
The 20 are part of 2 JComboBox array. (10-10 for each).
I want to limit them like this:
If there is 4 selected from (for example) option 4 and the user selects a 5th one of it, one of them jumps back to default to keep the limit of 4.
How Can I do it ?
for ex:
for (int i = 0; i < roles1.length; i++) {
roles1[i] = new JComboBox();
roles1[i].setModel(new DefaultComboBoxModel(new String[] { "Not Selected", "PartnerInCrime", "Driver",
"Gunman", "Coordinator", "Hacker", "Distraction", "GadgetGuy", "Bruglar", "ConMan" }));
roles1[i].setBounds(boxPlace, 200, 100, 20);
boxPlace += 105;
getFrame().getContentPane().add(roles1[i]);
}
Here is a suggestion which is supposed to lead you in the right direction.
First of all, you have to add an ActionListener to each ComboBox, that calls a method which compares all selections with your current one.
roles1[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// get the current selection
JComboBox currentBox = (JComboBox)e.getSource();
String currentSelection = (String)currentBox.getSelectedItem();
// call the method and hand in your current selection
checkForSelectionExceeding(currentSelection);
}
});
In your scanning method you should memorize the amount of matches while scanning. If your limit is exceeded, reset the current box to default and stop scanning. Something like this:
private void checkForSelectionExceeding(String currentSelection){
int matches = 0;
for(int i=0; i<roles1.length; i++) {
if(roles1[i].getSelectedItem().equals(currentSelection)) {
matches++;
}
if(matches > 4) {
roles1[i].setSelectedItem("Not Selected");
break;
}
}
}
You only have to refactor this solution a little in order to scan both arrays sequentially.
Hope this helps.
If I understand your question properly, I have an idea that you may start from:
// create global HashMap that can records the occurrence of the selection of each item
Map<String, Integer> reference = new HashMap<String, Integer>();
// populate it
reference.put("PartnerInCrime", 0);
reference.put("Driver", 0);
reference.put("Gunman", 0);
reference.put("Coordinator", 0);
reference.put("Hacker", 0);
reference.put("Distraction", 0);
reference.put("GadgetGuy", 0);
reference.put("Bruglar", 0);
reference.put("ConMan", 0);
// then for every JComboBox in your array -> add action item listener to observe and control the selection like this
for(JComboBox<String> jcb : roles1){
jcb.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent ie){
if(ie.getStateChange() == ItemEvent.DESELECTED){ // decrement record
if(!ie.getItem().toString().equals("Not Selected")){
reference.put(ie.getItem().toString(), reference.get(ie.getItem().toString()) -1);
}
}
else if(ie.getStateChange() == ItemEvent.SELECTED){
if(!ie.getItem().toString().equals("Not Selected")){
if(reference.get(ie.getItem().toString())>=4){ // if already selected 4 of them
jcb.setSelectedIndex(0); // return to the default
}
else{ // else record the selection
reference.put(ie.getItem().toString(), reference.get(ie.getItem().toString()) +1);
}
}
}
}
});
}
I am trying add an item listener to a checkbox to see if its been checked, and if it is, to be added to a list of SQL table names to be selected. Inversely, if it is not selected then remove it from the list. I cannot add a listener though to any checkbox because "they are not effitively final". What can I do/is there a better way to attack it?
My method:
public JPanel drawChecks(){
ArrayList<String> list = MainFrame.grabSQLTableNames();
int index = list.size();
int rows = 1;
while(index > 1){
rows++;
index = index - 3;
}
GridLayout c = new GridLayout(rows, 3);
JPanel panel = new JPanel(c);
JCheckBox check[] = new JCheckBox[list.size()];
for(int x = 0; x < list.size(); x++){
check[x] = new JCheckBox(list.get(x));
check[x].setVisible(true);
check[x].addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
if (check[x].getState == true){
//do something
}
}
});
panel.add(check[x]);
}
Get the source of the event using the getSource method of the ItemEvent
public void itemStateChanged(ItemEvent e) {
JCheckBox checkBox = (JCheckBox)e.getSource();
if ( checkBox.isSelected() ){
//do something
}
}
For future reference, please read the following for tips on posting code examples for asking questions on stack overflow: https://stackoverflow.com/help/mcve
These two buttons are cycling through an array and when pressed increment to many times and depending on what the maximum index is. I thought it might be because (for backwards a least I have "i set as maximum index" but changing to current index stops the button functioning all together.
btnprev.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = dataArrayMaxIndex; i >= 0; i-- ) {
System.out.println("backwards");
dataArrayCurrentIndex = i;
websitetxt.setText(dataArray[i].getWebsitename());
usernametxt.setText(dataArray[i].getUsername());
passwordtxt.setText(dataArray[i].getPassword());
notestxt.setText(dataArray[i].getNotes());
}
}
});
btnnext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i<dataArrayMaxIndex; i++) {
System.out.println("foward");
dataArrayCurrentIndex = i;
websitetxt.setText(dataArray[i].getWebsitename());
usernametxt.setText(dataArray[i].getUsername());
passwordtxt.setText(dataArray[i].getPassword());
notestxt.setText(dataArray[i].getNotes());
}
}
});
I am unsure as to fixing this problem and could use some help and suggestions. I feel it would be more helpful for myself to not be given the answer but to have some constructive criticism to lead myself to it, that being said feel free to post an a straight, working answer if that's your thing.
I think that your for loops don't belong in this code as you'll loop all the way to the end or all the way to the beginning with each button press. Instead, simply increment or decrement an index variable and use that index. I assume that you'll be using the dataArrayCurrentIndex for this functionality.
i.e.,
btnprev.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dataArrayCurrentIndex--;
// if you want to do a cyclic loop of the data
if (dataArrayCurrentIndex < 0) {
dataArrayCurrentIndex= maxIndex - 1;
}
System.out.println("backwards");
websitetxt.setText(dataArray[dataArrayCurrentIndex].getWebsitename());
usernametxt.setText(dataArray[dataArrayCurrentIndex].getUsername());
passwordtxt.setText(dataArray[dataArrayCurrentIndex].getPassword());
notestxt.setText(dataArray[dataArrayCurrentIndex].getNotes());
}
});
btnnext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dataArrayCurrentIndex++;
// if you want to do a cyclic loop of the data
if (dataArrayCurrentIndex >= maxIndex) {
dataArrayCurrentIndex = 0;
}
// etc...
}
});
I am creating a hangman game and I was having trouble getting the jlabel that contained each character of the word to update after the right letter button has been clicked. I have been having trouble with this as I am relatively new to working with Java Guis. Below is the action listener for the letter buttons.
private class LetterHandler implements ActionListener{
private char letterVal;
public LetterHandler(char lv){
letterVal = lv;
}
//checks if clicked button has the correct value as word char
public void actionPerformed(ActionEvent e){
for(int x = 1; x <= selectedWord.wordLength; x++){
if(selectedWord.wordValue.charAt(x - 1) == letterVal){
// JLabel letterValLabel = new JLabel(String.valueOf(letterVal));
wordSpacesArray.get(x-1).setName(String.valueOf(letterVal));
wordSpacesArray.get(x-1).revalidate();
continue;
}
else{
continue;
}
}
checkWin();
triesLeft--;
triesLeftLabel.revalidate();
}
//finds if all jlabels are complete or not
public void checkWin(){
for(int x = 1; x <= wordSpacesArray.size(); x++){
String charVal;
charVal = String.valueOf(wordSpacesArray.get(x-1));
if(charVal != "?"){
System.out.println("youWon");
System.exit(0);
}
else{
break;
}
charVal = null;
}
}
}
Any help is appreciated. Let me know if you need for of the programs code Thanks :)
There are some issues with the code. However, I'll first try to focus on your current problem:
I assume that wordSpacesArray is a list that contains the JLabels of individual letters of the word.
When this ActionListener will be notified, you try to update the labels in wordSpacesArray with the letter that corresponds to this button. However, in order to update the text that is shown on a JLabel, you have to call JLabel#setText(String) and not JLabel#setName(String). So the line should be
wordSpacesArray.get(x-1).setText(String.valueOf(letterVal));
// ^ Use setText here!
Now, concerning the other issues:
As pointed out in the comments, you should use 0-based indexing
The calls to revalidate are not necessary
The use of continue in its current for is not necessary
You should not compare strings with ==, but with equals
// if(charVal != "?") { ... } // Don't do this!
if(!charVal.equals("?")){ ... } // Use this instead
But the charVal in this case will be wrong anyhow: It will be the string representation of the label, and not its contents. So you should instead obtain the text from the label like this:
// String charVal = String.valueOf(wordSpacesArray.get(x-1)); // NO!
String charVal = wordSpacesArray.get(x-1).getText(); // Yes!
The triesLeftLabel will not be updated as long as you don't call setText on it
I think the logic of the checkWin method is flawed. You print "You won" when you find the first letter that is not a question mark. I think it should print "You won" when no letter is a question mark.
You should not call System.exit(0). That's a bad practice. Let your application end normally. (In this case, maybe by just disposing the main frame, although that would also be questionable for a game...)
So in summary, the class could probably look like this:
private class LetterHandler implements ActionListener
{
private char letterVal;
public LetterHandler(char lv)
{
letterVal = lv;
}
// checks if clicked button has the correct value as word char
#Override
public void actionPerformed(ActionEvent e)
{
for (int x = 0; x < selectedWord.wordLength; x++)
{
if (selectedWord.wordValue.charAt(x) == letterVal)
{
wordSpacesArray.get(x).setText(String.valueOf(letterVal));
}
}
checkWin();
triesLeft--;
triesLeftLabel.setText(String.valueOf(triesLeft));
}
// finds if all jlabels are complete or not
public void checkWin()
{
for (int x = 0; x < wordSpacesArray.size(); x++)
{
String charVal = wordSpacesArray.get(x).getText();
if (charVal.equals("?"))
{
// There is still an incomplete label
return;
}
}
// When it reaches this line, no incomplete label was found
System.out.println("You won");
}
}