Here's some code I found years ago (2007) that I thought was interesting. You can draw your own polygon by selecting the Options: Draw polygon and then clicking on the window to set the sides of the polygon and pressing Done to have the program fill in the polygon.
Java Code:
// Fill a polygon starting at a clicked on point

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
import java.util.*;

public class FillPolygon extends JPanel implements ActionListener {

   final int MaxLvl = 3000;            // Stop recursion at this level

   final int Width = 300;
   final int Height = 300;
    
    final static Color bg = Color.white;
    final static Color fg = Color.black;
    final static Color red = Color.red; 
    final static Color white = Color.white;

    final static JButton doneBtn = new JButton("Done");

    // Define the points in the polygon
    int[] xPts = {50, 250, 250,  50,  50, 100, 150};
    int[] yPts = {50,  50, 250, 250, 150, 200, 150};

    Polygon poly = new Polygon(xPts, yPts, xPts.length);

    Vector polyPts;                    // Save new points here

    BufferedImage theImage;
    Image anImage;
    Graphics g2d;
    int[] pixels;

    boolean debug = false; //true;


    //----------------------------------------------------------------------
    public FillPolygon() {
	     setBackground(bg);
        buildImage();

        // Get the image into an array of pixels
        int w = Width, h = Height;
        pixels = new int[w * h];
        try {
           PixelGrabber pg = new PixelGrabber(theImage, 0, 0, w, h, pixels, 0, w);
           pg.grabPixels();

           // Check for errors.
           if ((pg.status() & ImageObserver.ABORT) != 0) {
               System.err.println("Error while fetching image");
               System.exit(1);
           }
        } catch (Exception e) {
           e.printStackTrace();
        }

        addMouseListener(new MouseEventHandler());
        doneBtn.addActionListener(this);
    }
    //--------------------------------------------
    // Build the image to show & fill
    private void buildImage() {
        // Create an image to draw on
        theImage = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_RGB);
        g2d = theImage.getGraphics();   // THis also works
        g2d.setColor(Color.yellow);     // Set fill/background color
        g2d.fillRect(0,0, Width, Height);
        g2d.setColor(Color.black);
        g2d.drawPolygon(poly);
        g2d.setColor(Color.white);
        g2d.fillPolygon(poly);
        repaint();
    } // end buildImage()

    private void blankImg() {
        g2d = theImage.getGraphics();   // THis also works
        g2d.setColor(Color.yellow);     // Set fill/background color
        g2d.fillRect(0,0, Width, Height);
        repaint();
    }

    //-----------------------------------------------------
    // Class to hold the loc of pixels
    class MyPoint {
      int x;
      int y;
      MyPoint(int x, int y) {
         this.x = x;
         this.y = y;
      }
      public boolean equals(MyPoint mp) {
         return x == mp.x && y == mp.y;
      }
      public String toString() {
         return "[" + x + "," + y + "]";
      }
    } // end class MyPoint

   int targetPixelValue = 0;
   final int blueRGB  = 0Xff0000ff;
   final int greenRGB = 0Xff00ff00;
   final int whiteRGB = 0XFFFFFFFF;
   final int blackRGB = 0XFF000000;

   //---------------------------------------------------------------------------------
   class MouseEventHandler extends MouseAdapter {
        public void mousePressed(MouseEvent evt) {
          final int x = evt.getX(), y = evt.getY();
          // Are we drawing new polygon or to fill existing one?
          if(drawPolyMI.isSelected()) {
            MyPoint mp = new MyPoint(x, y);
            polyPts.add(mp);           // Add new point to list
            if(polyPts.size() > 1) {
               // draw the polygon
               g2d = theImage.getGraphics();
               g2d.setColor(Color.black);
               MyPoint mp0 = (MyPoint)polyPts.get(0);  // get first
               for(int i=1; i < polyPts.size(); i++) {
                  MyPoint mp1 = (MyPoint)polyPts.get(i); // get next
                  g2d.drawLine(mp0.x, mp0.y, mp1.x,mp1.y);
                  mp0 = mp1;           // move forward
               } // end for()
               repaint();
            }else {
               theImage.setRGB(x, y, blackRGB); // change the color of the point
            }
          }else{
            if(!poly.contains(x, y)) {
               System.err.println("outside the polygon");
               return;
            }
            // Save color of pixel where mouse Pressed
            targetPixelValue = pixels[y * Width + x];
            int pix = theImage.getRGB(x, y);
            System.out.println("mP pix=" + pix + " vs " + targetPixelValue
                               + " at " + x + "," + y);

//            g2d.setColor(Color.blue);   // change the color of that pixel
//            g2d.fillRect(x, y, 1, 1);
//            theImage.setRGB(x, y, blueRGB); // Change the color of that pixel
//            repaint();
            // Start a thread to fill in the poly starting at this point
            new Thread(new Runnable() {
               public void run() {
//                  Vector v = new Vector();
//                  v.add(new MyPoint(x, y));
//                  fill4(v, 0);
//                  fourFill(x, y, whiteRGB, greenRGB, 0);
                  fillWithQueue(x, y, whiteRGB, greenRGB);
                  System.out.println(">>> Finished filling <<<");
               }
            }).start();
          }
        } // end mousePressed()

        public void mouseReleased(MouseEvent evt) {
            repaint();
        }
    } // end class

    //-----------------------------------------------------------------------
    /*
    Procedure Four_Fill (x, y, fill_col, bound_col: integer);
      var
           curr_color: integer;
      begin
           curr_color := inquire_color(x, y)
           if (curr_color <> bound color) and (curr_color <> fill_col) then
           begin
               set_pixel(x, y, fill_col)
               Four_Fill (x+1, y, fill_col, bound_col);
               Four_Fill (x-1, y, fill_col, bound_col);
               Four_Fill (x, y+1, fill_col, bound_col);
               Four_Fill( x, y-1, fill_col, bound_col);
      end;
    */
    public void fourFill(int x, int y, int mtPixel, int fillCol, int lvl) {
      lvl++;
      if(lvl > MaxLvl)
         return;
      try {
         if(theImage.getRGB(x, y) == mtPixel) {
            theImage.setRGB(x, y, fillCol); // change the color
            fourFill(x+1, y, whiteRGB, greenRGB, lvl);
            fourFill(x-1, y, whiteRGB, greenRGB, lvl);
            fourFill(x, y+1, whiteRGB, greenRGB, lvl);
            fourFill(x, y-1, whiteRGB, greenRGB, lvl);
         } // end if()
      }catch(Error e) {
         System.err.println("Error: " + e + ", lvl=" + lvl);
         //Error: java.lang.StackOverflowError, lvl=3154
      }
    } // end four_fill()

    //-----------------------------------------------------------------------
    public void fill4(Vector vec, int lvl )   {
      lvl++;                           // To next level
      try {
         // Set the color for all the points in vec
         for(int i=0; i < vec.size(); i++) {
            MyPoint mp = (MyPoint)vec.get(i);
//            pixels[mp.y * Width + mp.x] = greenRGB;   // need to createImage below to see
    			theImage.setRGB(mp.x, mp.y, greenRGB); // set the color for this one
         } // end for(i)

         if(debug) System.out.println("Set colors for " + vec.size() + ", lvl=" + lvl);
//         MemoryImageSource mis = new MemoryImageSource(Width, Height, pixels, 0, Width);
//         anImage = createImage(mis);

         repaint();
         // Get all the neighbors to the points in vec
         Vector newVec = getNeighbors(vec, whiteRGB, lvl); // get all the empty neighbors
         if(newVec == null || newVec.size() == 0)
            return;                    // exit if none found
         fill4(newVec, lvl);
      }catch(Error e) {
         System.err.println("Error: " + e + ", lvl=" + lvl);
      }
  } // end fill4

  //------------------------------------------------------------------
  // Use a FIFO queue vs recursion to do the fill
  Vector theQueue = new Vector(256000);

  private void fillWithQueue(int x, int y, int mtPixel, int fillColor) {
    theQueue.add(new MyPoint(x, y));   // Prime the pump

    int setCnt = 0;
    int cnt = 0;
    int dups = 0;
    int maxQueueSize = 0;


    // Process the points until none left
    while(theQueue.size() > 0) {
      MyPoint mp = (MyPoint)theQueue.remove(0);
      if(theImage.getRGB(mp.x, mp.y) != mtPixel) {    // Test if only MT pixels in queue
         // Possible duplicates !!!            
//         System.out.println("Not MT pixel at "+ mp);  //Not MT pixel at [184,136] MANY!!!!
         dups++;
         continue;
      }
      cnt++;
		theImage.setRGB(mp.x, mp.y, fillColor); // set the color for this one
      if(cnt % 100 == 0)
         repaint();                    // Every 100 pixels   

      // Check/add the 4 neighbors
      // North = y-1
      if(theImage.getRGB(mp.x, mp.y-1) == mtPixel) {
         MyPoint nmp = new MyPoint(mp.x, mp.y-1);
//            if(!newVec.contains(nmp))
            theQueue.add(nmp);
      }else setCnt++;

      // East = x+1
      if(theImage.getRGB(mp.x+1, mp.y) == mtPixel) {
         MyPoint nmp = new MyPoint(mp.x+1, mp.y);
//            if(!newVec.contains(nmp))
            theQueue.add(nmp);
      }else setCnt++;

      // South = y+1
      if(theImage.getRGB(mp.x, mp.y+1) == mtPixel){
         MyPoint nmp = new MyPoint(mp.x, mp.y+1);
//            if(!newVec.contains(nmp))
            theQueue.add(nmp);
      }else setCnt++;

      // West = x-1
      if(theImage.getRGB(mp.x-1, mp.y) == mtPixel){
         MyPoint nmp = new MyPoint(mp.x-1, mp.y);
//            if(!newVec.contains(nmp))
            theQueue.add(nmp);
      }else setCnt++;

      if(theQueue.size() > maxQueueSize)
         maxQueueSize = theQueue.size();

//      if((cnt % 500) == 0)
//         System.out.print(" "+ theQueue.size());
    } // end while

    System.out.println("end of queue. setCnt=" + setCnt + ", maxQ=" + maxQueueSize
                        + ", #dups=" + dups);
    //end of queue. setCnt=65549, maxQ=298, #dups=31952
    //end of queue. setCnt=65549, maxQ=400, #dups=31952
    //end of queue. setCnt=65549, maxQ=589, #dups=31952
    //end of queue. setCnt=65549, maxQ=298, #dups=31952
  } // end fillWith Queue

  //-------------------------------------------------------------------------------------------
  // Return a Vector holding the points for all the neighbors to the points in incoming vector
  private Vector getNeighbors(Vector vec, int mtPixel, int lvl) {
      if(lvl > MaxLvl)
         return null;                  // Q&D exit
       int setCnt = 0;
       Vector newVec = new Vector(vec.size()*3);

       // Look at the four neighbors: N, E, S, W  
       for(int i=0; i < vec.size(); i++) {
         MyPoint mp = (MyPoint)vec.get(i);
         // North = y-1
         if(theImage.getRGB(mp.x, mp.y-1) == mtPixel) {
            MyPoint nmp = new MyPoint(mp.x, mp.y-1);
//            if(!newVec.contains(nmp))
               newVec.add(nmp);
         }else setCnt++;
         // East = x+1
         if(theImage.getRGB(mp.x+1, mp.y) == mtPixel) {
            MyPoint nmp = new MyPoint(mp.x+1, mp.y);
//            if(!newVec.contains(nmp))
               newVec.add(nmp);
         }else setCnt++;
         // South = y+1
         if(theImage.getRGB(mp.x, mp.y+1) == mtPixel){
            MyPoint nmp = new MyPoint(mp.x, mp.y+1);
//            if(!newVec.contains(nmp))
               newVec.add(nmp);
         }else setCnt++;
         // West = x-1
         if(theImage.getRGB(mp.x-1, mp.y) == mtPixel){
            MyPoint nmp = new MyPoint(mp.x-1, mp.y);
//            if(!newVec.contains(nmp))
               newVec.add(nmp);
         }else setCnt++;
       } // end for(i) thru vec

       if(debug) System.out.println(newVec.size() + " neighbors at lvl=" + lvl + ", setCnt=" + setCnt
                                    + ", # incoming pts=" + vec.size());
       return newVec;
  } // end getNeighbors()

  //-----------------------------------------------------------
  // Handle GUI events
   public void actionPerformed(ActionEvent e) {
      Object obj = e.getSource();
        if (obj == doneBtn) {
          if(drawPolyMI.isSelected()) {
            doneBtn.setEnabled(false); // done - turn off
          }else{
            System.err.println("doneBtn called without drawPoly");
            return;
          }
          drawPolyMI.setSelected(false);  // turn off when done

          // Copy points from polyPts to xPts and yPts
          xPts = new int[polyPts.size()];
          yPts = new int[polyPts.size()];
          for(int i=0; i < polyPts.size(); i++) {
            MyPoint mp = (MyPoint)polyPts.get(i);
            xPts[i] = mp.x;
            yPts[i] = mp.y;
          }
          poly = new Polygon(xPts, yPts, xPts.length); // create new Polygon
          buildImage();                // go draw the new one

        }else if(obj == clearPolyMI) {
          buildImage();

        }else if(obj == drawPolyMI) {
          if(drawPolyMI.isSelected()) {
            doneBtn.setEnabled(true);   // turn on
            polyPts = new Vector();
            blankImg();

          }else{
            doneBtn.setEnabled(false); // done - turn off
          }
	     }else{
         System.out.println("unkn ae " + e);
        }
   }

   public void paintComponent(Graphics g) {
//      System.out.println("g=" + g);   //g=sun.java2d.SunGraphics2D
   	super.paintComponent(g);
      if(anImage != null)
         g.drawImage(anImage, 0, 0, this);
      else   
         g.drawImage(theImage, 0, 0, this);
//      g.setColor(Color.red);
//      g.fillPolygon(poly);
   } // end paintComponent()

   JMenu optionsM = new JMenu("Options");
   JCheckBoxMenuItem drawPolyMI = new JCheckBoxMenuItem("Draw Polygon");
   JMenuItem clearPolyMI = new JMenuItem("Clear poly");

   private JMenuBar createMB() {
      JMenuBar mb = new JMenuBar();
      optionsM.add(drawPolyMI);  
      drawPolyMI.addActionListener(this);
      optionsM.add(clearPolyMI);  
      clearPolyMI.addActionListener(this);
      mb.add(optionsM);
      return mb;
   }

   //--------------------------------------------------------------------
   public static void main(String s[]){
   	WindowListener wl = new WindowAdapter() {
   		public void windowClosing(WindowEvent e) {System.exit(0);}
   		public void windowClosed(WindowEvent e) {System.exit(0);}
   	};
   	JFrame f = new JFrame("Fill Polygon");
   	f.addWindowListener(wl);
      FillPolygon fp = new FillPolygon();
      f.setJMenuBar(fp.createMB());
   	f.getContentPane().add(BorderLayout.CENTER, fp);

   	JPanel panel = new JPanel();
   	panel.add(doneBtn);
      doneBtn.setEnabled(false);
    	f.getContentPane().add(BorderLayout.SOUTH, panel);
      f.setResizable(false);
   	f.setSize(300, 400);
      f.setLocationRelativeTo(null);
   	f.setVisible(true);
    }  // end main()

} // end class FillPolygon