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 & HelpOther Libraries › G4P GUI inside class
Pages: 1 2 
G4P GUI inside class (Read 2313 times)
G4P GUI inside class
May 1st, 2009, 8:28am
 
  Hello guys! Tell me, please, how should I use G4P components to put them inside any own class. Is it possible?
Re: G4P GUI inside class
Reply #1 - May 4th, 2009, 6:43am
 
Not all your readers will be aware that G4P http://gui4processing.lagers.org.uk/ is in fact a 2D GUI library similar to controlP5 and InterFacia because it has only been available for a few weeks.

This is probably why you you are not getting any response.

Even knowing that, your question is still not clear because you need to explain what you mean by
Quote:
put them inside any own class




Re: G4P GUI inside class
Reply #2 - May 4th, 2009, 2:26pm
 
  Excuse me for not clear expressions... I mean, for example I put 3 shapes (or models)  on the screen, each shape is a class' object (circle, box and triangle), so I have 3 classes...  Also I want to change the properties of each class' object separately with the help of GUI - I mean I have 2 or 10 circles and I want same menu with slider for each of them to change their own radius separately of other circles.
And also if I don't have any circle on the screen - I don't need it's menu to be visible for the moment. For that I need, I think, to put the GUIs inside classes of shapes, that each object of the class had it's own floats and sliders connected among themselves inside only.
  I'm still newbe...  Huh
Re: G4P GUI inside class
Reply #3 - May 6th, 2009, 12:39am
 
Thats a lot clearer explanation and is a really interesting problem because you basically want a mini GUI controller for each object.

I have been thinking about the problem and I believe it should be easy to do with G4P and as soon as I get a chance I will provide a simple example program  for you to follow but I am really busy at work at the moment so it might be a couple of days so watch this space.
Smiley
Re: G4P GUI inside class
Reply #4 - May 6th, 2009, 4:34am
 
If I understood correctly, you want to have only one set of controls. When clicking/selecting an object, you want these controls to reflect the current parameters and allow to change them. Right?
(I first thought each object to have its controls embedded...)
Re: G4P GUI inside class
Reply #5 - May 6th, 2009, 10:31am
 
  Yes it is. I thought it will be possible, if there are a lot of one-type objects and they present same class. And also one-type has own contol set wich differs from another type wich holds another set.
Re: G4P GUI inside class
Reply #6 - May 6th, 2009, 10:36am
 
 Write, please, if this is a bad idea.
Re: G4P GUI inside class
Reply #7 - May 7th, 2009, 6:45am
 
Your reply to PhiLho is even clearer still and I still plan to do the demo but I am still really busy at work (13 yesterday) so it will probably be the weekend before I get round to it.
Smiley
Re: G4P GUI inside class
Reply #8 - May 7th, 2009, 7:03am
 
  I see, I will look forward  Cheesy .
Re: G4P GUI inside class
Reply #9 - May 9th, 2009, 9:18am
 
Sorry its taken a while but here is a screen shot from my sketch. Smiley
.
...

The blue panel has 2 sliders to change the width and the height of the pinkish rectangle. To close the panel click on the panel's tab bar and it will disappear. Once the panel is closed you can click on one of the other shapes and a controller panel will appear depending on the type of shape. The circles have a single slider to control the radius.

There are 5 main classes
Shape
Circle (extends Shape)
Rectangle (extends Shape)

I recommend that any you use the Shape class as the parent for any other shape classes you create.

Each shape has its own editor class in this example we have 2 :-
RectangleEditor
CircleEditor

The code has been written in such away that for each shape type there is just one editor object that works with all shapes of that type.

The code will be in the next post.


Re: G4P GUI inside class
Reply #10 - May 9th, 2009, 9:26am
 
The code is split over this and the next post (post size is restricted). Sorry about that but I have tried to make the code clear and meaningful rather than concise.
Code Part 1
Code:

import guicomponents.*;

final int MIN_WIDTH = 50;
final int MAX_WIDTH = 200;
final int MIN_HEIGHT = 50;
final int MAX_HEIGHT = 180;
final int MIN_RADIUS = 20;
final int MAX_RADIUS = 100;

Shape shapeToEdit = null;
boolean mouseEnabled = true;

CircleEditor circleEditor = null;
RectangleEditor rectangleEditor = null;

Shape[] shapes = new Shape[100];
int nbrShapes = 5;

void setup(){
size(500,400);
// MUST do this before creating any G4P components
registerMouseEvent(this);
// MUST create editors before we create shapes
circleEditor = new CircleEditor(this);
rectangleEditor = new RectangleEditor(this);
// Make some random shapes
makeRandomShapes();
}

public void makeRandomShapes(){
int x,y,w,h,r,c;
for(int i=0; i<nbrShapes; i++){
x = (int) random(100,width-100);
y = (int) random(100,height-100);
w = MIN_WIDTH + (int) random(MAX_WIDTH-MIN_WIDTH);
h = MIN_HEIGHT + (int) random(MAX_HEIGHT-MIN_HEIGHT);
r = MIN_RADIUS + (int) random(MAX_RADIUS-MIN_RADIUS);
c = color(128+random(128), 128+random(128), 128+random(128));
if(random(1) < 0.5)
shapes[i] = new Rectangle(this,x,y,w,h,c);
else
shapes[i] = new Circle(this,x,y,r,c);
}
}

/*
* DO NOT USE the methods
* mouseClicked(), mousePressed(), mouseDragged(), mouseReleased()
* these methods remove the actual mouse event from the event queue
* which means it is no longer available to G4P methods.
* Instead use this method.
*/
void mouseEvent(MouseEvent event){
// If a shape has been selected
if(shapeToEdit != null) return;
switch(event.getID()){
case MouseEvent.MOUSE_PRESSED:
break;
case MouseEvent.MOUSE_CLICKED:
handleMouseClick();
break;
case MouseEvent.MOUSE_RELEASED:
break;
case MouseEvent.MOUSE_DRAGGED:
break;
}
}

/*
* Loop through all the shapes in reverse draw order and see
* whether we have clicked on a shape. If we have then open
* the correct editor
*/
public void handleMouseClick(){
String shapeType = null;
Shape shpaeClicked;
for(int i=nbrShapes-1; i>=0; i--){
if(shapes[i].isInside(mouseX, mouseY)){
shapeToEdit = shapes[i];
shapeType = shapeToEdit.getClass().getSimpleName();
break;
}
}
if(shapeType != null){
if(shapeType.equalsIgnoreCase("Circle")){
circleEditor.initForCircle((Circle) shapeToEdit);
}
else if(shapeType.equalsIgnoreCase("Rectangle")){
rectangleEditor.initForRectangle((Rectangle) shapeToEdit);
}
}
}

/*
* You must surround your drawing commands with pushStyle()
* and popStyle() with this version of G4P.
* This will not be necessary with the next release V1.3
*/
public void draw(){
background(240);
pushStyle();
for(int i=0; i<nbrShapes; i++){
shapes[i].display();
}
popStyle();
}


/**
* Parent class for all your different types of shape
*/
abstract class Shape {
protected PApplet app;
// Centre of the shape
public int cx;
public int cy;
// Fill colour
public int fillColor;

// Override this method in child classes
// returns true if the position x,y is
// inside the shape
abstract public boolean isInside(int x, int y);

// Override this method in child classes
// displays the shape - should be called from draw() method
abstract public void display();
}
/**
* The rectangle class
*/
class Rectangle extends Shape {
public int width;
public int height;

Rectangle(PApplet theApplet, int x, int y, int w, int h, int col){
app = theApplet;
cx = x;
cy = y;
width = w;
height = h;
fillColor = col;
}

public boolean isInside(int x, int y){
return (abs(cx-x) <= width/2) && (abs(cy-y) < height/2);
}
public void display(){
rectMode(CENTER);
fill(fillColor);
rect(cx,cy,width,height);
}
}

/**
* The circle claas
*/
class Circle extends Shape {
public int radius;

Circle(PApplet theApplet, int x, int y, int r, int col){
app = theApplet;
cx = x;
cy = y;
radius = r;
fillColor = col;
}
public boolean isInside(int x, int y){
return ( (int)dist(cx,cy,x,y) <= radius);
}
public void display(){
ellipseMode(CENTER);
fill(fillColor);
ellipse(cx,cy,2*radius,2*radius);
}
}



Re: G4P GUI inside class
Reply #11 - May 9th, 2009, 9:27am
 
Code Part 2 : The editor classes.

Code:

public class RectangleEditor {
PApplet app;
GPanel pnlEditor;
GLabel lblWidth, lblHeight;
GHorzSlider sdrWidth, sdrHeight;

// Create the circle editor (only one allowed)
public RectangleEditor(PApplet theApplet){
app = theApplet;
if(rectangleEditor == null){
// Create the panel
pnlEditor = new GPanel(app, "Rectangle", 20,72, 180,26);
pnlEditor.setVisible(false);
pnlEditor.setCollapsed(false);
pnlEditor.setOpaque(true);
pnlEditor.addEventHandler(this, "hidePanel");
pnlEditor.setBorder(1);
pnlEditor.setAlpha(160);
// Create the controls for editing circles
lblWidth = new GLabel(app,"Width",2,2,50,10);
sdrWidth = new GHorzSlider(app,50,3,120,10);
sdrWidth.setLimits(MIN_WIDTH, MIN_WIDTH, MAX_WIDTH);
sdrWidth.setBorder(1);
sdrWidth.addEventHandler(this, "handleSliders");
lblHeight = new GLabel(app,"Height",2,12,50,10);
sdrHeight = new GHorzSlider(app,50,13,120,10);
sdrHeight.setLimits(MIN_WIDTH, MIN_WIDTH, MAX_WIDTH);
sdrHeight.setBorder(1);
sdrHeight.addEventHandler(this, "handleSliders");
// Add the controls to the panel
pnlEditor.add(lblWidth);
pnlEditor.add(sdrWidth);
pnlEditor.add(lblHeight);
pnlEditor.add(sdrHeight);
}
}

// Initialise the editor based on the selected shapes properties
public void initForRectangle(Rectangle r){
mouseEnabled = false;
sdrWidth.setValue(r.width, true);
sdrHeight.setValue(r.height, true);
pnlEditor.setXY(r.cx, r.cy);
pnlEditor.setCollapsed(false);
pnlEditor.setVisible(true);
}

// The user clicks on the title bar when finished editing
public void hidePanel(GPanel panel){
pnlEditor.setVisible(false);
pnlEditor.setFocus(false);
sdrWidth.setFocus(false);
sdrWidth.setFocus(false);
shapeToEdit = null;
mouseEnabled = true;
}

// Handle the slider control value changes
public void handleSliders(GSlider slider){
if(slider == sdrWidth)
((Rectangle)shapeToEdit).width = sdrWidth.getValue();
if(slider == sdrHeight)
((Rectangle)shapeToEdit).height = sdrHeight.getValue();
}
}

public class CircleEditor {
PApplet app;
GPanel pnlEditor;
GLabel lblRadius;
GHorzSlider sdrRadius;

// Create the circle editor (only one allowed)
public CircleEditor(PApplet theApplet){
app = theApplet;
if(circleEditor == null){
// Create the panel
pnlEditor = new GPanel(app, "Circle", 20,60, 180,16);
pnlEditor.setVisible(false);
pnlEditor.setCollapsed(false);
pnlEditor.setOpaque(true);
pnlEditor.addEventHandler(this, "hidePanel");
pnlEditor.setBorder(1);
pnlEditor.setAlpha(160);
// Create the controls for editing circles
lblRadius = new GLabel(app,"Radius",2,2,50,10);
sdrRadius = new GHorzSlider(app,50,3,120,10);
sdrRadius.setLimits(MIN_RADIUS, MIN_RADIUS, MAX_RADIUS);
sdrRadius.setBorder(1);
sdrRadius.addEventHandler(this, "handleSliders");
// Add the controls to the panel
pnlEditor.add(lblRadius);
pnlEditor.add(sdrRadius);
}
}

// Initialise the editor based on the selected shapes properties
public void initForCircle(Circle c){
mouseEnabled = false;
sdrRadius.setValue(c.radius, true);
pnlEditor.setXY(c.cx, c.cy);
pnlEditor.setCollapsed(false);
pnlEditor.setVisible(true);
}

// The user clicks on the title bar when finished editing
public void hidePanel(GPanel panel){
pnlEditor.setVisible(false);
pnlEditor.setFocus(false);
sdrRadius.setFocus(false);
shapeToEdit = null;
mouseEnabled = true;
}

// Handle the slider control value changes
public void handleSliders(GSlider slider){
if(shapeToEdit != null && slider == sdrRadius){
((Circle)shapeToEdit).radius = sdrRadius.getValue();
}
}
}
Re: G4P GUI inside class
Reply #12 - May 10th, 2009, 12:03pm
 
  Wow! Thank you! I'm trying to understand everything.
Re: G4P GUI inside class
Reply #13 - May 11th, 2009, 9:12pm
 
       I understand everything and it works very well, I like this GUI.  Smiley
  But on my way I got a barrier:
   I made  GTextField Inside RectangleEditor class like in example  and put some floats and strings inside handler "handleTextFieldEvents":

                  ...

 public void handleTextFieldEvents(GTextField tfield){
   if(tfield == txf1){
     
     switch (txf1.getEventType()){
     case GTextField.CHANGED:

       print("CHANGED");

       if( txf1!=null || txf1!="") { // this conditions didn't help

         string1 = txf1.getText();  //works
         testFloatX = new Float(string1); //works
         ((Rectangle)shapeToEdit).positionX = testFloatX; //works


         string2 = Float.toString(((Rectangle)shapeToEdit).positionX); //works
         ((Rectangle)shapeToEdit).teststring = string2; //works
       }
       else {
         string1 = "0"; //this didn't help too
       }
       break;     }
                     
                  ...

  Everything obeys fine... But when I type a letter or use backspace to delete digits in GTextField
  Console says : "Disabling handleTextFieldEvents due to an unknown error".

  I see, the problem is connected with "null reference" of the string (using backspace)
  and also convertation string-float there and back again (because of letters).


  How to correct or to bypass this?
  Now I try to disable letters printing with help "keyEvent(KeyEvent e)"
  (G4P native - I saw it in googlecode) - while it is unsuccessfully...
  Maybe you know some tips?

Deviating from the main question I want to add that the numbers wich were entered
in GTextField of class RectangleEditor remain valid for the next opened GUIs of other rectangles. I will join classes Rectangle and RectangleEditor. I'm not sure is this well, but we'll see what we got.    
Re: G4P GUI inside class
Reply #14 - May 12th, 2009, 7:34am
 
I assume that you want to get a value from the textfield and if it is a number change the position of the rectangle!

In the if statement
Code:
txf1!="" 


will not work properly because you are comparing a GTextField with a String Huh.
You are obviously trying to see if the textfield not null AND is not empty. This is the code you need
Code:
if( txf1!=null && !txf1.getText().equals("")) { 



To get a float from a string we can use the following statement
Code:
testFloatX = Float.parseFloat(txf1.getText()); 


If the string is empty or has letters it cannot be converted to a float and an exception is thrown, and it is this exception that is causing the message "Disabling handleTextFieldEvents due to an unknown error"

The solution is to catch the exception and I believe the code below will do what you want. Smiley

Code:

public void handleTextFieldEvents(GTextField tfield){
  if(tfield == txf1){
   
    switch (txf1.getEventType()){
    case GTextField.CHANGED:

      print("CHANGED");

      if( txf1!=null && !txf1.getText().equals("")) {
        try{
           // See if the text field holds a number
           testFloatX = Float.parseFloat(txf1.getText());
           // if it failed then goto catch clause below
           // if no problem then move the rectangle.
           ((Rectangle)shapeToEdit).positionX = testFloatX;
        }
        catch(Exception e){
           // We get here if the text in the txf1
           // cannot be converted to a number
        }
        break;    
    } // end of switch statement
                   
      ...
Pages: 1 2