wrong setting an arraylist - java

I want to ask a question about arraylist. In my program I defined an arraylist and an user defined object. The problem is when I want to add an object to this arraylist, it adds object, but next time when I give the different values to user object, it sets values of the old object that I added before to the new one. I mean, for example I have 13 in my old object and the new one is 14, it makes the old one 14. I couldn't find a solution for this. I'M working on a drawing program. I'm posting some parts of the code.
public class Tester extends JPanel implements MouseMotionListener, MouseListener {
ArrayList<Lines> array = new ArrayList<Lines>();
Lines l1;
...
public Tester(){
l1 = new Lines();
l1.point1 = new Point();
l1.point2 = new Point();
l1.denklem = new int[3];
And thi is how I add object into arraylist
else if(lineci == true){
if(mouseclicks == 0){
l1.point1.x = e.getX();
l1.point1.y = e.getY();
statusBar.setText( String.format( "Clicked at [%d, %d]",
e.getX(), e.getY() ) );
mouseclicks++;
starter = false;
}
else if(mouseclicks == 1){
l1.point2.x = e.getX();
l1.point2.y = e.getY();
statusBar.setText( String.format( "Clicked at [%d, %d]",
e.getX(), e.getY() ) );
mouseclicks = 0;
int a = l1.point2.y - l1.point1.y;
int b = l1.point1.x - l1.point2.x;
int c = (l1.point2.x * l1.point1.y) - (l1.point1.x * l1.point2.y);
l1.denklem[0] = a;
l1.denklem[1] = b;
l1.denklem[2] = c;
array.add(l1);
// array3.add(l1);
repaint();
}
}
When I click mouse, if lineci is true, it draws a line according to points. I get always last lines when I print elements of arraylist. If I draw 10 lines, 10 elements of the arraylist are the same. It never keeps old values inside arraylist. By the way boolean starter is not important. I just forget to remove it.

You are simply adding the same object repeatedly to the list. Each addition to the list is merely adding a reference to the same object: l1. Hence, when you update the state of l1, the old "object" also appears to have changed.
To rectify this you need to create a new instance of Lines for each addition you wish to perform.

You're referencing the original l1 object, so it will modify the original l1 object--whether or not it's in the list.
If you want to create a new object, create a new object.

i think your l1 reference is still pointing the previous object added to the arrayList , you should override the reference as soon as you add the object to the arraylist .
by either
l1 = new Lines();
or
l1 = null;

Use l1.clone() before changing the value inside if you want to keep all values same but one and the class is clonable or create a new object which is better for your case.

Related

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.

ArrayList index is always 0 (zero) [duplicate]

This question already has answers here:
Why does my ArrayList contain N copies of the last item added to the list?
(5 answers)
Closed 6 years ago.
i have a problem with ArrayLists in Java.
The problem is that when i add an element to the list (pointStorer), the index doesn't increment and every time it resets and remains zero.
Here's my code (well it's only the important part of the code):
private ArrayList pointStorer = new ArrayList();
private Point pointValues = new Point();
public void mouseClicked(MouseEvent e) {
pointValues.setLocation(e.getX(), e.getY());
mousePointX = pointValues.x;
mousePointY = pointValues.y;
repaint();
}
public void paint(Graphics g){
pointStorer.add(pointValues);
System.out.println("Index point "+pointStorer.indexOf(pointValues));
}
I use the method .indexOf to know what's the index of the element that i've just added, but it remains always zero.
Thank you in advance for your help.
You only have one Point instance which you keep adding to the ArrayList, so all the indices of the ArrayList contain the same Point.
To add a new Point each time the mouse is clicked, you should create a new Point instance :
public void mouseClicked(MouseEvent e) {
Point pointValues = new Point();
pointValues.setLocation(e.getX(), e.getY());
mousePointX = pointValues.x;
mousePointY = pointValues.y;
repaint();
}
You should instantiate your pointStorer variable inside your paint() method

Stackoverflow in recursive method to create hiearchy

Suppose i have an image like this (the numbers are for explaining, so focus on the white):
I'm working on a method to create a hiearchy of the contours instead of a flat list. In the case of the image above:
-n1 holds 1 contour: n2
-n2 hold 3 contours: n3, n4, n5
-n5 holds 1 contour: n6
-n6 holds 1 contour: n7
Make sure you understand the above before continue reading.
I have the method addContainingBlob, this method is in the blob class. I already checked in another method if the blobToAdd is within the bounds of the blob where i add it. I get a StackOverflowError at this line: b.addContainingBlob(blobToAdd); // <<<<<<.
I'm breaking my head around this for the last hour. Can someone see why it goes wrong?
protected void addContainingBlob(Blob blobToAdd) {
if (containingBlobs.size() == 0) {
containingBlobs.add(blobToAdd);
return;
}
Rectangle r1 = new Rectangle();
r1.setBounds(blobToAdd.minX(), blobToAdd.minY(), blobToAdd.width(), blobToAdd.height());
Rectangle r2 = new Rectangle();
// first check if we already have a containing blob that
// can hold the one we like to add
for (Blob b : containingBlobs) {
r2.setBounds(b.minX(), b.minY(), b.width(), b.height());
if (r2.contains(r1)) {
b.addContainingBlob(blobToAdd); // <<<<<<
return;
}
}
// it can also be that one OR MORE of the containing blobs can fit in the blob we like to add
for (int i = containingBlobs.size()-1; i >= 0; i--) {
Blob b = containingBlobs.get(i);
r2.setBounds(b.minX(), b.minY(), b.width(), b.height());
if (r1.contains(r2)) {
containingBlobs.remove(i);
blobToAdd.addContainingBlob(b);
}
}
containingBlobs.add(blobToAdd);
}
If the code allows a blob to contains itself, the call to blobToAdd.addContainingBlob(b) will lead to infinite recursion because of
if (r2.contains(r1)) {
b.addContainingBlob(blobToAdd); // <<<<<<
return;
}

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

Trying to avoid a Force close after a bullet goes off screen

So I'm just messing around learning to create a Space invaders type game. I can get the bad guys to move, Great!!. Hero moves, Great!! Bullets move, Great!! However I try to remove my bullets once they leave the screen as to not eat up all resources and it force closes on me once it gets rid of the bullet. It goes off the screen. Hits the int of -2 and then we use the remove() and boom. Force Close.
Here is my code. I'm wondering if they access the size() at the same time and just cause a force close because of it.
//I removed everything that doesn't pertane to the bullets.
public class GameScreen{
Bullet bullet = world.bullet;
public GameScreen(Game game) {
super(game);
world = new World();
}
//Draws our bullets.
int bulletLength = bullet.bullets.size();
for(int i = 0; i < bulletLength; i++) {
Placement part = bullet.bullets.get(i);
x = part.x * 32 + 11;
y = part.y * 32;
g.drawPixmap(Assets.bullet, x, y);
}
Class that holds my bullets.
public class Bullet {
public List<Placement> bullets = new ArrayList<Placement>();
public Bullet() {
}
public void shoot(int x, int y){
bullets.add(new Placement(x,y));
}
public void advance(){
int len = bullets.size(); // gets all bullets.
for(int i = 0; i < len; i++) {
bullets.get(i).y --;
if (bullets.get(i).y <= -2){//removes them once they are off the screen.
bullets.remove(i);
}
}
}
This is what I use to keep track of placement.
package com.learning.planecomander;
public class Placement {
public int x, y;
public Placement(int x, int y) {
this.x = x;
this.y = y;
}
}
When going through your list to remove bullets, you can remove bullets from a list but that affects the list immediately instead of after your loop is done. Since you are traversing to the length of the list at the start, you are going off the end of the list since you've removed elements. An example is probably more helpful than that description.
Let's say you have a list with three bullets (which I'll call a, b, c to make the example easier). On a pass through the list, a and c are fine but b needs to be removed.
i = 0;
bullets[0] = a;
bullets[1] = b;
bullets[2] = c;
First loop goes fine, second loop starts like this
i = 1;
bullets[0] = a;
bullets[1] = b;
bullets[2] = c;
We remove b, but the loop keeps going
i = 2;
bullets[0] = a;
bullets[1] = c;
OH CRAP ARRAYINDEXOUTOFBOUNDS! PROGRAM CRASHES!
The way to solve this is to use a temp list to store the bullets that need to be removed, and then once your update loop is finished, make a call to bullets.removeAll(temp)
Doing two passes is a good answer. It makes the loops simpler and easy to understand. If you'd like to do it in one pass though, iterate through the list in reverse order, and when you remove a bullet you can go to the next one and not worry about blasting past the end of the ArrayList.
Alternatively, you can keep your bullets in a linked list, and run through the list with an Iterator, which you can also use to remove items from the list with. Removing from the beginning middle or end of an linked list is always a constant time operation. Whereas removing from the beginning of an ArrayList can be more expensive. If you need random access to the elements in the list, then they can be inefficient. Keep in mind though, if you're only dealing with a handful of objects, then it doesn't really matter.
For bonus points, you might want to put all of your objects in a list, and then have your central loop process them all and have your game objects respond polymorphically to calls like dead?, think, move, draw or whatever you think is appropriate.

Categories

Resources