"Metaaccess" of Objects in Java With Variables in the Identifiers - java

I want to access to a certain number of objects in Java without write a lot of code, for example:
int X;
for(X=0;X<5;X++){
jLabelX = /*do something*/
}
Would be something like this:
When X=0 then jLabel0 is access, X=1 then jLabel1 and so on...
Is there any way of doing this? or i need to specify all the cases

The best way of doing this is to not have variables called jLabel0, jLabel1 etc in the first place. Instead, have an array variable (or some other collection):
JLabel[] labels = new JLabel[5];
for (int i = 0; i < labels.length; i++) {
labels[i] = new JLabel();
// Whatever
You can get at fields with reflection, but any time I see variables x0, x1, x2 etc I shudder - it's a clear indication that a collection of some kind is a better fit.

Related

How do I modify 100 objects without having to write 100 lines of code? (Java)

I have a lot of JButton objects which have the names a, b, c, d, ...
I want to set all of their states according to a boolean array I have. For example, if the boolean array is [true, false, true], I want to set a's state to true, b's state to false, and c's state to true. (using JButton.setEnabled(boolean))
The problem is that I have too many objects and if I have to change their states one by one, the code is going to get long and redundant.
How do I do this in a simple way?
I'm programming in Netbeans, Java with Ant, JFrame Form.
Edit) Netbeans won't let you change the code that creates the objects.
So "private javax.swing.JButton a" this part is unchangeable.
Having that many individual JButtons seems like something you should try to avoid at all costs, especially if you have scenarios when you need to address them all, but if you are stuck with that you could do this:
JButton a = new JButton();
JButton b = new JButton();
//Etc for all the buttons you make
JButton[] list = {a,b}; //Manually insert the JButtons into an array
for(int i=0; i < list.length; i++) //For loop through all of the buttons in the list
{
list[i].addNotify(); //Then just use list[i] and that will be whatever JButton is at index i in the list (so in my example, i=0 is button a, i=1 is button b)
}
In the code above you insert all of your buttons into an array and then do the same function like I showed, where I called the .addNotify() function on every button in the list.
If you do have the opportunity to start from scratch and this would make things easier, I suggest putting all of the buttons into an array to begin with, such as the code below:
JButton[] list = new JButton[10]; //Manually insert the JButtons into an array
for(int i=0; i < list.length; i++) //For loop through all of the buttons in the list
{
list[i] = new JButton();
list[i].addNotify(); //Then just use list[i] and that will be whatever JButton is at index i in the list (so in my example, i=0 is button a, i=1 is button b)
}
Arrays are especially useful for these scenarios where you have a lot of objects of the same type and have the same operations done to them, so based on your description it might be a good application

Final variable being changed without any = statements

I'm making an autoclicking project in java for personal use, and using the following method to get coordinates of a click from a class that extends MouseAdapter. The click is being done on a JFrame.
int[] mouseCoordinates = new int[2]; //The coordinates of the click
mouseCoordinates = mouseListenerExample.getCoordinates();
final int[] baseCoordinates = mouseCoordinates; //The base coordinates (no click) which is this problem//
int[][] totalCoordinates = new int[4][2]; //An array that collects all coordinates of 4 mouse clicks
for (int i = 0; i < 4; i++){ //the goal is to get the coordinates of 4 clicks
while (mouseCoordinates[0] == baseCoordinates[0]){
mouseCoordinates = mouseListenerExample.getCoordinates(); //The problem occurs here: when mouseListenerExample.getCoordinates() changes, mouseCoordinates is changed, baseCoordinates is also changing, which it shouldnt, since there are no statements that say so.
if (mouseCoordinates[0] != baseCoordinates[0]) {
break;
}
}
totalCoordinates[i] = mouseListenerExample.getCoordinates();
mouseListenerExample.setCoordinates(baseCoordinates);
mouseCoordinates = baseCoordinates;
}
Is there some statement that is changing baseCoordinates that I am missing?
Your baseCoordinates variable has been declared final, and so it cannot change, but since it is an int[] or int-array, it is a reference variable, and so what cannot change is the reference itself, not the state of the reference, and so the ints held within the array can (and in your case -- do) change.
You're changing the values held by mouseCoordinates. Since the baseCoordinates refers to the exact same int[] object, then this will likewise change the values for baseCoordinates. Best to create a completely new int object for the final variable if you don't want it changed.
Do something like:
final int[] baseCoordinates = new int[mouseCoordinates.length];
System.arraycopy( mouseCoordinates, 0, baseCoordinates , 0, mouseCoordinates.length );
So after some looking around, i just replaced the arrays with individual ints, and added a print statement right before the break, and it made it work.

Deep copies of 2d object array

how can I make on a button press a new deep copy of a 2 dimensional array?
Basically I created a game field with buttons. The game is called sokoban and it's a puzzle. The player is moving from one button to the other with arrow keys on a fixed map (8x8 buttons).
I want to implement an undo function. So I thought that I just create a deep copy of the JButton array before each move and save it into a stack. So when I press the undo button it calls the pop function of my stack. The problem is that I need to declare and initialize another JButton[][] where I can save the game field to before each move. Since I want infinite possible moves and also undos it seems impossible to me. I can't declare and initalize infite diffrent JButton[][] arrays. Any idea on how I can solve that?
That's how I copy a 2d object array:
JButton[][] tempArray = new JButton[jbArray.length][jbArray[0].length];
for (int i = 0; i < getJbArray().length; i++) {
for (int j=0;j<getJbArray()[0].length;j++) {
tempArray[i][j]=jbArray[i][j];
}
}
movesStack.push(tempArray);
Unfortunately you can't clone swing components in general, as they do not implement the Cloneable interface. As I see it you have two options:
Create a new JButton inside your double loop and copy whatever properties (like alignment, color etc.) you have set to the new JButton
Write your own class that extends JButton and implement the Cloneable interface
The first way is somewhat of a hack and not very robust or reusable. The second way is much better practice. In this case you'll have to define how the deep copy is supposed to happen, and ensure that all relevant properties are copied over.
You've got the right idea. You're not quite going deep enough.
public JButton[][] copy(JButton[][] jbArray) {
JButton[][] tempArray = new JButton[jbArray.length][jbArray[0].length];
for (int i = 0; i < jbArray.length; i++) {
for (int j = 0; j < jbArray[0].length; j++) {
tempArray[i][j] = new JButton(jbArray[i][j].getText());
}
}
return tempArray;
}
Rather than copying JButtons, you should have a model that you use to set the JButtons. Maybe a ModelClass[][] array?

How to find out which textfield was typed into by the user in a Java JtextField?

I have the following code:
int[] matrix = new int[9][9];
(for int x = 0; x <= 8; x++){
(for int y = 0; y <= 8; x++){
JtextField matrix[x][y] = new JtextField(“Matrix" x + y)
int[] coords = new int[2];
coords[0] = x;
coords[1] = y;
matrix[x][y].putClientProperty("coords", coords);
matrix[x][y].setText(game[x][y]);
}
}
After the loops end, I need a way of finding out which textfield the user typed into (the user also hits enter). So:
1. How do I check if a JtextField has been edited without knowing which one it is or its name?
2. How do I check which "coords" the textfield is positioned at? I have an idea of how to do it, but for some reason I cannot code it.
I feel like the answer is staring me right in the face, but its late, I'm tired, and I'm getting flustered. Thanks!
The answer depends on what you want to achieve.
If you're only interested in the end result, you could use an ActionListener (for when the user hits Enter) and a FocusListener for when they don't and leave the field any way (assuming you want to know this)
When the respective event occurs, you can inspect the source of the event by using getSource. Now this returns Object, but you can use instanceof to determine if the object can be cast to a JTextField...
For example...
Object source = evt.getSource();
if (source instanceof JTextField) {
JTextField field = (JTextField)source;
int[] coords = field.getClientProperty("coords");
}
Take a look at How to write an Action Listener and How to write a Focus Listener for more details.
Depending on your needs, you could also take a look at Validating Input

Null Pointer Exception on a 2D array (Java)

I have a class, "Tetris", in which one of the instance variables is "board". "board" is 2D array of Color objects. Upon the creation of a tetris object I call a method that sets the dimensions of board and then sets all of the Color objects to be the Default value, that is to say, Color.blue.
public Tetris(int rows, int cols) {
this.rows = rows;
this.cols = cols;
reset(rows, cols);
}
public void reset(int rows, int cols) {
Color[][] board = new Color[rows][cols];
for(int i = 0; i<this.rows; i++) {
for(int j = 0; j<this.cols; j++) {
board[i][j] = DEFAULT_COLOR; // Color.blue; //DEFAULT-COLOR
}
}
}
Unfortunately, when I run the code (which obviously has not been posted in its entirety) I get a null pointer exception on the line:
board[i][j] = DEFAULT_COLOR; // Color.blue; //DEFAULT-COLOR.
Is there anything obviously wrong with what I am doing?
It would help if you would post a short but complete program which demonstrated the problem. The code you've posted isn't enough to throw an exception, but I can see how with a few changes it might.
In particular, it seems odd to me that you're declaring a new local variable within your reset method... and you also have an instance variable called board? I suspect the solution may be as simple as changing the start of reset to:
board = new Color[rows][cols];
If your real code uses the local variable to create the array, but then tries to assign values via the instance variable, that could very well be the cause of the problem.
It also seems wrong that you're passing rows and cols into the method, and using those parameters in one place but the instance variables this.rows and this.cols in the loop. Why bother passing them at all?
I think you must allocate every one of those colors like this:
board[i][j] = new Color(...

Categories

Resources