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

2015/4/27

Creating a Button in inherited class

opna opna

2015/4/27

#
How would I create a new generic clickable button titled "load" or merge? Would I have to do this in a subclass using super or in the world class?
import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.awt.Color; // gives the ability to name colors for images.

/**
 * A "generic" clickable button. Note that you cannot create any objects of this type. Instead,
 *   you should inherit this class into a new subclass. In the new subclass, make sure *NOT* to
 *   have an act method, and make sure you *DO* have a doButtonWork method (matching the header
 *   below).
 *   
 * *** DO *NOT* MODIFY THIS CODE IN ANY WAY!!!! ***
 * 
 * @author Mark Keena
 * @version 4/23/15
 */
public abstract class GenericButton extends Actor
{
    // constants 
    /** how long (in number of act calls) a button should stay clicked */
    public static final int CLICK_DELAY=10; 
    /** one more than CLICK_DELAY indicates button is unclicked*/
    public static final int UNCLICKED=CLICK_DELAY+1; 
    
    // instance variables
    private String label;                // actual text found in the button. 
    
    private GreenfootImage unclickedImg; // image to use when buttin is not clicked, 
    private GreenfootImage clickedImg;   // image to use when but has been clicked recently.
    
    private int clickedCountDown;        // keeps track of how long to keep button appearing clicked
    
    /**
     * GenericButton - builds a button with a label of the given text. Note that
     *    you can NOT construct a GenericButton because the class is abstract;
     *    classes that inherit this one can call this constructor using super()
     *    from their own constructor(s)
     *    
     *    @param text the label to utilize in the resulting button.
     */
    public GenericButton(String text)
    {
        clickedCountDown=UNCLICKED; // set the button countdown as unclicked 
    
        label=new String(text);     // store text to place into button
    
        buildImages();              // build images for use with this button
    
        setImage(unclickedImg);     // default image is the nlicked version.
    }
    
    /*
     * buildImages - (private) builds the two images needed while the button is act-ing. 
     *   one for an unclicked button, the other for when the button has been clicked.
     */
    private void buildImages()
    {
       // the colors for the button. The unlicked version has gray background with white text,
       Color bgColor = Color.gray;
       Color fgColor = Color.white;
       
       // build the unclicked image
       unclickedImg = buildImage(bgColor, fgColor);
       
       // build the clicked version of the button image. Note that it has the reversed color scheme,
       clickedImg = buildImage(fgColor, bgColor);
    }
    
    /*
     * buldImage - (private) builds a single image with specified colors:
     *    bg - the button background color
     *    fg - the button foreground color
     */
    private GreenfootImage buildImage(Color bg, Color fg)
    {
        // build an image to hold the text label
        GreenfootImage txtImg = new GreenfootImage(label, 24, fg, bg);
        
        //build an image big enough to hold the text and the sourrounding border for the button itself
        GreenfootImage buttonImg = new GreenfootImage(txtImg.getWidth()+10, txtImg.getHeight()+10);
        
        // fill the buttons's image with background color
        buttonImg.setColor(bg);
        buttonImg.fill();
        
        // add the text to the button image
        buttonImg.drawImage(txtImg, 5,5);
        
        // draw a rectangle around the text
        buttonImg.setColor(fg);
        buttonImg.drawRect(1,1,buttonImg.getWidth()-3, buttonImg.getHeight()-3);
        
        // return "finished product" image.
        return buttonImg;
    }
    
    /**
     * Act - when the mouse is clicked on this button, makes the button image change and
     *    calls doButtonWork(), which is where the "action" for the button should be
     */
    public void act() 
    {
        // if the button has been clicked for long enough, reset it
        if (clickedCountDown<=0)
        {
            setImage(unclickedImg);      // reset means changing image to unclicked version and ... 
            clickedCountDown=UNCLICKED;  // ...storing that it is now UNCLICKE
        }
        // if button was just clicked ...
        else if (clickedCountDown==CLICK_DELAY)
        {
            doButtonWork();     // do work for the button and ...
            clickedCountDown--; // start countdown to resetting button
        }
        // if button was recently clicked, but not yet ready to be reset ...
        else if (clickedCountDown<CLICK_DELAY)
        {
            clickedCountDown--; // continue countdown to resetting btton
        }
        
        // if someone clicks this button ...
        if (Greenfoot.mouseClicked(this))
        {
            clickedCountDown=CLICK_DELAY; // make sure next pass starts doing the work and ...
            setImage(clickedImg);         // rememebr button has been clicked,
        }
    } 
    
    /**
     * setLabel - changes the label text. Also redraws button and moves it to keep it left aligned.
     * 
     * @param newText - the new text to be plaed in the button.
     */
    public void setLabel(String newText)
    {
        label = new String(newText);  // store the new text.
        
        // need the old width to figure out how far to move the button for left alignment
        int oldWidth = unclickedImg.getWidth();
        
        buildImages(); // update bith images for button
        
        // figure out if changing text in middle of button click...
        boolean clicked=false;        
        if (clickedCountDown<=CLICK_DELAY)
            clicked=true;
        
        // if the button was clicked ... 
        if (clicked)
            setImage(clickedImg);   // ... use clicked image version  
        else // button is not in "clicked state, so ...
            setImage(unclickedImg); // ... use unclicked version of button
        
        
        // calculate difference in size between old and new button images ...
        int newWidth = unclickedImg.getWidth(); 
        int deltaWidth = newWidth-oldWidth;
        
        // move the newly imaged button according to its new size. 
        setLocation(getX()+deltaWidth/2, getY());
    }
    
    /**
     * getLabel - returns what text is currently in the button
     *   @return a String containing the button's text.
     */
    public String getLabel()
    {
        return label;
    }
    
    /**
     * doButtonWork - code to do when this button is pressed. YOU MUST OVERRIDE THIS METHOD IN
     *   YOUR SUBCLASS!
     */
    public void doButtonWork()
    {
        System.out.println("You clicked a generic button. Perhaps you forgot an overload?");
    }
}
Super_Hippo Super_Hippo

2015/4/27

#
You would create a subclass of this class. I think it will look like this:
public class LoadButton extends GenericButton
{
    public LoadButton(String text)
    {
        super(text);
    }
    
    public void doButtonWork()
    {
        //whatever should happen when you press the button
    }
}
Make sure that you uncomment the act method.
You need to login to post a reply.