I have 8 MC questions in a panel. When submitted, I want all the selected answer to be recorded in the database. However, my code is only recording 1 question. Here is the code. (Note: All the jRadioButton names are not same since they are in one panel together.)
Here is the code :
public void submitButtonClicked(){
for(int i=1;i<9;i++){
username = "Smith";
questionID = i;
if(jRadioButton1.isSelected()){answer = jRadioButton1.getText();}
else if(jRadioButton2.isSelected()){answer = jRadioButton2.getText();}
if(jRadioButton3.isSelected()){answer = jRadioButton3.getText();}
else if(jRadioButton4.isSelected()){answer = jRadioButton4.getText();}
// and So on until the question 8.
}
Consider creating an array or ArrayList of the ButtonGroups for each JRadioButton cluster. You can then use a for loop to get the selection from each ButtonGroup which is the model of the JRadioButton selected, and if not null, get its actionCommand String.
For example, please look at my code here.
In your solution only one value is recorded because if one if statement is executed then it will bypass all other else if statements.
You could create a array of jradiobuttons and then use them in for loop,traversing each button one by one and then recording its answer.
Related
I am making a simple calculator using a JFrame and JButtons. Before I made each button, 0 thru 9, with their own action listeners, now I have realized that this is super inefficient and I should use a loop to make each button and assign the ActionListeners. So the only thing that needs to happen in each ActionListener is to add whatever number the button is to a JTextField, called nums. Here is what I have now.
for(int i = 0; i <=9; i++) {
count = i;
btns.get(i).addActionListener(new ActionListener(){ //makes action listeners for each button
public void actionPerformed(ActionEvent e){
nums.setText(nums.getText()+ count);//IMPORTANT CODE
}
});
}
So as you can see I used a terribly named variable named count. count is set to i in each iteration before the important code is used. I have to do this because an AL is it's own class and cannot access i. However count is public and static, so the ALs can use count.
My problem is that all the buttons print 9. This logically makes sense because what is happening is that the ALs in each button use the count variable, when the loop is done, count will be 9, which means each AL will essentially contain nums.setText(nums.getText()+ 9);. Instead, I need button 1 to be nums.setText(nums.getText()+ 1); 2 to be 2, ETC.
I have tried to call the text of each button, however, because you need to use an index in the ArrayList get method, you need a variable, if you use count, the same problem occurs; after the for loops has terminated, count is 9, so all the buttons print the text of the 9 button.
Any and all help is appreciated, Thanks in advance,
-Max
P.S. Just in case you don't understand why I'm getting the text and then adding count, it is because in order to type the number 12. you need to type 1 and then concatenate the 2 to the one to et 12. getText gets the 1, and adding count concatenates the 2 to make 12.
In general you will want to avoid using static fields as you loose all benefits of object-oriented programming by this. There are specific places for use of static fields, but this is not one of them. In your situation you can't use the index of the loop, i, directly since it is not a final local variable, and non-final local variables cannot be used within anonymous inner classes. So a simple solution exists:
Make count a final local variable and you should be able to use it within your anonymous inner class:
for(int i = 0; i <= 9; i++) {
final int finalCount = i;
btns.get(i).addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
nums.setText(nums.getText() + finalCount);
}
});
}
Assuming the text for each button is simply the digit you wish to append, there is another way that lets you share the same ActionListener instance for every number button.
private ActionListener numberBtnListener = new ActionListener(){
public void actionPerformed(ActionEvent e){
JButton b = (JButton) e.getSource();
nums.setText(nums.getText() + b.getText());
}
}
Then just use the same listener instance for each button:
for(JButton b : btns) {
b.addActionListener(numberBtnListener);
}
If your button text is different for some reason, you can still use the same technique by using a client property on each button to hold the value that you wish to append. E.g.:
b.putClientProperty("digit", i);
then use
nums.setText(nums.getText() + b.getClientProperty("digit"));
In my app, I need for values from buttons (the value is taken from an SQLite database) to be displayed in one of 13 JTextFields, and they can be in any order. How do I make it possible for the value to be displayed in the next available JTextField, if say the first one is empty?
The only thing I could think of was
if (textField.getText().isEmpty())
{
String text = String.valueOf(num);
textField.setText(textField.getText() + text);
}
What should I do next? How should I go around the else statement? Should I even use it?
Thanks in advance!
If I understand your question correctly,this should be the idea
JTextField[] fields = new JTextField[13];
firstText.setName("First Text") ;
.......
field[0] = firstText;
field[1] = SecondText;
//then add remaining textfields
for(JTextField txtField : fields) {
if(txtField.getText().equals("") ) {
// do whatever you want
}else{
// do whatever you want
}
}
I am working on a GUI that will feature a table that has been manually connected to a database. Above this table there are 3 radio buttons that will "decide " what criteria is to be used when fetching the data( All rows have a boolean value, depending on the button pressed it is supposed to return either 1, 0 or both).
This is the code for the table(NOTE i am using netbeans gui designer)
ServiceTable = new javax.swing.JTable();
int radiovalue = 0;
if (RadioActive.isSelected()) radiovalue = 0;
else if (RadioAll.isSelected()) radiovalue = 1;
else if (RadioFinished.isSelected()) radiovalue = 2;
Object[][] DataAct = null;
try {
DataAct = SQL.MYSQL_FETCH_OMNI_DATA(radiovalue);
} catch (Exception ex) {
Logger.getLogger(MainforAdmin.class.getName()).log(Level.SEVERE, null, ex);
}
String[] Colnombs = SQL.MYSQL_ROW_NOMBER();
ServiceTable.setAutoCreateRowSorter(true);
ServiceTable.setModel(new javax.swing.table.DefaultTableModel( DataAct, Colnombs ));
TableContainer.setViewportView(ServiceTable);
This works as it should and the 2 external functions return arrays that make the table display what it should display (Which is as the program starts all the "active " transactions)
However i want to be able to change the table so that it will evaluate if radioactive is equals to 0, 1 or 2 (The number is going to determined what data the function fetches). The program outputs the MYSQL tables trough System.out.print perfectly with the diffrent criterias. So I know my functions are working. But I can not figure out how I am to make the entire table "refresh" after another radiobutton is selected..
This is my event code for Mousepressed for a radio button.
TableRefresher();
System.out.println("Pressed");
And Pressed is outputed so i know this code has been summoned after clicking on the radio button. Here is the TableRefresher function.
Write.Echo("The TableRefresher method hath been summoned");
//This code is going to evaluate which button is selected as of now.
MainforAdmin table = new MainforAdmin();
if (table.RadioActive.isSelected()) radiovalue = 0;
else if (table.RadioAll.isSelected()) radiovalue = 1;
else if (table.RadioFinished.isSelected()) radiovalue = 2;
Object[][] DataAct = null; //This code is going to innitialize the tablecontents.
try {
DataAct = SQL.MYSQL_FETCH_OMNI_DATA(radiovalue);//This code assigns the table contents And i know this works because it correctly outputs the table with the diffrent where clause (where state = x or the status as you saw on the picture.)
} catch (Exception ex) {
Logger.getLogger(MainforAdmin.class.getName()).log(Level.SEVERE, null, ex);
}
String[] Colnombs = SQL.MYSQL_ROW_NOMBER(); //Assigns the column names and works is used as the table is created so this works.
table.TableContainer.remove(table.ServiceTable);
table.add(table.ServiceTable, null);
table.ServiceTable.setModel(new javax.swing.table.DefaultTableModel( DataAct, Colnombs ));
table.ServiceTable.revalidate();
table.ServiceTable.repaint();
table.TableContainer.setViewportView(table.ServiceTable);
Yet as this method is summoned(Which i know it is from the console output) nothing happens to the JTable in the GUI...It stays the same.
So how am i supposed to refresh the table after a different criteria for fetching the data has been applied ? I have looked at other suggestions here on this site but none of them worked or gave me what i needed.
Any answers would be very appreciated, and please forgive me if this is an easy question I am by no means a Programming deity.
If it makes any difference the JTable is in a Scrollpane..
Sincerly...
//Orville Nordström.
Just as a start:
If it makes any difference the JTable is in a Scrollpane.
That's correct and it must keep in this way. It makes no difference to solve the main problem though.
So how am i supposed to refresh the table after a different criteria for fetching the data has been applied?
Code quote:
table.TableContainer.remove(table.ServiceTable);
table.add(table.ServiceTable, null);
table.ServiceTable.setModel(new javax.swing.table.DefaultTableModel( DataAct, Colnombs ));
table.ServiceTable.revalidate();
table.ServiceTable.repaint();
table.TableContainer.setViewportView(table.ServiceTable);
Please note this is kind of spaghetti code and it's not clear which is the table to be updated. However the correct way to update a table is not removing / re-creating / re-locating it but working with / refreshing its table model instead. See examples here (includes SwingWorker to make database calls in a background thread), here and here. Please have a look to those answers, there are explanations to make the point clear.
Off-topic
Looking at the quoted lines above, I'd suggest you to avoid using static members. Those are intended to very specific cases (i.e.: constants) but not to general use, and often breaks the encapsulation principle. In this particular case they led to an unintelligible chain of calls that are probably wrong and causing an unexpected hard-to-debug (for us) behavior.
if I understand your problem is that you can not "refresh" the table, in my programs I use this method (DefaultTableModel):
private void jButtonActionPerformed(java.awt.event.ActionEvent evt) { .......
..................
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object[][]{},
new String[]{
"CLMN1", "CLMN2", "CLMN3", "CLMN..."
}) {});
enter code here
model = (DefaultTableModel) jTable.getModel();
model.addRow(new Object[]{("YOUR ROW"}); ----> in a While(or FOR), for any rows
bye :)
I am searching through an array and matching the users entered date with ones stored in the array.
The code is working fine and finds dates or gives appropriate error messages perfectly, the only issue is due to the nature of my program it leaves the possibility of multiple records having the same date.
Now, I only have one form displaying each search result in this format:
lbl txtField
lbl txtField
etc, if the date is matched, it will display the REST of the data matching the record in the text fields.
Now, how would it be possible to display every record's data that has matched a date?
My Code:
public void searchDay() {
String idInputString = JOptionPane.showInputDialog(null, "Please enter the Date you're searching for using the format: DD/MM/YYYY");
for (int i = 0, count = 0; i < orderID.length; i++) {
if (idInputString.equals(startDate[i])) {
txtOrderID.setText(orderID[i]);
txtOrderForename.setText(customerForename[i]);
txtOrderSurname.setText(customerSurname[i]);
txtOrderAddress1.setText(address1[i]);
txtOrderAddress2.setText(address2[i]);
txtOrderTown.setText(town[i]);
txtOrderCounty.setText(county[i]);
txtOrderPost.setText(postCode[i]);
txtOrderCarModel.setText(carModel[i]);
txtOrderCarReg.setText(carReg[i]);
txtOrderStartDate.setText(startDate[i]);
txtOrderStartTime.setText(startTime[i]);
txtOrderSerial.setText(serialNum[i]);
count++;
}
if(i == orderID.length - 1 && count==0){
JOptionPane.showMessageDialog(null, "Order ID Doesn't Exist", "Error!", JOptionPane.WARNING_MESSAGE);
break;
}
}
}
Thank you.
Create more text fields on the fly, or drop results into a JTable.
The final UI could have a JList at the PAGE_START of the GUI that lists the orders for a day or range, but only displays the 'order number'. Then have a JPanel that contains a group of labels and field in the CENTER to display the details of an order selected in the list.
A JTable as suggested by #Ray might be a viable alternative, but I sometimes feel the data is more complex than can be well presented in a single table row (using one row per order).
I'm newly moving from Java to Qt, and I have a question. In JOptionPane you can pass an array of choices and JOptionPane will automatically make a combo box for the user to select a choice from. Is something analogous to this possible in Qt with QMessageBox or another native Qt element?
You should use QInputDialog::getItem(). For example:
QStringList fruits;
fruits << "Apple" << "Banana" ... ;
QString fruit = QInputDialog::getItem(this, "Select fruit", "Fruit:", fruits);
You could just read QMessageBox reference.
I am copy-pasting code sample from it:
QMessageBox msgBox;
msgBox.setText("The document has been modified.");
msgBox.setInformativeText("Do you want to save your changes?");
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
switch (ret) {
case QMessageBox::Save:
// Save was clicked
break;
case QMessageBox::Discard:
// Don't Save was clicked
break;
case QMessageBox::Cancel:
// Cancel was clicked
break;
default:
// should never be reached
break;
}
This code creates a message box with three buttons (Save, Discard, Cancel). Save button is focused.
You can combine values from Standard buttons using bitwise OR operator in setStandardButtons function.
If you need some options known only at runtime I can propose this possible solution.
QMessageBox msgBox;
//set common message box parameters. (informative text, etc)
//iterate through possible options. For each possible option:
{
QPushButton *button = msgBox.addButton(myQStringOption, QMessageBox::AcceptRole);
connect(button, SIGNAL(clicked()), /* response object */, SLOT(/*response slot*/));
}
msgBox.exec();
I am not sure this is the most elegant solution but it should works.
If you don't want to use signals and slots you could use clickedButton() method to determine which button was pressed.
msgBox.exec();
if ((msgBox.clickedButton())->text() == myQStringOption){
//doStuff
}