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

2016/3/13

Having trouble updating Wolrd when changing slider.

RedPanda98 RedPanda98

2016/3/13

#
My program is to simulate gas particles. When I move the number of particle slider to add another particle it does not add it into the world unless I press the reset button. Can anyone help me on this please? Here's the code for the particle. MyWorld Class
 public void populate(){ //Generates particles in the world.
        ball bl;
        for(int i=0;i<(NumberOfParticleSlider.particle);i++) //Adds
          addObject(new ball(),10+Greenfoot.getRandomNumber(1000-1),10+Greenfoot.getRandomNumber(900-1));
    }
And the slider class.
import greenfoot.*;

public class TemperatureSlider extends Actor
{
    private GreenfootImage background, foreground; //The background and foreground images.
    
    private int height, fgWidth = 9, fgHeight = 10; //The height and width of the foreground
    
    private int maxValue, actualWidth, valueWidth, valueLabelWidth, padding, valueX, valueRight; //The maximum value, width in pixels, width of the selectable area, width of the value label,
                                                                                                 //the padding either side of the selectable area, the x-coordinate of the selectable area
                                                                                                 //and the x-coordinate of the right-hand side of the selectable area
    
    private int majorSections, minorSections; //The number of major and minor sections.
    
    private boolean showValue = false,imagesInvalid = true; //Display the value, re-draw the images.
    
    private float pixelsPerValue; //How wide each number is in the selectable value.
    
    public static int temp; //The current value of temperature of the system.
    
    public TemperatureSlider(){ //Creates a new slider with the size of 150 pixels wide by 20 pixels high.
        this(150, 20);
    }
    
    public TemperatureSlider(int width, int height){ //Creates a new slider.
        majorSections = 2;
        minorSections = 2;
        
        maxValue = 273;
        actualWidth = width;
        this.height = height;
        fgHeight = height/2;
        fgWidth = fgHeight;
        if(fgWidth % 2 == 0){
            fgWidth--;
        }
        
        setImage( new GreenfootImage(actualWidth, height) );
    }
    
    public void addedToWorld(World world){ //Method is called by the World class when the slider is added to the world.
        createImages();
        updateImage();
        imagesInvalid = false;
        valueX = getX()*getWorld().getCellSize() - actualWidth/2 + padding;
        valueRight = valueX + valueWidth;
    }
    
    public void act(){ //This method is called by Greenfoot which updates the slider if the user has moved the slider.
        if(Greenfoot.mouseDragged(this) || Greenfoot.mousePressed(this)){
            MouseInfo mouseInfo = Greenfoot.getMouseInfo();
            int x = Math.max(valueX, mouseInfo.getX()*getWorld().getCellSize());
            x -= valueX;
            x = Math.min(x, valueRight);
            setValue(posToValue(x));
            imagesInvalid = true;
        }
        if(imagesInvalid){
            createImages();
            updateImage();
            imagesInvalid = false;
        }
    }
    
    public void setValue(int value){ //Sets the current seleted value of the slider and the dusplay will change to represent this new value.
        if(value < 0){
            value = 0;
        }if(value > maxValue){
            value = maxValue;
        }
        this.temp = value;
        imagesInvalid = true;
    }
    
    public int getValue(){ //Get the current value.
        return temp;
    }
    
    public void showValue(boolean show){ //set whether the value should be displayed next to the slider.
        if(showValue != show){
            imagesInvalid = true;
        }
        showValue = show;
    }
    
    public boolean isShowingValue(){ //Check whether the slider is set to display the value.
        return showValue;
    }
    
    public void setMajorSections(int sections){ //Set the number of major sections to be marked.
        majorSections = sections;
        imagesInvalid = true;
    }
    
    public int getMajorSections(){ //Get the number of major sections that are marked.
        return majorSections;
    }
    

    public void setMinorSections(int sections){ //Set the number of minor sections to be marked per major section.
        minorSections = sections;
        imagesInvalid = true;
    }
    
    public int getMinorSections(){ //Get the minor sections that are marked.
        return minorSections;
    }
    
    public void setMaximumValue(int value){ //Get the maximum value that the user can select.
        if(value <= 0) return;
        maxValue = value;
        pixelsPerValue = valueWidth/(float)maxValue;
        setValue(value);
    }

    public int getMaximumValue(){ //Get the current maximum value which the user can select
        return maxValue;
    }

    private int posToValue(int x){ //Convert a pixel position to a selected value.
        int v = Math.round(x / pixelsPerValue);
        return v;
    }
    
    private int valueToPos(int v){ //Converts the selected value to its equivalent pixel position.
        int p = Math.round(v * pixelsPerValue);
        return p;
    }
    
    private void createImages(){ //Creates the backgroun and the foreground images.
        valueLabelWidth = (int)(Math.floor(Math.log10(maxValue))+1)*10;
        valueWidth = actualWidth - fgWidth - valueLabelWidth;
        valueWidth -= valueWidth%2;
        padding = fgWidth/2;
        pixelsPerValue = valueWidth/(float)maxValue;
        assert padding >= 0;
        
        background = new GreenfootImage(actualWidth, height);
        foreground = new GreenfootImage(fgWidth, height);
        background.drawLine(padding, height/2, padding+valueWidth, height/2);
        if(majorSections > 0){
            float pixelsPerMarker = valueWidth/(float)majorSections;
            float pixelsPerMinor = 0;
            if(minorSections > 0) pixelsPerMinor = pixelsPerMarker/(float)minorSections;
            for(int i=0; i<=majorSections; i++){
                int x = Math.round(i*pixelsPerMarker + padding);
                background.drawLine(x, height, x, 2*height/3);
                for(int m=1; m<minorSections && i<majorSections; m++){
                    int mx = Math.round(x + m*pixelsPerMinor);
                    background.drawLine(mx, 5*height/6, mx, 4*height/6);
                }
            }
        }
        foreground.fillRect(0, 0, fgWidth, fgHeight);
        int pointHeight = Math.min(fgWidth/2, height-fgHeight);
        int[] pointerXPoints = {0, fgWidth/2, fgWidth-1};
        int[] pointerYPoints = {fgHeight, pointHeight+fgHeight, fgHeight};
        foreground.fillPolygon(pointerXPoints, pointerYPoints, 3);
        if(foreground.getWidth()%2 == 0){
            foreground.scale(foreground.getWidth()+1, foreground.getHeight());
        }
    }

    private void updateImage(){ //Updates the position of the foreground and the text
        GreenfootImage image = new GreenfootImage(background);
        image.drawImage(foreground, valueToPos(temp), 0);
        image.drawString(String.valueOf(temp), valueWidth+padding*2, image.getHeight());
        setImage(image);
    }
}
danpost danpost

2016/3/13

#
I believe you posted the wrong slider class. You posted the TemperatureSlider class, where you probably should have posted the NumberOfParticleSlider class (for a start).
RedPanda98 RedPanda98

2016/3/13

#
Sorry! Here it is:
import greenfoot.*;

public class NumberOfParticleSlider extends Actor
{
    private GreenfootImage background, foreground; //The background and foreground images.
    
    private int height, fgWidth = 9, fgHeight = 10; //The height and width of the foreground
    
    private int maxValue, actualWidth, valueWidth, valueLabelWidth, padding, valueX, valueRight; //The maximum value, width in pixels, width of the selectable area, width of the value label,
                                                                                                 //the padding either side of the selectable area, the x-coordinate of the selectable area
                                                                                                 //and the x-coordinate of the right-hand side of the selectable area
    
    private int majorSections, minorSections; //The number of major and minor sections.
    
    private boolean showValue = false,imagesInvalid = true; //Display the value, re-draw the images.
    
    private float pixelsPerValue; //How wide each number is in the selectable value.
    
    public static int particle; //The current value of the particle.
    
    public NumberOfParticleSlider(){ //Creates a new slider with the size of 150 pixels wide by 20 pixels high.
        this(150, 20);
    }
    
    public NumberOfParticleSlider(int width, int height){ //Creates a new slider.
        majorSections = 2;
        minorSections = 2;
        
        maxValue = 20;
        actualWidth = width;
        this.height = height;
        fgHeight = height/2;
        fgWidth = fgHeight;
        if(fgWidth % 2 == 0){
            fgWidth--;
        }
        
        setImage( new GreenfootImage(actualWidth, height) );
    }
    
    public void addedToWorld(World world){ //Method is called by the World class when the slider is added to the world.
        createImages();
        updateImage();
        imagesInvalid = false;
        valueX = getX()*getWorld().getCellSize() - actualWidth/2 + padding;
        valueRight = valueX + valueWidth;
    }
    
    public void act(){ //This method is called by Greenfoot which updates the slider if the user has moved the slider.
        if(Greenfoot.mouseDragged(this) || Greenfoot.mousePressed(this)){
            MouseInfo mouseInfo = Greenfoot.getMouseInfo();
            int x = Math.max(valueX, mouseInfo.getX()*getWorld().getCellSize());
            x -= valueX;
            x = Math.min(x, valueRight);
            setValue(posToValue(x));
            imagesInvalid = true;
        }
        if(imagesInvalid){
            createImages();
            updateImage();
            imagesInvalid = false;
        }
    }
    
    public void setValue(int value){ //Sets the current seleted value of the slider and the dusplay will change to represent this new value.
        if(value < 0){
            value = 0;
        }if(value > maxValue){
            value = maxValue;
        }
        this.particle = value;
        imagesInvalid = true;
    }
    
    public int getValue(){ //Get the current value.
        return particle;
    }
    
    public void showValue(boolean show){ //set whether the value should be displayed next to the slider.
        if(showValue != show){
            imagesInvalid = true;
        }
        showValue = show;
    }
    
    public boolean isShowingValue(){ //Check whether the slider is set to display the value.
        return showValue;
    }
    
    public void setMajorSections(int sections){ //Set the number of major sections to be marked.
        majorSections = sections;
        imagesInvalid = true;
    }
    
    public int getMajorSections(){ //Get the number of major sections that are marked.
        return majorSections;
    }
    

    public void setMinorSections(int sections){ //Set the number of minor sections to be marked per major section.
        minorSections = sections;
        imagesInvalid = true;
    }
    
    public int getMinorSections(){ //Get the minor sections that are marked.
        return minorSections;
    }
    
    public void setMaximumValue(int value){ //Get the maximum value that the user can select.
        if(value <= 0) return;
        maxValue = value;
        pixelsPerValue = valueWidth/(float)maxValue;
        setValue(value);
    }

    public int getMaximumValue(){ //Get the current maximum value which the user can select
        return maxValue;
    }

    private int posToValue(int x){ //Convert a pixel position to a selected value.
        int v = Math.round(x / pixelsPerValue);
        return v;
    }
    
    private int valueToPos(int v){ //Converts the selected value to its equivalent pixel position.
        int p = Math.round(v * pixelsPerValue);
        return p;
    }
    
    private void createImages(){ //Creates the backgroun and the foreground images.
        valueLabelWidth = (int)(Math.floor(Math.log10(maxValue))+1)*10;
        valueWidth = actualWidth - fgWidth - valueLabelWidth;
        valueWidth -= valueWidth%2;
        padding = fgWidth/2;
        pixelsPerValue = valueWidth/(float)maxValue;
        assert padding >= 0;
        
        background = new GreenfootImage(actualWidth, height);
        foreground = new GreenfootImage(fgWidth, height);
        background.drawLine(padding, height/2, padding+valueWidth, height/2);
        if(majorSections > 0){
            float pixelsPerMarker = valueWidth/(float)majorSections;
            float pixelsPerMinor = 0;
            if(minorSections > 0) pixelsPerMinor = pixelsPerMarker/(float)minorSections;
            for(int i=0; i<=majorSections; i++){
                int x = Math.round(i*pixelsPerMarker + padding);
                background.drawLine(x, height, x, 2*height/3);
                for(int m=1; m<minorSections && i<majorSections; m++){
                    int mx = Math.round(x + m*pixelsPerMinor);
                    background.drawLine(mx, 5*height/6, mx, 4*height/6);
                }
            }
        }
        foreground.fillRect(0, 0, fgWidth, fgHeight);
        int pointHeight = Math.min(fgWidth/2, height-fgHeight);
        int[] pointerXPoints = {0, fgWidth/2, fgWidth-1};
        int[] pointerYPoints = {fgHeight, pointHeight+fgHeight, fgHeight};
        foreground.fillPolygon(pointerXPoints, pointerYPoints, 3);
        if(foreground.getWidth()%2 == 0){
            foreground.scale(foreground.getWidth()+1, foreground.getHeight());
        }
    }

    private void updateImage(){ //Updates the position of the foreground and the text
        GreenfootImage image = new GreenfootImage(background);
        image.drawImage(foreground, valueToPos(particle), 0);
        image.drawString(String.valueOf(particle), valueWidth+padding*2, image.getHeight());
        setImage(image);
    }
}
danpost danpost

2016/3/13

#
Okay -- the slider class is not limited, as far as its behavior, to your project (other than what its name implies). That is, there is no code in it which refers to other classes specific to your project. This means that it is re-usable and portable (after generalizing the name and the value fields, 'temp' and 'particles'). In turn, it means that you do not need multiple classes, one for each type slider; you can have one Slider class and use it for all your Slider objects (the value field should be an instance field, not a class field -- not 'static'). Anyway, to get back to your issue, you now need to show all codes related to the NumberOfParticleSlider class and related to any objects created from that class. Indicate were each part is located within your project (give the class trees to each bit of code provided).
You need to login to post a reply.