Java Choice Selected Index not returning properly - java

Ok, so here is the problem: Every time I click OK it should return the selected index number, right? The code below is returning ONLY the first index regardless of what I select. I set "cMenu.selected(1)" and it returns index 1, again, regardless of what I select.
Using JPanel, JButton, Choice
String[] menu = {"item 1" , "item 2", "item3"};
cMenu = new Choice();
cMenu.setBounds(0, 0, 75, 25);
for (int i = 0; i < menu.length; i++)
cMenu.add(menu[i]);
}
panel.add(cMenu);
final int menuSelection = cMenu.getSelectedIndex();
//Below is, of course, debugging
//Before asking, the button works it does say 0 or Hello World or whatever I want
//when clicked
OK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println(menuSelection);
}
});

You need to recalculate the value for menuSelection when the 'OK' button is clicked; you're setting it once during instantiation of the Choice as shown below:
final int menuSelection = cMenu.getSelectedIndex();
If you do something like this, you should be able to see your value:
OK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int currentSelection = cMenu.getSelectedIndex();
System.out.println(currentSelection);
}
});
This will mean cMenu should be final, which is probably OK because you don't need to ever update that reference.

"OK it should return the selected index number". No, it should not. you're calling getSelectedIndex() once. So your int has the same value forever. You have to call getSelectedIndex() in your listener to get the new value.

Related

Getting input from multiple button groups in Java

I have an array of question, an array of possible answers and an array of properties I want to find out by answering the questions
String[] questions = new String[]{"Question1", "Question2", "Question3"};
String[] possibleAnswers = new String[]{"yes,no", "yes,no", "big,small"};
String[] properties = new String[]{"", "", ""};
I created a label for every question and JRadioButtons for every answer for that question by using split on the corresponding element in the possibleAnswers array.
for (int i = 0; i < questions.length; i++) {
//label that holds the current question
JLabel questionLabel = new JLabel(questions[i]);
questionPanel.add(questionLabel);
// string that holds answers for current question i.e. {yes, no}
String[] currentQuestionAnswers = possibleAnswers[i].split(",");
ButtonGroup buttonGroup = new ButtonGroup();
for (int j = 0; j < currentQuestionAnswers.length; j++) {
JRadioButton btnRadio = new JRadioButton(currentQuestionAnswers[j]);
// action listener that will store the selected answer and the question
btnRadio.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
answer = btnRadio.getText();
// some code that moves answer at the right index in the properties array
}
});
buttonGroup.add(btnRadio);
questionPanel.add(btnRadio);
}
}
This image shows what I want it to look like.
For each question I want to find a property. Let's say {Question1, Question2, Question3} are actually these questions {"talks?", "expensive?", "dimension?"}. When I get the text from the selected buttons, I'll have talks -> yes, expensive -> no, dimension -> big, so the properties array will become {"yes", "no", "big"}.
I know how to get the selected answer, but I can't figure out how to find the question that corresponds to that answer. I thounght I can somehow use the button groups I created, but I don't know how.
I hope this makes sense and someone can help. Thank you.
One way to do it would be to extend JRadioButton and add a simple ID field (a tag). I can't test this code right now but I think
it should work.
class MyRadioButton extends JRadioButton{
private int tag;
public getTag(){ return tag;}
public setTag(int val){ tag = val}
}
And then in the actionPerfomed method, just check this tag and take an appropriate action based on it.
int tag = 0;
btnRadio.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
answer = btnRadio.getText();
switch(btnRadio.getTag()){
case 0:
//do some action
break;
case 1:
....
}
// some code that moves answer at the right index in the properties array
}
});
btnRadio.setTag(tag++);//this will set a unique tag for each radio button
buttonGroup.add(btnRadio);
Alternatively, if you don't want to extend JRadioButton,which arguably might be overkill for your use case, you can use RadioButton.setActionCommand and ActionEvent.getActionCommand
btnRadio.setActionCommand("some_unique_string")
and then just check this command string in actionPerformed
if("some_unique_string".equals(ae.getActionCommand())
//do something

Selecting Items in JComboBox

I have two combo boxes with a list of distance units to convert from/to. Now, when I want to choose eg. "Centimeter" from the ComboBox From (distance)..., I really don't need to have "Centimeter" in ComboBox To (distance)..., because it doesn't make sense to convert from centimeter to centimeter.
So when "Centimeter" is selected in From (distance)... I want it to be removed in To (distance)... ComboBox. But, when I change my selection (say "Meter"), I want "Centimeter" to be back and "Meter" disappear etc.
I managed to remove the selected item in To (distance)... box, but don't know how to return it back when I change my selection. Besides, when I change selection, the code below just removes the corresponding item in To (distance)... ComboBox.
Please guide me to the correct solution. Here is the corresponding code. I can give you the whole code if you need. Thank you!
private String[] convertFromDistance = {"From (distance)...", "Centimeter", "Inch", "Kilometer", "Knot", "Meter", "Mile", "Millimeter", "Yard"};
private String[] convertToDistance = {"To (distance)...", "Centimeter", "Inch", "Kilometer","Knot", "Meter", "Mile", "Millimeter", "Yard"};
private JComboBox fromListDistance, toListDistance;
fromListDistance.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String list = (String)fromListDistance.getSelectedItem();
for (int i=0; i<convertToDistance.length; i++) {
if (convertToDistance[i].equals(list)) {
toListDistance.removeItem(convertToDistance[i]);
//here should go the code for adding back the item if selection is changed
}
}
}
});
toListDistance = new JComboBox<String>(convertToDistance);
first thing you i should do in your problem is to know what is the selected choice from fromListDistance combo box ..
after that i have to refill the toListDistance combo box except for the choice that the user have selected ..
it's easy to do this with if statement
fromListDistance.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//saving the selected choice
String choise=fromListDistance.getSelectedItem().toString();
//here we remove all items from the combo box
toListDistance.removeAllItems();
for (int i = 0; i < convertToDistance.length; i++) {
String distance=convertToDistance[i];
//compare the selected choice with the convertToDistance[i]
if (choise.equals(distance)) {
continue;
}
toListDistance.addItem(distance);
}
}
});

evaluating button clicks java

I have the following code:
for (int i = 0; i < dynamicVariable; i++) {
String tmpString = myArray[i];
JToggleButton tButton = new JToggleButton(tmpString);
myJPanel.add(tButton);
tButton.addActionListener(this);
}
JButton go = new JButton("go");
myJPanel.add(submit);
Where I create x amount of buttons and add them to my panel. What I now need to do is, when the user selects the correct buttons and hits go. I evaluate all the selected buttons. If they are all right, then print true, otherwise print false. If they select all the correct answers except one, then it should evaluate to false. I just have no idea how to evaluate each button selected inside the actionPerformed() method.
Put all the buttons into a List or array, then iterate over this when the go button is clicked
private List<JToggleButton> listOfButtons;
//...
listOfButtons = new ArrayList<>(dynamicVariable);
for (int i=0; i<dynamicVariable;i++){
String tmpString= myArray[i];
JToggleButton tButton = new JToggleButton (tmpString);
listOfButtons.add(tButton);
myJPanel.add(tButton);
tButton.addActionListener(this);
}
JButton go= new JButton("go");
myJPanel.add(submit);
//...
// ActionListener of go button
public void actionPerformed(ActionEvent evt) {
for (JToggleButton btn : listOfButtons) {
if (btn.isSelected()) {
// Evaluate the state, set some flags
// get funky tonight
}
}
// Evaluate the final state once you know what
// buttons are actually selected
}
You should first map the correct values for each button, then if the user clicks on the Go button, then iterate over the buttons, checking for each button if it is correctly toggled on or off.
In short:
First we define the correct answers as a map with each toggle button bound to a boolean indicating whether the statement is correct or not;
Then we add all toggle buttons to the panel;
Then we add a listener to the Go button, which determines whether the selected button is correctly pressed or left unpressed.
Here's the code:
// Put all values into a map. If the mentioned fruit has the mentioned
// color, then the answer is correct.
private Map<JToggleButton, Boolean> correctAnswers = new HashMap<JToggleButton, Boolean>() {{
put(new JToggleButton("A strawberry is red"), true);
put(new JToggleButton("A banana is blue"), false);
put(new JToggleButton("A lemon is yellow"), true);
put(new JToggleButton("An orange is orange"), true);
}};
void init() {
for (JToggleButton button : map.keySet()) {
// button.setActionListener(this); // The toggle buttons themselves
// do not need to have a listener, do they? Only when the user clicks
// "go", then the buttons should be evaluated, right?
myJPanel.add(button);
}
JButton submitButton = new JButton("go");
submitButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
boolean wrong = false; // It's all good now, until a wrong
// answer is found.
// Iterate over all entries of our map.
for (JToggleButton button : this.buttons.keySet()) {
// Check if the selection state of the toggle button is
// equal to whether the answer is yes or no.
if (button.isSelected() != this.buttons.get(button)) {
// A button is pressed while it should not be pressed
// OR vice versa. Let's mark that at least one button
// is incorrect.
wrong = true;
}
}
// We found at least one incorrect button.
if (wrong) {
// DO SOMETHING
}
}
});
myJPanel.add(submitButton);
}
I haven't tested this code, but it should work.

How do I make a program where I can keep adding 1 to a value when a button is clicked?

I know this sounds very basic, but I never really learned how to do this.
I know about for loops where you can just use for example:
for(int i=0; i<=10; i++)
System.out.println(i);
But that just prints out numbers from 0 to 10 with a gap of 1...which isn't what I'm looking for.
I'm looking for some code where the program starts at a value and adds 1 (or another number) whenever the a button is clicked.
I already have the code for the button and everything, but I have an empty ActionListener as I don't know what to place inside it.
In the ActionListener actionPerformed method write the following code:
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == button_name)
{
count_variable += 1;
}
}
Just add something like this.
int counter = 0;
JButton button = new JButton(" Click me ");
//Add action listener to button
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
counter++;
}
});
This will make counter++ execute whenever the button is pressed. If you want another number, say 10, then just replace counter++ with counter+=10
**disclaimer**
Make sure that counter is accessible inside of ActionPerformed. You can do this by making it a field variable of an encapsulating class, making it a mutable object, and many other ways.

JTable boolean values not updating when using JOptionPane

I'm trying to write a bit of code that can allow the user to fill in text fields by clicking on boolean cells in a JTable.
I can get the program to enter the data from the table into a text-field but my current method of doing this involves a JOptionPane which for some strange reason stops the table from changing the check-box values (i.e. the check-box doesn't change from black to ticked). Not only this but the selection doesn't update so the value in the last column remains false, even though the selection should switch it to true.
I think it might be something to do with the JOptionPane somehow overriding the selection event, but I don't know enough about the JOptionPane object to say how. My code is:
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
ListSelectionModel selectionModel = table.getSelectionModel();
selectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
if (lsm.isSelectionEmpty()) {
//no rows are selected do nothing
} else {
//First find the row clicked
int selectedRow = lsm.getLeadSelectionIndex();
/*
* put a popup here to ask the user which peak to associate
* the energy with.
*/
System.out.println(selectedRow);
//Get user to associate with a peak
availablePeaks = getAvailablePeaks();
String returnVal = (String) JOptionPane.showInputDialog(
null,
"Select the peak:",
"Peak Matching",
JOptionPane.QUESTION_MESSAGE,
null,
availablePeaks, null);
System.out.println(returnVal);
//Determine the selection
int index = 0;
for (int i = 0; i < availablePeaks.length; i++) {
if (availablePeaks[i] == returnVal) {
index = i;
} else {
}
}
//Set the peak value in the peak specifier to the energy in the row
double energy = (Double) table.getValueAt(selectedRow, 0);
System.out.println(energy);
frame.getPeakSetter().getPeakSpecifiers()[index].setEnergy(energy);
frame.getPeakSetter().getPeakSpecifiers()[index].getTextField().setText("" + energy);
}
}
});
Does anyone know why a JOptionPane in the ListSelectionListener would stop the table from updating the check-boxes?
Thanks!
I assume that your model returns true for isCellEditable() and that getColumnClass() returns Boolean.class for the JCheckBox column. This enables the default rednerer/editor, listed here.
It looks like the gesture of selecting the row is bringing up the dialog. It's not clear how this prevents the DefaultCellEditor from concluding; it works for me. As you are not checking getValueIsAdjusting(), I'm surprised you don't see two ListSelectionEvent instances.
In any case, bringing up a dialog each time the selection changes seems cumbersome. Several alternatives are possible:
Keep the ListSelectionListener, make the cell non-editable by returning false from isCellEditable(), and set its value in the model only if the dialog concludes successfully.
Drop the ListSelectionListener in favor of a JButton editor, shown here.
Drop the ListSelectionListener in favor of a custom CellEditor, as outlined below.
table.setDefaultEditor(Boolean.class, new DefaultCellEditor(new JCheckBox()) {
#Override
public boolean stopCellEditing() {
String value = JOptionPane.showInputDialog(...);
...
return super.stopCellEditing();
}
});

Categories

Resources