My program is a GUI. I have this method where when a button is clicked. It populates the next screen with JRadioButtons dynamically.
private void setExamButtonActionPerformed(java.awt.event.ActionEvent evt)
{
if(evt.getActionCommand().equals("Set Exam"))
{
CardLayout cL = (CardLayout)cardPanels.getLayout();
cL.show(cardPanels, "setExamPanel");
}
try
{
//InputStream code
String theMessage = myObject.getMessage();
String delims = "(?=(0*([0-9]{1,2}|100)))";
String[] questions = theMessage.split(delims);
System.out.println(Arrays.toString(questions));
for (int j = 1; j < questions.length; j++)
{
settingQuestionBoxes = new JCheckBox(questions[j]);
settingQuestionTextField = new JTextField("");
jPanel1.add(settingQuestionBoxes);
jPanel1.add(settingQuestionTextField);
jPanel1.revalidate();
jPanel1.repaint();
}
//close streams and socket code
}
catch(Exception e)
{
System.out.println(e);
}
}
Then I have this other method from another screen where the data that is populated from the previous method goes to.
private void setExamQuestionButtonActionPerformed(java.awt.event.ActionEvent evt)
{
if(evt.getActionCommand().equals("Set Exam Question"))
{
ArrayList<JToggleButton> settingQuestionBoxes = new ArrayList<JToggleButton>();
for(JToggleButton questions: settingQuestionBoxes)
{
if(questions.isSelected())
{
System.out.println(questions.getActionCommand());
}
}
CardLayout cL = (CardLayout)cardPanels.getLayout();
cL.show(cardPanels, "instructorPanel");
}
}
So basically when i call this System.out.println(questions.getActionCommand()) I'm trying to see the text from the JRadiobutton that was clicked on.
Right now when I run the program and select a button. Nothing happens.
Put the buttons into a List<JToggleButton> such as an ArrayList<JToggleButton> and then iterate through the list when the information is needed.
for (JToggleButton btn : myButtonList) {
if (btn.isSelected() {
String actionCommand = btn.getActionCommand();
// use the actionCommand here
}
}
Note that JToggleButton is the parent class for JRadioButton and using it would allow you to add JRadioButtons, JCheckBoxes, and JToggleButtons to the list. Since your JRadioButton is not part of a ButtonGroup, perhaps you should be using a JCheckBox instead.
Edit
You now have posted this code, stating it doesn't work:
// Section (A)
ArrayList<JToggleButton> settingQuestionButton = new ArrayList<JToggleButton>();
// Section (B)
for(JToggleButton questions: settingQuestionButon)
{
if(questions.isSelected())
{
System.out.println(questions.getActionCommand());
}
}
Is this code, both (A) and (B), all together in your program? If so, it would make sense that it doesn't work. You should have (A) in a constructor or some set up method. You should follow (A) with code that creates your JRadioButtons or JCheckBoxes, that sets their actionCommand String, that places them in the GUI, and that adds them to the ArrayList.
The part (B) code, the enhanced for loop would need to be in code that is called in response to an event, perhaps in a JButton or radio button's ActionListener.
Please check out this information and fill us in on the details. Please consider creating and posting an sscce illustrating your problem for us.
Edit 2
Your code is confusing in that you appear to have two completely variables of different types with the exact same name, and you appear to be assuming that this will give the variable magical properties that will allow it to know what it's "twin" might be doing. Java doesn't work that way, and in fact variable names are not nearly all that important or smart to allow them any such functionality. Rather your code must be smart.
I'm assuming that more than one of your JCheckBoxes will be checked, and that you want to check which ones are checked at some point in your program. If so, then in your class you should have a List or ArrayList field, something like
private List<JToggleButton> questionsList = new ArrayList<JToggleButton>();
This way this field will available throughout the class.
Then where you create your JCheckBoxes, you add them to this list:
private void setExamButtonActionPerformed(java.awt.event.ActionEvent evt)
{
if(evt.getActionCommand().equals("Set Exam"))
{
CardLayout cL = (CardLayout)cardPanels.getLayout();
cL.show(cardPanels, "setExamPanel");
}
try
{
String theMessage = myObject.getMessage();
String delims = "(?=(0*([0-9]{1,2}|100)))";
String[] questions = theMessage.split(delims);
for (int j = 1; j < questions.length; j++)
{
settingQuestionBox = new JCheckBox(questions[j]); // *** renamed to make more sense
settingQuestionBox.setActionCommand(questions[j]); // **** add actionCommand String
questionsList.add(settingQuestionBox); // ****** add JCheckBox to List
settingQuestionTextField = new JTextField("");
jPanel1.add(settingQuestionBox);
jPanel1.add(settingQuestionTextField);
jPanel1.revalidate();
jPanel1.repaint();
}
//close streams and socket code
}
catch(Exception e)
{
// System.out.println(e);
e.printStackTrace(); // ***** more informative
}
}
Then elsewhere in your code
setExamQuestionButtonActionPerformed(java.awt.event.ActionEvent evt)
{
if(evt.getActionCommand().equals("Set Exam Question"))
{
// ArrayList<JToggleButton> settingQuestionBoxes = new ArrayList<JToggleButton>();
for(JToggleButton questions: questionsList)
{
if(questions.isSelected())
{
System.out.println(questions.getActionCommand());
}
}
CardLayout cL = (CardLayout)cardPanels.getLayout();
cL.show(cardPanels, "instructorPanel");
}
}
And of course you'll need to take care that the ActionListener is added to a button
Related
I'm on a project right now and I'm trying out some new code to make my program more efficient. I was thinking of an ArrayList "dice" which will contain some buttons (that're supposed to be dice). If I for example array.add(die1), I assume I can refer to the object in the array instead of the actual button.
For example: I can set the text of die1 as die1.setText(""); I would also like to do it to the object in the array directly so I can use loops, like, array.get(i).setText("");
But it doesn't work which is weird. If I do array.get(0).getClass() it says javax.Swing.JButton which seems to be right.
Java 11
ArrayList dice = new ArrayList<JButton>();
private void die1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if (die1.getBackground() == Color.red) {
dice.remove(dice.indexOf(die1));
die1.setBackground(Color.green);
}
else {
dice.add(die1);
die1.setBackground(Color.red);
}
}
private void btnRollActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
for (int i = 0; i < dice.size(); i++) {
int random = roll();
dice.get(i).setText(""+random); //This displays as error; uncompilable
}
}
Expected: to work.
But naturally it can't compile and crashes.
Because you haven't typed the declaration of your List.
Try this:
List<JButton> dice = new ArrayList<>();
I am trying to build a GUI application that will let the user to choose product by clicking the button. I hold products in an ArrayList and then use this ArrayList and for loop to create proper number of JButtons. When user clicks the button price of that product should appear in the TextField.
My problem is: how to find out which button was clicked? If I was using Array of Buttons (JButton button[] = new JButton[3]) I would find it in the loop:
if (target.equals(button[i]))...
But I can't figure out how to find it when I use ArrayList of products to create buttons. Any help would be well appreciated. Here's my code (I tried many approaches so I only post the one I started with - it finds only the last item in the ArrayList).
public void addStuff() {
stuffList.add(new Stuff("Lemon Haze", 15.00));
stuffList.add(new Stuff("OG Kush", 16.00));
stuffList.add(new Stuff("Strawberry Cough", 18.00));
for (int i = 0; i < stuffList.size(); i++) {
stuffButton = new JButton();
stuffPanel.add(stuffButton);
stuffButton.setText(stuffList.get(i).getName());
stuffButton.addActionListener(this);
}
}
public void actionPerformed(ActionEvent e) {
Object target = e.getSource();
for (int i = 0; i < stuffList.size(); i++) {
if (target == stuffButton) {
subtotalTextF.setText(stuffList.get(i).getPrice() + "");
}
}
}
Create a specific class for your ActionListener, and give it a reference to your Stuff - this way you can create a specific instance for each button that automatically links back to the correct instance of Stuff, without trying to search on the fly:
stuffButton.addActionListener(new StuffListener(stuffList.get(i));
...
private class StuffListener implements ActionListener {
private final Stuff myStuff;
public StuffListener(Stuff stuff) {
this.myStuff = stuff;
}
public void actionPerformed(ActionEvent e) {
subtotalTextF.setText(String.valueOf(myStuff.getPrice()));
}
}
Note that you can accomplish this with a bit less code using lambdas, but figured this is the clearest way to explain the logic, which is the same either way.
On a side note, based on the code you've posted, the reason it's only getting the last button is because you're comparing to stuffButton, which is not changed from the last instance after your initialization loop is done.
I see there are some questions already asked about this topic but I haven't come up to an answer for my. I am writing a code where user types something in JTextField, and after clicking a button, his word is replaced with the number of asterisks with the same number of characters his word had e.g "table" would be replaced by "****". i did it this way:
ask.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String guess = "";
String given = textGive.getText();
for (int i=0; i<given.length(); i++){
String asterisk = "*";
guess += asterisk;
textGive.setText(guess);
}
}
});
I know that I did not do this in a great way, but I did not know how to do it better. Any recommendations?
Now, I want somehow to save both Strings, the original word and the asterisk one outside the scope so I can access it in another ActionListener and modify it further.
Before writing first ActionListener i did write String guess = "" and String given = "" but it seems as it did not do anything.
So, in my second ActionListener i want to send him the string given I received when the user typed his word.
guess.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String attempt = textGuess.getText();
char att = attempt.charAt(0);
for (int i=0; i<5; i++){
if (given.charAt(i)==att){
textGuess.setText("Ok!");
}
}
}
});
Eclipse gives me error saying:
"Cannot refer to the non-final local variable given defined in an enclosing scope".
I understand that I need to make given final in order to acces it further, but how to do that if the variable depends on text input from first ActionListener? Is there some other solution for this problem? I've recently started using java, so I do not know the language so well.
Anything that you want visible to class should be placed in instance fields, not in local variables. For instance, the given variable should be a private non-static field declared in the class, and not a variable buried within your listener's actionPerformed method.
e.g.,
public class Foo extends JPanel {
private JButton ask = new JButton("Ask");
private JTextField textGive = new JTextField(10);
private String given = ""; // visible throughout the class
public Foo() {
add(textGive);
add(ask);
ActionListener listener = e -> {
String guess = "";
// String given = textGive.getText(); //visible only within this method
given = textGive.getText();
guess = given.replaceAll("\\w", "*");
textGive.setText(guess);
};
ask.addActionListener(listener);
textGive.addActionListener(listener); // also give the same listener to the JTextField
}
I am not sure how to ask this. The program I am working on is done, but it seems like it has excessive code. Here is part of the code:
chkDef1 = new JCheckBox
if (chkDef1.isSelected()) {
actual = chkDef1.getText();
}
else if (chkDef2.isSelected()) {
actual = chkDef2.getText();
}
else if (chkDef3.isSelected()) {
actual = chkDef3.getText();
}
else {
actual = chkDef4.getText();
}
There are other areas where there is a lot of duplicate code with the chkDef1 - 4 checkboxes. What I would like to do is use a loop in the areas where the code is duplicated and then just use 1 assignment statement.
I've tried :
if(('chkDef' + counter).isSelected())
I've also tried assigning "'chkDef' + counter" to a String variable and then adding isSelected. Unfortunately I keep getting error messages.
I am a novice programmer so I do not know if what I want to do is possible or what it is called. If it is possible an explanation of how would be appreciated.
Simply create a list of checkboxes and iterate through it.
ArrayList<JCheckBox> checkboxes = new ArrayList<JCheckBox>();
//Init your checkboxes array.
for(JCheckbox chkbox :checkboxes)
{
if(chkbox.isSelected())
{
actual = chkbox.getText() ; break;
}
}
Although, there could be a JCheckbox group that does what you want.
Looks like you can use ButtonGroup and get the elements to iterate through it.
You could create an array that contains all the check boxes and then loop through the array...
JCheckBox[] boxes = new JCheckBox[] {chkDef1,chkDef2,chkDef3,chkDef4}
for (JCheckBox box : boxes) {
if (box.isSelected()) {
actual = box.getText();
break; // We don't want to loop unnecessarily
}
}
Equally, you could create a simple method that takes a variable number of arguments...
public String getCheckedItem(JCheckBox... boxes) {
String actual = null;
for (JCheckBox box : boxes) {
if (box.isSelected()) {
actual = box.getText();
break; // We don't want to loop unnecessarily
}
}
return actual;
}
And call it like...
String actual = getCheckItem(chkDef1, chkDef2, chkDef3, chkDef4);
Personally, I'd return the check box, but that's up to you
If you're only interested in maintaining a single selected check box (ie not allowing multiple check boxes to be selected) then you should seriously consider using JRadioButtons and ButtonGroup instead.
Otherwise you could collect ALL the selected checked boxes...
public JCheckBox[] getCheckedItem(JCheckBox... boxes) {
List<JCheckBox> selected = new ArrayList<JCheckBox>(boxes.length);
for (JCheckBox box : boxes) {
if (box.isSelected()) {
selected.add(box);
}
}
return selected.toArray(new JCheckBox[selected.size]);
}
How to enclose try-catch in a public method and invoke when needed.
I have try-catch in one screen code. I want to invoke it from another screen by calling a method to it that stands public(to the entire application).
Is it possible ? If so how.
Please guide.
Re edits:
As seen in the below code, second tab pane implementation has been shown,please ignore the syntactic differences one may find with native java(This has been implemented for Blackberry JDE). Implementation constructs remain the same hence please overlook the differences and suggest a logical solution to the problem being faced.
// setup the second tab
vfm = new VerticalFieldManager(
Field.USE_ALL_HEIGHT | Field.USE_ALL_WIDTH |
Manager.VERTICAL_SCROLL | Manager.NO_HORIZONTAL_SCROLL );
//Initialize grid for publishing results
grid.add(new LabelField("Name")
{
public void paint(Graphics graphics)
{
graphics.setColor(Color.CYAN);
super.paint(graphics);
}
});
grid.add(new LabelField("Total")
{
public void paint(Graphics graphics)
{
graphics.setColor(Color.CYAN);
super.paint(graphics);
}
});
grid.setColumnPadding(100);
grid.setRowPadding(20);
//TRY CATCH STARTS HERE
try
{
//Open or create the database
Database db = DatabaseFactory.openOrCreate("database1.db");
Statement statementG55 = db.createStatement("CREATE TABLE IF NOT EXISTS GTemp4(gname TEXT,gbal INTEGER)");
statementG55.prepare();
statementG55.execute();
statementG55.close();
Statement statementG56 = db.createStatement("SELECT gname,gbal FROM GTemp4 ORDER BY ROWID DESC");
statementG56.prepare();
statementG56.execute();
Cursor c = statementG56.getCursor();
//Get to the row of grid
for (int i =1; i < grid.getRowCount(); i++)
{
System.out.println("Inside for first loops");
//Get to the column of grid
for (int j = 0; j < grid.getColumnCount() ; j++)
{
System.out.println("Inside for second loops");
//Get to the row of temp4 table
while(c.next())
{
System.out.println("Inside while");
Row r;
r = c.getRow();
for (int k = 1; k >=0; k--)
{
System.out.println("Inside for loops");
if(k==0)
{
System.out.println("Retrieving Names");
grid.insert(new LabelField(r.getString(k))
{
public void paint(Graphics graphics)
{
graphics.setColor(Color.GOLD);
super.paint(graphics);
}
},i,j);
}
else
{
System.out.println("Retrieving other values");
String p = "" + r.getObject(k);
grid.insert(new LabelField(p)
{
public void paint(Graphics graphics)
{
graphics.setColor(Color.GOLD);
super.paint(graphics);
}
},i,j);
}
grid.setBackground(BackgroundFactory.createLinearGradientBackground(Color.MIDNIGHTBLUE,Color.STEELBLUE,Color.MIDNIGHTBLUE,Color.STEELBLUE));
}
System.out.println("Exiting while");
}
System.out.println("Exiting sec for");
break;
}
System.out.println("Exiting first for");
break;
}
statementG56.close();
db.close();
}
catch(Exception e)
{
System.out.println( e.getMessage() );
e.printStackTrace();
}
vfm.add(grid);
nullFld = new NullField( Field.FOCUSABLE );
hfm = new HorizontalFieldManager();
hfm.add( nullFld );
hfm.add( myLbl );
pane = new Pane( hfm, vfm );
model.addPane( pane );
A big thanks to everyone below who have made a suggestion.
Your question is still cryptic. I am assuming that you have some code which does some searching and then, it publishes the results to some JPanel called pane2. What you want is that once the Search button is pressed, you call the code.
You could have a method like so:
public void doSomeSearching(...) throws Exception //This will allow you to remove the try/catch block from within the method and be able to catch any exceptions in the layer above.
{
//Do the searching
//Update panel2
}
Then, what you need to do is to add an action listener to your button. This will allow the code to be executed once the button is clicked. (You can find more information on ActionListeners here).
JButton btnSearch = new JButton("Search");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
try
{
doSomeSearching();
}
catch (Exception e)
{
//Do something when exception is raised.
}
}
});
This should allow you to trigger the search functionality when you click the button and handle any exceptions which should arise.
EDIT:
another try-catch included within pane2 to publish(It keeps running from the start,i.e,doesnt wait for action listener of search button to be executed)`
Having something loop indefinitely is something which should be ideally avoided since this consumes CPU cycles while basically doing nothing. This usually increases the resources your application consumes and might also cause your GUI to hang. If I where you I would have some method which updates panel2 which you than call once you have done your searching.
That being said, you could have some intermediary variable, such as a string which contains whatever you need to print and your search method continuously updates this intermediary variable.
This approach is not recommended.
Instead of placing a generic surrounding try-catch block around your method, you should consider adding the "throws" clause to the declaration of each method you want to handle this way, and then handle all those exception in a higher layer.