How to create references to objects created in a loop? - java

I'm sure this question has been asked but I cannot find it (on SO or Google) for my life.
How can I most effectively create a reference to multiple objects that I create in a loop?
In this specific case, I am using Swing to add JButtons to a GridLayout.
int numOfButtons = 10;
for (int i = 0; i < numOfButtons; i++){
add(new JButton("" + i));}
If later I want to change the text on the buttons, how would I do so? Say, if I wanted to change button number 8:
buttonEight.setText("DO NOT CLICK!!!);
How would I create a reference to the button with the 8 on it from buttonEight?
The only thing I can think of is creating a bunch of instance variables before the loop. Except... Well. Actually , that wouldn't work (I don't think)
Something that would do this:
JButton button8;
for (int i = 0; i < numOfButtons; i++){
button + i = new JButton(""+ i);
//like, if i = 8 then button + i gets me button8 to reference it or something?
//obviously that doesn't work
}
button8.setText("DO NOT CLICK!!!);
and also I'd be in trouble creating the right number of instance variables if numOfButtons is variable.
How should I do this?

Use an ArrayList:
ArrayList<JButton> list=new ArrayList<>();
int numOfButtons = 10;
for (int i = 0; i < numOfButtons; i++){
JButton jb=new JButton("" + i);
list.add(jb);
add(jb);
}
Later (assuming you want to change the text of 8th button (which is 7 in list)):
list.get(7).setText("...");
The list only create a reference to JButton object. Then any change made to it will reflect on the UI.

Or, if you wanted to set the text of only the eighth button, you could use a conditional to single out that button:
for (int i=0;i<numOfButtons;i++) {
if (i==7) {
add(new JButton("DO NOT CLICK!");
} else {
add(new JButton(""+i);
}
}
which will save memory space in your program than if you use an ArrayList.

Related

How to rewrite the text of buttons that are not separately defined

I have started trying to write a code similar to the game 2048, however the size of the board can have any value depending on what the user inputs. I decided to make the numbers on the board, for style purposes, separate buttons.
This is the current GUI:
How can I make it so that when the buttons: up, down left, or right are pressed each of the button's in the board texts are changed? I know about event listeners I just mean how can I replace the button's in the same grid with different values when I defined the buttons on the board as:
`for(int i = 2; i < rows + 2; i++) {
for(int j = 2; j < columns + 2; j++) {
gbc.gridx = j;
gbc.gridy = i;
num = new JButton(board.board[j-2][i-2].getValue()+"");
num.setFont(new Font("monospaced", Font.PLAIN, screenSize.height/50));
num.setEnabled(false);
this.add(num, gbc);
}
}`
The only ideas I've had was to create an array of buttons and then change the button's text in the array of buttons and then replace the old array of buttons with the new one. Also sorry if it has some super simple answer that I just couldn't find, I am just about finished with one semester of coding courses in college.
You could store the JButtons on a HashMap and use column number and row number as a key to find the correct button.
Something like:
Map<String, JButton> grid = new HashMap<String, JButton>;
for(int i = 2; i < rows + 2; i++) {
for(int j = 2; j < columns + 2; j++) {
grid.put(String.valueOf(i) + String.valueOf(i), new JButton("some text"));
// we transform the integers into String, otherwise the operator "+" will sum them
// instead of concatenate them.
}
}
Now you cant get the desired button with grid.get(row + column);
JButton bt;
JButton bt = grid.get("4" + "6");
bt.setText("different text");
grid.put("4" + "6", bt);
I don't think you should use Buttons to do such a game button it's something that you can click on it since your are not supposed to click on numbers. If I were you I would use a gamePanel which contains fixed labels since it's easier changing text of label than moving label.
I would add MouseListener to the gamePanel and then fill implemented methods in order to manage when the mouse left button is pressed and move to left and so on.
So create an array of Label.
Create a method which add and move numbers according to the direction of the move. For instance if you make a left to right move you will start to add the numbers of the first column into the second column when they have same values. Next you just have to do it recursively until the last column.
If you need a bit more explainations ,I'll be pleased to help you.

Declare multiplie swing elements at once

I am working on a little game, a Java project for IT-classes.
To add/declare(???) Java swing elements I've used this type of writing:
JLabel A = new JLabel();
JLabel B = new JLabel();
//More JLabels...
JButton A = new JButton();
JButton B = new JButton();
//More JButtons...
That the code does not become longer and (more) confusing, I continued with this type of writing:
JLabel A = new JLabel(), B = new JLabel()/*More JLabels...*/;
JButton A = new JButton(), B = new JButton()/*More JButton...*/;
/*Generaly more comments everywhere over the code for my teacher (and me)
*and more for a better overview.
*/
My question is:
Is there a shorter way to add/declare(???) multiple Java swing elements at once?
//like this
JLabel A, B, C, D, E, F = new JLabel();
//or
new JLabel[A, B, C, D, E, F];//PLS don't ask what I'm doing in this line xD
or may is there already a semilar question in Stackoverflow that I've not found?
Edit
This question may already have an answer here: Initializing multiple
variables to the same value in Java 6 answers
Here the Link to the question
Your question has been identified as a possible duplicate of another
question. If the answers there do not address your problem, please
edit to explain in detail the parts of your question that are unique.
Not worked with Jbuttons and JLabels.
If you are using Java 8 you can use :
List<String> labels = ....;
Stream<Button> stream = labels.stream().map(Button::new);
List<Button> buttons = stream.collect(Collectors.toList());
From the book Java se 8 for the really impatient
Then you can use :
JPanel p = new JPanel();
buttons.forEach((t) -> p.add(t));//add your buttons to your panel
It depends, if all your objects are JLabel or the same object type, you could try:
An array of JLabel like:
JLabel[] labels = new JLabel[size of your array];
Then access it after inside a for loop:
for (int i = 0; i < labels.length; i++) {
labels[i] = new JLabel("I'm label: " + i);
}
A List of labels:
ArrayList <JLabel> labelsList = new ArrayList <JLabel>();
Then you could:
for (int i = 0; i < 10; i++) { //I take 10 as an arbitrary number just to do it in a loop, it could be inside a loop or not
labelsList.add(new JLabel("I'm label-list: " + i));
}
And later you could add them like:
pane.add(labels[i]); //Array
pane.add(labelsList.get(i)); //List
The above code should be inside a loop or change i for the explicit index of the element to be added.
If you want to do the same thing (or a similar thing) many times in a program, the answer is to use a loop of some kind. Here, you could declare an array (or List) of JButton elements, and loop over it to initialize its elements:
final int NUM_BUTTONS = 6;
JButton[] buttons = new JButton[NUM_BUTTONS];
for (int i = 0; i < NUM_BUTTONS; i++) {
buttons[i] = new JButton();
}
// refer to A as buttons[0], C as buttons[2], etc
You can make variables equal to each other after declaring them.
String one, two, three;
one = two = three = "";
So, I think you could do
JLabel A,B,C,D,E,F;
A = B = C = D = E = F = new JLabel();

how to update a container in java that already has data in it

Hi all i need to update a containers data for a sudoku game i am creating but am struggling to get the field to update with the new data.the container uses a grid layout and each cell contains a button with the appropriate number for sudoku in it and i need to know how to update the text in these buttons. any help with what methods i could use or any help in general would be greatly appreciated. please see the code i currently have to try and update below i know its probably messy and completely on the wrong track but ive just been trying to mess with stuff hoping it would work.
public void update(int[][] grid2)throws NullPointerException{
myGrid = new Container();
try{
for(int i = 0; i<9; i++){
for(int j = 0; j<9; j++){
String appropriateNumber = convertSimple(grid2[i][j]);
JButton button = new JButton(appropriateNumber);
button.addActionListener(new sudokuListener());
myGrid.add(button);
}
}
}
catch(NullPointerException e){
}
myGrid.setLayout(new GridLayout(9, 9));
myGrid.setPreferredSize (new Dimension(400, 400));
add(myGrid);
puzzleGUI.update();
}
puzzlGUI.update simply contains puzzle.validate() (puzzle being the GUI)
[edit]
ok i have changed things around a bit and used the JButton arrya as suggested and i have been able to set the text of the buttons in this array (i know through a system.out.print) but this does not update the text which is in the actual GUI. aaaaahhh coding is not fun at the end of a semester please help anyone
To re-iterate, if you have a grid of JButtons, why re-create them every time? Why not simply iterate through the components that are already in the grid and update their state, such as perhaps the text showing on the JButtons?
for(int i = 0; i<9; i++){
for(int j = 0; j<9; j++){
String appropriateNumber = convertSimple(grid2[i][j]);
someButtonArray[i][j].setText(appropriateNumber);
// no longer need this stuff
// JButton button = new JButton(appropriateNumber);
// button.addActionListener(new sudokuListener());
// myGrid.add(button);
}
}
Your update method is creating new Swing components every time it is called which is unnecessary if you just need to update the text. To directly update the text in any JButton you could create a button array like so:
JButton[][] buttons = new JButton[9][9];
and create like this (called only once):
for (int i = 0; i<9; i++) {
for(int j = 0; j < 9; j++){
String appropriateNumber = convertSimple(grid2[i][j]);
button[i][j] = new JButton(appropriateNumber);
button[i][j].addActionListener(new sudokuListener());
myGrid.add(button[i][j]);
}
}
then to update :
buttons[row][column].setText("New Text");

JCombobox and JTextfield

I'm trying to work to display a number of jtextfield according to one of the given values in a combobox.
So, I will have a drop down menu with let's say 1 to 4. If the user selects number 3, 3 textfields will be displayed. I've created the jcombobox with a selection of numbers. But I'm not sure how to implement this. If I'm not mistaken I need to use
ItemEvent.SELECTED
I think I need to create a reference to the JTextField object that will be available to the JComboBox's itemListener object.
Any help would be greatly appreciated.
I've added this to my class :
// aOption is the combobox I declared
aOptionComboBox.setModel(new DefaultComboBoxModel(new String[]{"1","2","3"}));
public void itemStateChanged(ItemEvent event) {
String num = (String)aOptionComboBox.getSelectedItem();
int num1 = Integer.parseInt(num);
JTextField[] textfields = new JTextField[num1];
for (int i = 0; i < num1; i++)
{
textfields[i] = new JTextField("Field");
getContentPane().add(textfields[i]);
textfields[i].setBounds(200, 90, 100, 25);
}
}
am I on a right track?
use the getSelectedItem() on the combobox. This will either yield a string or an integer (depending on how you implemented it). Next use a for-loop to determine the amount of JTextField's and store them in an array.
int amount = myJComboBox.getSelectedItem();
JTextField[] textfields = new JTextField[amount];
for (int i = 0; i < amount; i++) {
textfields[i] = new JTextField("awesome");
this.add(textfields[i]);
}
this way you can easily store the textfields and add them to your panel.
Some added information.
The textfield-array must be accesible outside the eventListener, so you must implement it in your class. that way the whole class can use it.

Problem regarding loops. I need to access 10 labels through a loop in java?

I have a problem regarding loops. I need to access 10 labels which have names like label1, label2, label3 .... etc. I need to know whether I can access those labels by going through a loop in java?
How about using List or an array
List<JLabel> labels = new ArrayList<JLabel>();
labels.get(index);
Change those labels to be an array, and access it using an index.
For example:
JLabel[] labels = new JLabel[10];
for (int i = 0; i < labels.length; ++i) {
labels[i] = new JLabel("Label " + i);
}
for (int i = 0; i < labels.length; ++i) {
// access each label.
}
Put your labels in to LinkList or array
Then you can access those array or linkList on a loop
If you cannot change the labels names / put them into an array you can make an array of references to the labels and fill it at the beginning of your program with the list of your labels.
'Access to labels' is kinda vague. Are you referring to different instances of java.awt.label? If so you can simply loop over them when they're in a list with a for-each statement.
If you are talking about Java labels, you can use a switch statement instead. If you are talking about objects such as a JLabel, use an array or ArrayList.

Categories