We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › Lists' objects interaction mess
Pages: 1 2 
Lists' objects interaction mess (Read 966 times)
Lists' objects interaction mess
Dec 28th, 2008, 8:34pm
 
  Hi guys! Sorry for my noob's question. If someone have had similar problem, or have suggestions, or know some
theory in syntax, please help. I couldn't post code because it is very long...

Two util.synchronized.lists contains different objects (Boxes and Circles).

Circles supposed to interact with Boxes (Interaction functions placed inside class Circles).

But when I add Box in runtime all Circles interact with last added one only. Smiley)


Inside class Circles I use Boxes' data to interact  this way:

box.positionX ...


Here what they are:

box = (Box)boxes.get(i);

"boxes" is the : boxes = Collections.synchronizedList(new ArrayList());

"Box" is the class;

"positionX" it is the float wich is situated inside class Box;

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ __ _ _ _ _ __ _ _ _

Another question: Can I get access to synchronized Lists' objects DATA out of other classes, or lists ???


Re: Lists' objects interaction mess
Reply #1 - Dec 29th, 2008, 12:23pm
 
I think we (well, I!) are missing some elements.

First, I wonder why you are using synchronizedLists. Is your sketch multi-threaded?
I have no experience with this function (which I discover). Has it any advantage over a list with built-in synchronization (like Vector)?

Where the boxes variable is instantiated? How do you access it from Circles class? How do you add boxes?

If your code is too long, perhaps you can show only relevant parts (not drawing stuff, only class stuff).
Re: Lists' objects interaction mess
Reply #2 - Dec 29th, 2008, 4:49pm
 
   Maybe I will be wrong but I did that because:
Synchronized Lists are for accessing each object separately, for their separate interaction with others objects and to disable further flowing out (wrong direction) the data (floats) they hold.
   When I tried to put function "synchronize" to  ArrayLists or Vectors or inside classes or to any floats my objects all interacted together Smiley .
   I'l post the questions' code you told to.
Re: Lists' objects interaction mess
Reply #3 - Dec 29th, 2008, 5:29pm
 
Well, synchronization isn't necessary if you don't use threads. Its goal is to avoid concurrent accesses, like a thread reading an object while another thread writes it. For simple programs, just use plain ArrayList.
Re: Lists' objects interaction mess
Reply #4 - Jan 12th, 2009, 8:00am
 
Hello again!

I've changed "Synchronided Lists" to simple ArrayLists and deleted all "synchronize(alist) {}" function and
same problem exists (objects 1 from AList1 work only with the last object2 from AList2.
Please PhiLho, look the code:




// declare

//class Box
Box boxx, tempbox;
Circle circle, tempcircle;
ArrayList boxes, tempboxes;      // the seconds are temporary for runtime adding
ArrayList circles,tempcircles;
static int boxes_quant =0;
static int circles_quant = 0; // Arraylists' sizes
float xxxx, yyyy;

void setup() {
 //strokeWeight(0.5);
 noStroke();
 scale(1);
 size(800, 800);
 fill(230,230,250);

 boxes = new ArrayList();
 tempboxes = new ArrayList();
 circles = new ArrayList();
 tempcircles = new ArrayList();
}
void draw(){

 frameRate(60);

 background(100,100,100);
 // Boxes
 for(int  i = 0; i<boxes.size(); i++)
 {
   pushMatrix();
   for(int  ii = 0; ii<tempboxes.size(); ii++) {
     tempbox = (Box)tempboxes.get(boxes_quant);      //This is temporary list for getting data you need out of it's    
                                                                              // objects  for further using for other lists in runtime adding
     tempbox.xxx = (tempbox.xxx)*0;                         // In my case I need "0" pisition so I discard changes with "*0"
     tempbox.yyy = (tempbox.yyy)*0;                
     xxxx = tempbox.xxx;                                          // Get data out of it
     yyyy = tempbox.yyy;
   }
   boxx = new Box(xxxx,yyyy);                                 // Use data for Arraylist I work with

   boxx = (Box)boxes.get(i);                  
   fill (250,250,250);
   ((Box)boxes.get(i)).display();                                  //class' Box function

   popMatrix();
 }

 // Circles that same

 for(int  i = 0; i<circles.size(); i++)
 {
   pushMatrix();
   for(int  ii = 0; ii<tempcircles.size(); ii++) {
     tempcircle = (Circle)tempcircles.get(circles_quant);                                                        
     tempcircle.xxx = (tempcircle.xxx)*0;              
     tempcircle.yyy = (tempcircle.yyy)*0;                
     xxxx = tempcircle.xxx;                        
     yyyy = tempcircle.yyy;
   }
   circle = new Circle(xxxx,yyyy);                
   circle = (Circle)circles.get(i);                  
   ((Circle)circles.get(i)).display();          
   popMatrix();
 }


}
public class Box {
 float xxx=0;
 float yyy= 0;
 float posX = 0;
 float posY = 0;
 boolean boxover = false;
 boolean boxlocked = false;

 protected float bdifx = 0.0;
 protected float bdify = 0.0;
 Box(float xxx,float yyy) {
   this.xxx=xxx;
   this.yyy=yyy;
   this.posX = posX;
   this.posY = posY;
   this.boxover = boxover;
   this.boxlocked = boxlocked;

   this.bdifx = bdifx;
   this.bdify = bdify;
 }
 protected void display()  {
   this.posX = posX;
   this.posY = posY;
   this.boxover = boxover;
   this.boxlocked = boxlocked;
   this.bdifx =bdifx;
   this.bdify = bdify;
   // Picking
   if ((mouseX > posX-50 && mouseX < posX+50 &&
     mouseY > posY-50 && mouseY < posY+50)){
     boxover = true;
     if(!boxlocked) {  
     }
   }
   else {
     boxover = false;
   }
   pushMatrix();
   fill(255,255,255);
   strokeWeight(0.5);
   fill(255,255,255);
   scale(1);
   translate(posX, posY);
   rectMode(CENTER);
   rect(0, 0, 100, 100);
   popMatrix();
 }
 void mousePressed() {
   if(mouseButton == LEFT){
     if(boxover) {
       boxlocked = true;
       fill(255, 255, 255);
     }
     else {
       boxlocked = false;
     }
     bdifx =  (mouseX-posX);
     bdify =  (mouseY-posY);
   }
 }
 void mouseDragged() {
   if(mouseButton == LEFT){
     if(boxlocked) {

       posX = mouseX-bdifx;
       posY = mouseY-bdify;
     }
   }
 }
 void mouseReleased() {
   boxlocked = false;
 }
}
Re: Lists' objects interaction mess
Reply #5 - Jan 12th, 2009, 8:00am
 
class Circle {
 float xxx = 0;
 float yyy = 0;
 float circleposX = 0;
 float circleposY = 0;
 boolean circleover = false;
 boolean circlelocked = false;
 protected float circlebdifx = 0.0;
 protected float circlebdify = 0.0;
                                                        // new ints for interaction
 boolean spaceoverbottom = false;
 boolean locktobottom = true;


 Circle(float xxx,float yyy) {
   this.xxx=xxx;
   this.yyy=yyy;
   this.circleposX = circleposX;
   this.circleposY = circleposY;
   this.circleover = circleover;
   this.circlelocked = circlelocked;
   this.circlebdifx = circlebdifx;
   this.circlebdify = circlebdify;
   this.spaceoverbottom = spaceoverbottom;
   this.locktobottom = locktobottom;
 }
 protected void display()  {
   this.circleposX = circleposX;
   this.circleposY = circleposY;
   this.circleover = circleover;
   this.circlelocked = circlelocked;
   this.circlebdifx =circlebdifx;
   this.circlebdify = circlebdify;
   this.spaceoverbottom = spaceoverbottom;
   this.locktobottom = locktobottom;
                                                                        // Picking

   if ((mouseX > circleposX-50 && mouseX < circleposX+50 &&
     mouseY > circleposY-50 && mouseY < circleposY+50)){
     circleover = true;
     if(!circlelocked) {  
     }
   }
   else {
     circleover = false;
   }
                                                                  // For interaction  !!! here maybe my PROBLEM
   if(locktobottom) {  
     if (circle.circleposY+100 >= boxx.posY+150 && circle.circleposY-300 <= boxx.posY-50 &&
       circle.circleposX >= boxx.posY-200 && circle.circleposX <= boxx.posX+150)
     {
       spaceoverbottom = true;
     }
     else {
       spaceoverbottom = false;
     }
   }
   pushMatrix();
   fill(255,255,255);
   noStroke();
   scale(1);

   translate(circleposX, circleposY);
   ellipse(0, 0, 100, 100);
   popMatrix();
 }
 void mousePressed() {
   if(mouseButton == LEFT){
     if(circleover) {
       circlelocked = true;
       fill(255, 255, 255);
     }
     else {
       circlelocked = false;
     }
     circlebdifx =  (mouseX-circleposX);
     circlebdify =  (mouseY-circleposY);
   }
 }
 void mouseDragged() {
   if(mouseButton == LEFT){
     if(circlelocked) {
       circleposX = mouseX-circlebdifx;
       circleposY = mouseY-circlebdify;
     }
   }
 }
 void mouseReleased() {
   circlelocked = false;
   if (spaceoverbottom) {
     circleposX = boxx.posX;
     circleposY = boxx.posY+100;  
   }
 }
}
void mousePressed() {
 for(int  i = 0; i<boxes.size(); i++)
 {
   pushMatrix();
   ((Box)boxes.get(i)).mousePressed();
   popMatrix();
 }
 for(int  i = 0; i<circles.size(); i++)
 {
   pushMatrix();
   ((Circle)circles.get(i)).mousePressed();
   popMatrix();
 }
}
void mouseDragged() {
 for(int  i = 0; i<boxes.size(); i++)
 {
   pushMatrix();
   ((Box)boxes.get(i)).mouseDragged();
   popMatrix();
 }
 for(int  i = 0; i<circles.size(); i++)
 {
   pushMatrix();
   ((Circle)circles.get(i)).mouseDragged();
   popMatrix();
 }
}
void mouseReleased() {
 for(int  i = 0; i<boxes.size(); i++)
 {
   pushMatrix();
   ((Box)boxes.get(i)).mouseReleased();
   popMatrix();
 }

 for(int  i = 0; i<circles.size(); i++)
 {
   ((Circle)circles.get(i)).mouseReleased();
 }
}
void keyReleased() {
 if (keyCode == 'B') {
   boxes_quant++;
   pushMatrix();
   boxes.add(new Box(100,100));
   popMatrix();
 }
 if (keyCode == 'C') {
   circles_quant++;
   pushMatrix();
   circles.add( new Circle(100,100));
   popMatrix();
 }
}





You could paste it in sketch to see what I'm talking about, it works...
'B' button to create box - it must be done before circle! Because of NPE...
'C' button to create circle wich must be picked and moved to the bottom of box to connect!

When you'll create 2nd or 3rd box - all circles will connect only to last one and not to firsts...
(I want to connect every object to each other).

Can't get, where am I stuck??? Couldn't find nothing at any forums...

If you have any suggestions or advices, please post it...
Re: Lists' objects interaction mess
Reply #6 - Jan 12th, 2009, 11:36pm
 
  Sorry for the long code... Don't look everything in the code - the problem is when Arraylists' objects fuctions called...

I don't know...
Maybe it is better to create one more class for arraylists' objects interaction or some function inside  void draw?
Re: Lists' objects interaction mess
Reply #7 - Jan 13th, 2009, 12:14am
 
I fear I don't get the final goal. I see the circles to snap on the box, which works well, but I am not sure how other circles must "connect", to what?

I will comment on some portions of code, at least.

It looks like you do too much pushMatrix/popMatrix. They are OK around the scale/translate operations, but they are useless around the method calls. They don't really hurt, except adding "noise" to code reading...

The lines:
Code:
  for(int  i = 0; i<boxes.size(); i++)
{
pushMatrix();
for(int ii = 0; ii<tempboxes.size(); ii++) {
tempbox = (Box)tempboxes.get(boxes_quant); //This is temporary list for getting data you need out of it's
// objects for further using for other lists in runtime adding
tempbox.xxx = (tempbox.xxx)*0; // In my case I need "0" pisition so I discard changes with "*0"
tempbox.yyy = (tempbox.yyy)*0;
xxxx = tempbox.xxx; // Get data out of it
yyyy = tempbox.yyy;
}
boxx = new Box(xxxx,yyyy); // Use data for Arraylist I work with

boxx = (Box)boxes.get(i);
fill (250,250,250);
((Box)boxes.get(i)).display(); //class' Box function

popMatrix();
}

... do nothing! (almost...)
You put nothing in tempboxes, so the loop will never be executed. Beside,  tempbox.xxx = (tempbox.xxx)*0; is the same as tempbox.xxx = 0; and xxxx = tempbox.xxx; is thus always 0 too...
You set boxx to a new object then discard it immediately (next line, new assignment of the variable).
So the loop actually only display the boxes.
Idem for circles.

I don't get why in the constructors you set the variables to themselves, and redo that in the display() routine.

It is late, I will come back later.
I played a bit with the code, it acts the same, but it is shorter... Smiley
Code:
Box boxx;
Circle circle;
ArrayList boxes;
ArrayList circles;

void setup() {
//strokeWeight(0.5);
noStroke();
size(800, 800);
fill(230,230,250);
frameRate(60);
rectMode(CENTER);

boxes = new ArrayList();
circles = new ArrayList();
}

void draw(){
background(100,100,100);
fill (250,250,250);
// Boxes
for(int i = 0; i<boxes.size(); i++)
{
((Box)boxes.get(i)).display(); //class' Box function
}
// Pick latest box
if (boxes.size() > 0)
boxx = (Box) boxes.get(boxes.size() - 1);

// Circles that same
for(int i = 0; i<circles.size(); i++)
{
((Circle)circles.get(i)).display();
}
if (circles.size() > 0)
circle = (Circle) circles.get(circles.size() - 1);
}

void mousePressed() {
for(int i = 0; i<boxes.size(); i++)
{
((Box)boxes.get(i)).mousePressed();
}
for(int i = 0; i<circles.size(); i++)
{
((Circle)circles.get(i)).mousePressed();
}
}
void mouseDragged() {
for(int i = 0; i<boxes.size(); i++)
{
((Box)boxes.get(i)).mouseDragged();
}
for(int i = 0; i<circles.size(); i++)
{
((Circle)circles.get(i)).mouseDragged();
}
}
void mouseReleased() {
for(int i = 0; i<boxes.size(); i++)
{
((Box)boxes.get(i)).mouseReleased();
}
for(int i = 0; i<circles.size(); i++)
{
((Circle)circles.get(i)).mouseReleased();
}
}

void keyReleased() {
if (keyCode == 'B') {
boxes.add(new Box(100,100));
}
if (keyCode == 'C') {
circles.add( new Circle(100,100));
}
}
Re: Lists' objects interaction mess
Reply #8 - Jan 13th, 2009, 12:15am
 
Code:
public class Box {
 float xxx=0;
 float yyy= 0;
 float posX = 0;
 float posY = 0;
 boolean boxover = false;
 boolean boxlocked = false;

 protected float bdifx = 0.0;
 protected float bdify = 0.0;
 Box(float xxx,float yyy) {
   this.xxx=xxx;
   this.yyy=yyy;
 }
 protected void display()  {
   // Picking
   if ((mouseX > posX-50 && mouseX < posX+50 &&
       mouseY > posY-50 && mouseY < posY+50)){
     boxover = true;
     if(!boxlocked) {
     }
   } else {
     boxover = false;
   }
   pushMatrix();
   fill(255,255,255);
   strokeWeight(0.5);
   translate(posX, posY);
   rect(0, 0, 100, 100);
   popMatrix();
 }
 void mousePressed() {
   if(mouseButton == LEFT){
     if(boxover) {
       boxlocked = true;
       fill(255, 128, 128);
     }
     else {
       boxlocked = false;
     }
     bdifx =  (mouseX-posX);
     bdify =  (mouseY-posY);
   }
 }
 void mouseDragged() {
   if(mouseButton == LEFT){
     if(boxlocked) {
       posX = mouseX-bdifx;
       posY = mouseY-bdify;
     }
   }
 }
 void mouseReleased() {
   boxlocked = false;
 }
}

class Circle {
 float xxx = 0;
 float yyy = 0;
 float posX = 0;
 float posY = 0;
 boolean circleover = false;
 boolean circlelocked = false;
 protected float circlebdifx = 0.0;
 protected float circlebdify = 0.0;
           // new ints for interaction
 boolean spaceoverbottom = false;
 boolean locktobottom = true;


 Circle(float xxx,float yyy) {
   this.xxx=xxx;
   this.yyy=yyy;
 }
 protected void display()  {
   // Picking
   if ((mouseX > posX-50 && mouseX < posX+50 &&
       mouseY > posY-50 && mouseY < posY+50)){
     circleover = true;
     if(!circlelocked) {
     }
   } else {
     circleover = false;
   }
   // For interaction  !!! here maybe my PROBLEM
   if(locktobottom && circle != null && boxx != null) {
     if (circle.posY+100 >= boxx.posY+150 && circle.posY-300 <= boxx.posY-50 &&
         circle.posX >= boxx.posY-200 && circle.posX <= boxx.posX+150)
     {
       spaceoverbottom = true;
     } else {
       spaceoverbottom = false;
     }
   }
   pushMatrix();
   fill(255,255,255);
   noStroke();
   translate(posX, posY);
   ellipse(0, 0, 100, 100);
   popMatrix();
 }
 void mousePressed() {
   if(mouseButton == LEFT){
     if(circleover) {
       circlelocked = true;
       fill(255, 128, 128);
     } else {
       circlelocked = false;
     }
     circlebdifx =  (mouseX-posX);
     circlebdify =  (mouseY-posY);
   }
 }
 void mouseDragged() {
   if(mouseButton == LEFT){
     if(circlelocked) {
       posX = mouseX-circlebdifx;
       posY = mouseY-circlebdify;
     }
   }
 }
 void mouseReleased() {
   circlelocked = false;
   if (spaceoverbottom) {
     posX = boxx.posX;
     posY = boxx.posY+100;
   }
 }
}
Re: Lists' objects interaction mess
Reply #9 - Jan 13th, 2009, 4:08am
 
 Hello PhiLho! All night long I was learning the code you've posted - it's very cool and helpful!
 Thank you for Null Pointer Exceptions!!! I couldn't find that anywhere, even at java.sun.com.
 But I didn't understand this code completely
 (I know it's very cool and I'm almost sure that solving of my problem is hidden here Smiley ) :


//  Pick latest box
 if (boxes.size() > 0)
 boxx = (Box) boxes.get(boxes.size() - 1);

But I can't get it now.

Some words about main goal again Smiley
I want to make any circle to snap to any box.
When sketch runs,  you can see 5 boxes and 1 circle are created  - and the circle snaps only to the last created box! This is it!


But working with your code I found 1 thing.
I put the following code in the end of void draw, deleted same code in the class Circle:

// For snapping  !!! here maybe my PROBLEM

for(int  ii = 0; ii<circles.size(); ii++) {
  for(int iii = 0; iii < boxes.size(); iii++)  {
 if (boxes.size() > 0)
boxx = (Box) boxes.get(boxes.size() - 2); // the thing !!!
         
   if(((Circle)circles.get(ii)).locktobottom && circles != null && boxes != null)
   {  
     if (((Circle)circles.get(ii)).circleposY+100 >= ((Box)boxes.get(iii)).posY+150 && ((Circle)circles.get(ii)).circleposY-300 <= ((Box)boxes.get(iii)).posY-50 &&
       ((Circle)circles.get(ii)).circleposX >= ((Box)boxes.get(iii)).posX-200 && ((Circle)circles.get(ii)).circleposX <= ((Box)boxes.get(iii)).posX+150)
     {
       ((Circle)circles.get(ii)).spaceoverbottom = true;
     }
     else {
       ((Circle)circles.get(ii)).spaceoverbottom = false;
     }
}
}
}


  I found that when I move circle to the last created box it snaps to penultimate but nothing more again! That's really interesting problem for me! Smiley
  I can't catch up how to snap circles to any box from severals, more concrete - how and what to write in the code to make all boxes involved to snap with the aid of ArrayList.
Re: Lists' objects interaction mess
Reply #10 - Jan 13th, 2009, 12:44pm
 
The "pick latest box" is actually doing what you did, not doing what must be done to get correct behavior.
I worked a bit more on your script. It still does the same thing! But it is much shorter (it fits in one post!) and structured... I thought I should post it for educational purpose...
It is a good idea to have used classes, but you didn't do it in OOP spirit: you duplicated code, which is BAD in OO! Wink
So I made a common ancestor to both classes, implementing the common code. So the two classes just take care of the differences.
Code:
BoxList boxes;
CircleList circles;
Box boxx; Circle circle;

void setup() {
 noStroke();
 size(800, 800);
 frameRate(60);
 rectMode(CENTER);
 ellipseMode(CENTER);  // Default...

 boxes = new BoxList();
 circles = new CircleList();
}

void draw() {
 background(100, 100, 100);
 // Boxes
 for(int  i = 0; i < boxes.size(); i++)
 {
   boxes.get(i).display();    //class' Box function
 }
 // Pick latest box
 if (boxes.size() > 0)
   boxx = boxes.get(boxes.size() - 1);

 // Circles that same
 for(int  i = 0; i < circles.size(); i++)
 {
   circles.get(i).display();
 }
 if (circles.size() > 0)
   circle = circles.get(circles.size() - 1);
}

void mousePressed() {
 for(int  i = 0; i < boxes.size(); i++)
 {
   boxes.get(i).onMousePressed();
 }
 for(int  i = 0; i < circles.size(); i++)
 {
   circles.get(i).onMousePressed();
 }
}
void mouseDragged() {
 for(int  i = 0; i < boxes.size(); i++)
 {
   boxes.get(i).onMouseDragged();
 }
 for(int  i = 0; i < circles.size(); i++)
 {
   circles.get(i).onMouseDragged();
 }
}
void mouseReleased() {
 for(int  i = 0; i < boxes.size(); i++)
 {
   boxes.get(i).onMouseReleased();
 }
 for(int  i = 0; i < circles.size(); i++)
 {
   circles.get(i).onMouseReleased();
 }
}

void keyReleased() {
 if (keyCode == 'B') {
   boxes.add(new Box(100, 100));
 }
 if (keyCode == 'C') {
   circles.add(new Circle(100, 100));
 }
}

// Abstract so it cannot be instanciated
public abstract class Shape {
 // No need to initialize class fields to default values
 float posX;
 float posY;

 protected float sWidth = 100;
 protected float sHeight = 100;

 private boolean isOver;
 private boolean isLocked;
 private float difx;
 private float dify;

 // Can be changed per shape
 color baseColor = color(255, 255, 255);
 // Should be static (ie. shared by all instances) but cannot here
 color moveColor = color(255, 128, 128);
 // Color of this instance
 color sColor = baseColor;

 Shape(float xxx, float yyy) {
   posX = xxx;
   posY = yyy;
 }

 void display() {
   fill(sColor);
   pushMatrix();
   translate(posX, posY);
   showShape();
   popMatrix();
 }
 abstract protected void showShape();

 // Might be overridden depending on shape
 protected boolean isOver() {
   // Picking
   return mouseX > posX - sWidth/2 && mouseX < posX + sWidth/2 &&
       mouseY > posY - sHeight/2 && mouseY < posY + sHeight/2;
 }

 protected void onMousePressed() {
   if (mouseButton == LEFT) {
     if (isOver()) {
       isLocked = true;
       sColor = moveColor;
       difx = mouseX - posX;
       dify = mouseY - posY;
     } else {
       isLocked = false;
       sColor = baseColor;
     }
   }
 }

 protected void onMouseDragged() {
   if (mouseButton == LEFT && isLocked) {
     posX = mouseX - difx;
     posY = mouseY - dify;
   }
 }

 protected void onMouseReleased() {
   isLocked = false;
   sColor = baseColor;
 }
}

public class Box extends Shape {
 Box(float xxx, float yyy) {
   super(xxx, yyy);
 }

 void showShape() {
   strokeWeight(1);
   rect(0, 0, sWidth, sHeight);
 }
}

class Circle extends Shape {
 boolean spaceoverbottom = false;
 boolean locktobottom = true;

 Circle(float xxx, float yyy) {
   super(xxx, yyy);
 }

 void showShape() {
   noStroke();
   ellipse(0, 0, sWidth, sHeight);
 }

 protected void onMouseReleased() {
   super.onMouseReleased();
   if (locktobottom && circle != null && boxx != null) {
     if (circle.posY+100 >= boxx.posY+150 && circle.posY-300 <= boxx.posY-50 &&
         circle.posX >= boxx.posY-200 && circle.posX <= boxx.posX+150)
     {
       spaceoverbottom = true;
     } else {
       spaceoverbottom = false;
     }
   }
   if (spaceoverbottom) {
     posX = boxx.posX;
     posY = boxx.posY + 100;
   }
 }
}

// Just to avoid casting after get...
// Can be used better!
class BoxList extends ArrayList {
 Box get(int i) {
   return (Box) super.get(i);
 }
}

class CircleList extends ArrayList {
 Circle get(int i) {
   return (Circle) super.get(i);
 }
}

Will come back with the solution to your problem!
Re: Lists' objects interaction mess
Reply #11 - Jan 13th, 2009, 1:30pm
 
A little incremental improvement... These methods & classes replace the previous ones.
Code:
void mousePressed() {
 boxes.onMousePressed();
 circles.onMousePressed();
}
void mouseDragged() {
 boxes.onMouseDragged();
 circles.onMouseDragged();
}
void mouseReleased() {
 boxes.onMouseReleased();
 circles.onMouseReleased();
}

abstract class ShapeList extends ArrayList {
 Shape get(int i) {
   return (Shape) super.get(i);
 }
 void display() {
   for (int i = 0; i < size(); i++) {
     get(i).display();
   }
 }
 void onMousePressed() {
   for (int i = 0; i < size(); i++) {
     get(i).onMousePressed();
   }
 }
 void onMouseDragged() {
   for (int i = 0; i < size(); i++) {
     get(i).onMouseDragged();
   }
 }
 void onMouseReleased() {
   for (int i = 0; i < size(); i++) {
     get(i).onMouseReleased();
   }
 }
}

class BoxList extends ShapeList {
 Box get(int i) {
   return (Box) super.get(i);
 }
}

class CircleList extends ShapeList {
 Circle get(int i) {
   return (Circle) super.get(i);
 }
}

To make shapes snap to others, we will have to use an algorithm similar to collision detection.
Re: Lists' objects interaction mess
Reply #12 - Jan 14th, 2009, 5:05pm
 
OK, here is the latest state of the code, with circles snapping to closest (more or less) box.
Code:
BoxList boxes;
CircleList circles;

void setup() {
 noStroke();
 size(800, 800);
 frameRate(60);
 rectMode(CENTER);
 ellipseMode(CENTER);  // Default...

 boxes = new BoxList();
 circles = new CircleList();
}

void draw() {
 background(222);
 // Boxes
 boxes.display();
 circles.display();
}

void mousePressed() {
 boxes.onMousePressed();
 circles.onMousePressed();
}
void mouseDragged() {
 boxes.onMouseDragged();
 circles.onMouseDragged();
}
void mouseReleased() {
 boxes.onMouseReleased();
 circles.onMouseReleased();
}

void keyReleased() {
 switch (keyCode) {
   case 'B':
     boxes.add(new Box(100, 100));
     break;
   case 'C':
     circles.add(new Circle(100, 100));
     break;
   case 'D': // Debug...
     for (int i = 0; i < boxes.size(); i++) {
       Box box = (Box) boxes.get(i);
       println("B" + i + ": " + box.posX + " " + box.posY);
     }
     for (int i = 0; i < circles.size(); i++) {
       Circle circle = (Circle) circles.get(i);
       println("C" + i + ": " + circle.posX + " " + circle.posY);
     }
     break;
 }
}

// Abstract so it cannot be instanciated
public abstract class Shape {
 // No need to initialize class fields to default values
 float posX;
 float posY;

 protected float sWidth;
 protected float sHeight;

 private boolean isOver;
 private boolean isLocked;
 private float difx;
 private float dify;

 // Can be changed per shape
 color baseColor = color(255, 255, 255);
 // Should be static (ie. shared by all instances) but cannot here
 color moveColor = color(255, 128, 128);
 // Color of this instance
 color sColor = baseColor;

 Shape(float w, float h) {
   posX = mouseX;
   posY = mouseY;
   sWidth = w;
   sHeight = h;
 }

 void display() {
   fill(sColor);
   pushMatrix();
   translate(posX, posY);
   showShape();
   popMatrix();
 }
 abstract protected void showShape();

 // Might be overridden depending on shape
 protected boolean isOver() {
   // Picking
   return mouseX > posX - sWidth/2 && mouseX < posX + sWidth/2 &&
       mouseY > posY - sHeight/2 && mouseY < posY + sHeight/2;
 }
 public boolean isLocked() {
   return isLocked;
 }

 protected void onMousePressed() {
   if (mouseButton == LEFT) {
     if (isOver()) {
       isLocked = true;
       sColor = moveColor;
       difx = mouseX - posX;
       dify = mouseY - posY;
     } else {
       isLocked = false;
       sColor = baseColor;
     }
   }
 }

 protected void onMouseDragged() {
   if (mouseButton == LEFT && isLocked) {
     posX = mouseX - difx;
     posY = mouseY - dify;
   }
 }

 protected void onMouseReleased() {
   isLocked = false;
   sColor = baseColor;
 }
}

public class Box extends Shape {
 Box(float w, float h) {
   super(w, h);
 }

 void showShape() {
   strokeWeight(2);
   stroke(128);
   rect(0, 0, sWidth, sHeight);
 }
}

class Circle extends Shape {
 boolean locked;

 Circle(float w, float h) {
   super(w, h);
 }

 void showShape() {
   strokeWeight(1);
   stroke(128);
   ellipse(0, 0, sWidth, sHeight);
 }

 protected void onMouseReleased() {
   super.onMouseReleased();
   for (int i = 0; i < boxes.size(); i++) {
     Box box = (Box) boxes.get(i);
     if (posX >= box.posX - 2 * box.sWidth &&
         posX <= box.posX + 2 * box.sWidth &&
         posY >= box.posY + box.sHeight / 2 &&
         posY <= box.posY + box.sHeight * 2) {
       locked = true;
       // Reposition the circle
       posX = box.posX;
       posY = box.posY + box.sHeight;
       break;
      }
   }
 }
}

abstract class ShapeList extends ArrayList {
 Shape get(int i) {
   return (Shape) super.get(i);
 }
 void display() {
   for (int i = 0; i < size(); i++) {
     get(i).display();
   }
 }
 void onMousePressed() {
   for (int i = 0; i < size(); i++) {
     get(i).onMousePressed();
   }
 }
 void onMouseDragged() {
   for (int i = 0; i < size(); i++) {
     get(i).onMouseDragged();
     if (keyPressed && key == CODED && keyCode == SHIFT && get(i).isLocked()) {
       // Shift drag, we drag only the first shape found under the cursor
       // Helps when two circles snap to the same location...
       break;
     }
   }
 }
 void onMouseReleased() {
   for (int i = 0; i < size(); i++) {
     get(i).onMouseReleased();
   }
 }
}

class BoxList extends ShapeList {
 Box get(int i) {
   return (Box) super.get(i);
 }
}

class CircleList extends ShapeList {
 Circle get(int i) {
   return (Circle) super.get(i);
 }
}

Also changed some little things, like shapes appearing at cursor location.
Re: Lists' objects interaction mess
Reply #13 - Jan 15th, 2009, 7:23am
 
  Very strong code! PhiLho thank you very much! I'll try to understand all things you did. Also thanks for helping and advicing!
Re: Lists' objects interaction mess
Reply #14 - Jan 17th, 2009, 7:30am
 
  Hello PhiLho!   I worked with your latest code and found it faster and  smoother than in case without ancestor.
What about your words : " So I made a common ancestor to both classes, implementing the common code. So the two classes just take care of the differences", - Could you show the strings where is it implemented, or it touchs ancestor's and child's architecture in java?
Pages: 1 2