This site requires JavaScript, please enable it in your browser!
Greenfoot back
CodingCowgirl
CodingCowgirl wrote ...

2021/11/16

Are checkboxes possible in Greenfoot? And how?

CodingCowgirl CodingCowgirl

2021/11/16

#
So, currently I’m working on a quiz. I wanted to ask if it’s possible to add checkboxes (like in JavaScript) in Greenfoot. If ‘yes’ how? You can image a question like this: “ What doesn’t go on pizza? a) Cheese b) Tomato sauce c) Pineapple d) Dough “
RcCookie RcCookie

2021/11/16

#
You can, but you have to code them yourself. Greenfoot.mouseClicked(Object) may be helpful for that. It's not to hard, unless you want some animations. Alternatively you can use this stuff I made some time ago, it doesn't have a checkbox but at least a toggleable switch.
CodingCowgirl CodingCowgirl

2021/11/16

#
@RcCookie So, basically I can do Greenfoot.mouseClicked(Button_A), right? How do I signal Greenfoot that answer C would be wrong and how can I add the right and wrong answers. So, I can give an analyze at the resullt.
RcCookie RcCookie

2021/11/16

#
The checkbox itself only checks whether it is on or not. Here is an example implementation of a simple checkbox:
import greenfoot.Actor;
import greenfoot.Color;
import greenfoot.Greenfoot;
import greenfoot.GreenfootImage;

public class Checkbox extends Actor {

    public static final GreenfootImage ON_IMAGE, OFF_IMAGE;
    static {
        ON_IMAGE = new GreenfootImage(20, 20);
        ON_IMAGE.setColor(Color.LIGHT_GRAY);
        ON_IMAGE.fill();
        ON_IMAGE.setColor(Color.DARK_GRAY);
        ON_IMAGE.drawRect(0, 0, ON_IMAGE.getWidth() - 1, ON_IMAGE.getHeight() - 1);
        ON_IMAGE.drawRect(1, 1, ON_IMAGE.getWidth() - 3, ON_IMAGE.getHeight() - 3);

        OFF_IMAGE = new GreenfootImage(ON_IMAGE);
        OFF_IMAGE.setColor(Color.GREEN);
        OFF_IMAGE.fillRect(3, 3, OFF_IMAGE.getWidth() - 7, OFF_IMAGE.getHeight() - 7);

        // You can also use images:

//        ON_IMAGE = new GreenfootImage("images/checkbox_on.png");
//        OFF_IMAGE = new GreenfootImage("images/checkbox_off.png");
    }

    private boolean on = false;
    private final boolean onlyOneOne;

    public Checkbox(boolean on, boolean onlyOneOn) {
        this.onlyOneOne = onlyOneOn;

        if(on) toggle();
        else updateImage();
    }

    public boolean isOn() {
        return on;
    }

    public void setOn(boolean on) {
        if(this.on == on) return;
        this.on = on;
        updateImage();

        if(on && onlyOneOne) {
            for(Checkbox b : getWorld().getObjects(Checkbox.class))
                b.setOn(false);
        }
    }

    public void toggle() {
        setOn(!on);
    }

    private void updateImage() {
        setImage(on ? ON_IMAGE : OFF_IMAGE);
    }

    @Override
    public void act() {
        if(Greenfoot.mouseClicked(this))
            toggle();
    }
}
It's untested.
danpost danpost

2021/11/16

#
There are examples of check boxes in multiple demo scenarios. My Bar Subclasses scenario has a standard switch (or checkbox). My Dialog Support Class scenario also has a check box element included within it.
danpost danpost

2021/11/16

#
My version of a simple check box is as follows. (1) Create a subclass of Actor for check box objects:
import greenfoot.*;

public class Checkbox extends Actor
{
    private boolean checked = false;
    private int size = 24;
    private Color frameColor = Color.BLACK;
    private Color onColor = Color.GREEN;
    private Color offColor = Color.WHITE;
    private boolean clickable = false;
    
    public Checkbox()
    {
        updateImage();
    }
    
    private void updateImage()
    {
        GreenfootImage img = new GreenfootImage(size, size);
        img.setColor(frameColor);
        img.fill();
        img.setColor(checked ? onColor : offColor);
        img.fillRect(3, 3, size-6, size-6);
        setImage(img);
    }
    
    public void setSize(int imgSize)
    {
        if (imgSize < 14) return;
        size = imgSize;
        updateImage();
    }
    
    public void setFrameColor(Color color)
    {
        if (color == null) return;
        frameColor = color;
        updateImage();
    }
    
    public void setOnColor(Color color)
    {
        if (color == null) return;
        onColor = color;
        updateImage();
    }
    
    public void setOffColor(Color color)
    {
        if (color == null) return;
        offColor = color;
        updateImage();
    }
    
    public void setClickable(boolean clicks)
    {
        clickable = clicks;
    }
    
    public void setState(boolean state)
    {
        checked = state;
        updateImage();
    }
    
    public void toggleState()
    {
        checked = !checked;
        updateImage();
    }
    
    public boolean isChecked()
    {
        return checked;
    }
    
    public void act()
    {
        if (clickable && Greenfoot.mouseClicked(this)) toggleState();
    }
}
(2) Have your world create the checkbox:
private Checkbox checkboxActor;

public MyWorld()
{
    super(600, 400, 1);
    checkboxActor = new Checkbox();
    checkboxActor.setSize(28);
    checkbox.setClickable(true);
    addObject(checkbox, 120, 50);
    setText("State:", 50, 50);
    ...
}
(3) If required to immediately do something upon a change in the state of the checkbox, set clickable to false and add the following to world:
public void act()
{
    if (Greenfoot.mouseClicked(checkboxActor))
    {
        checkboxActor.toggleState();
        // do whatever action are required
    }
    ...
}
danpost danpost

2021/11/16

#
If you have multiple check boxes where only one is to be checked at a time, put group in an array:
Checkbox[] checkboxGroup = new Checkbox[3];

public MyWorld()
{
    super(600, 400, 1);
    for (int i=0; i<checkboxGroup.length; i++)
    {
        checkboxGroup[i] = new Checkbox();
        addObject(checkboxGroup[i], 120, 50+50*i);
        ...
    }
    
    public void act()
    {
        for (int i=0; i<checkboxGroup.length; i++)
        {
            if (checkboxGroup[i].getState() == false && Greenfoot.mouseClicked(checkboxGroup[i]))
            {
                for (int j=0; j<checkboxGroup.length; j++) checkboxGroup[j].setState(false);
                checkboxGroup[i].toggleState();
                // do any other required action upon check in which check box is checked
                // (a switch statement may be appropriate here based on the int index i)
            }
        }
    }
    ...
}
You need to login to post a reply.