Search code examples
javaeclipsejavafxflood-fillpane

Flood fill using java Pane - JAVA


Hi I am supposed to create function which would do flood fill on a Pane containing Shapes using Java. It is supposed to behave just like MSPaint, I dont need to later move rectangles Lines or other shapes. I was thinking converting Pane into Image and then work with pixels and then clear all Panes children and insert it as a image but I cant make it work. code example:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class Paint extends Application {


public static void main(String[] args) {
    launch(args);
}

private Pane pane;


@Override
public void start(Stage primaryStage) {
    pane= new Pane();

    primaryStage.setTitle("Fill");
    Scene scene = new Scene(pane,500,600);
    primaryStage.setScene(scene);
    primaryStage.show();


    pane.setOnMousePressed((e)->{
        doFill(e.getX(),e.getY());
    });

    //RECT 1
    Rectangle rect1=new Rectangle(1,100,200,300);
    rect1.setStroke(Color.BLACK);
    rect1.setStrokeWidth(2);
    rect1.setFill(Color.WHITE);

  //RECT 2
    Rectangle rect2=new Rectangle(50,150,200,400);
    rect2.setStroke(Color.BLACK);
    rect2.setStrokeWidth(2);
    rect2.setFill(Color.WHITE);

    //LINE
    Line line=new Line(0,0,200,550);
    rect2.setStroke(Color.BLACK);
    rect2.setStrokeWidth(2);


    pane.getChildren().addAll(rect1,rect2,line);
}

private void doFill(double eventX, double eventY){
    //**TODO**
}

}


Solution

  • Got managed to do that function even though its a bit messy. So for everyone who is getting anxious over this:

        private void doFill(double eventX, double eventY,boolean b){
    
        WritableImage i=pane.snapshot(new SnapshotParameters(), null);
        ArrayList<Integer> pozicie=new ArrayList<Integer>();
        ArrayList<Character> strany=new ArrayList<Character>();
        pozicie.add((int)eventX);
        pozicie.add((int)eventY);
        int c=i.getPixelReader().getColor((int)eventX,(int)eventY).hashCode();
        if(c==usedColor.hashCode()){
            //System.out.println("same color");
    
            return;}
        strany.add('a');
    
    
        while(pozicie.size()!=0){
            char strana=strany.remove(0);
            int x=pozicie.remove(0);
            int y=pozicie.remove(0);
            i.getPixelWriter().setColor(x, y, usedColor);
            if(strana=='d'){
                //iba dole
                if(y<pane.getHeight()-2 && i.getPixelReader().getColor(x, y+1).hashCode()==c){
                    pozicie.add(x);
                    pozicie.add(y+1);
                    strany.add('d');
                }
            }
            else if(strana=='u'){
                //iba hore
                if( y>100 && i.getPixelReader().getColor(x, y-1).hashCode()==c){
                    pozicie.add(x);
                    pozicie.add(y-1);
                    strany.add('u');
                }
            }
            else{
    
    
            if(x>2 && i.getPixelReader().getColor(x-1, y).hashCode()==c){
                pozicie.add(x-1);
                pozicie.add(y);
                strany.add('l');
            }
            if(x<pane.getWidth()-2 && i.getPixelReader().getColor(x+1, y).hashCode()==c){
                pozicie.add(x+1);
                pozicie.add(y);
                strany.add('r');
            }
            if( y>101 && i.getPixelReader().getColor(x, y-1).hashCode()==c){
                pozicie.add(x);
                pozicie.add(y-1);
                strany.add('u');
            }
            if(y<pane.getHeight()-2 && i.getPixelReader().getColor(x, y+1).hashCode()==c){
                pozicie.add(x);
                pozicie.add(y+1);
                strany.add('d');
            }
            }
        }
        pane.getChildren().clear();
        pane.getChildren().add(new ImageView(i));
    
    }