Posted by : Unknown Thursday 18 June 2015


This program demonstrates recursion by counting the number of squares in a "blob". The squares are arranged in a grid, and each position in the grid can be either empty or filled. A blob is defined to be a filled square and any square that can be reached from that square by moving horizontally or vertically to other filled squares. This program fills the grid randomly. If the user clicks on a filled square, all the squares in the blob that contains that square are colored red, and the number of squares in the blob is reported. The program can also count and report the number of blobs. When the user clicks a "New Blobs" button, the grid is randomly re-filled.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Blobs extends JPanel implements MouseListener, ActionListener 
{
    public static void main(String[] args) 
    {
        JFrame window = new JFrame("Recursive Blob Counting");
        window.setContentPane( new Blobs(454,400) );
        window.pack();
        window.setResizable(false);
        window.setLocation(150,100);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
    }
    final static int SQUARE_SIZE = 9;  
    JLabel message;      
   JComboBox<String> percentFill; 
    int rows;   
    int columns;
    boolean[][] filled; 
    boolean[][] visited; 
    public Blobs(int width, int height) {
        setLayout(null);
        setBackground(new Color(220,220,255));
        addMouseListener(this);
        setBorder(BorderFactory.createMatteBorder(2,2,2,2,Color.BLUE));
        setPreferredSize( new Dimension(width,height) );

        rows = (height - 120) / SQUARE_SIZE;
        columns = (width - 20) / SQUARE_SIZE;

        filled = new boolean[rows][columns];
        visited = new boolean[rows][columns];

        for (int r = 0; r < rows; r++)
            for (int c = 0; c < columns; c++)
                filled[r][c] = (Math.random() < 0.3);

        /* Create the components. */

        message = new JLabel("Click a square to get the blob size.", JLabel.CENTER);
        message.setForeground(Color.BLUE);
        message.setFont(new Font("Helvetica",Font.PLAIN,14));

        percentFill = new JComboBox<String>();
        percentFill.addItem("10% fill");
        percentFill.addItem("20% fill");
        percentFill.addItem("30% fill");
        percentFill.addItem("40% fill");
        percentFill.addItem("50% fill");
        percentFill.addItem("60% fill");
        percentFill.addItem("70% fill");
        percentFill.addItem("80% fill");
        percentFill.addItem("90% fill");
        percentFill.setBackground(Color.WHITE);
        percentFill.setSelectedIndex(2);

        JButton newButton = new JButton("New Blobs");
        newButton.addActionListener(this);
        newButton.setBackground(Color.LIGHT_GRAY);

        JButton countButton = new JButton("Count the Blobs");
        countButton.addActionListener(this);
        countButton.setBackground(Color.LIGHT_GRAY);

        /* Add the components to the panel and set their sizes and positions. */

        add(message);
        add(newButton);
        add(percentFill);
        add(countButton);

        message.setBounds(15, height-100, width-30, 23);
        countButton.setBounds(15, height-70, width-30, 28);
        newButton.setBounds(15, height-35, (width-40)/2, 28);
        percentFill.setBounds(width/2 + 5, height-35, (width-40)/2, 28);

    } // end constructor

    public void actionPerformed(ActionEvent evt) {
        String cmd = evt.getActionCommand();
        if (cmd.equals("New Blobs"))
            fillGrid();
        else if (cmd.equals("Count the Blobs"))
            countBlobs();
    }


    private void fillGrid() {
        double probability = (percentFill.getSelectedIndex() + 1) / 10.0;
        for (int r = 0; r < rows; r++)
            for (int c = 0; c < columns; c++) {
                filled[r][c] = (Math.random() < probability);
                visited[r][c] = false;
            }
        message.setText("Click a square to get the blob size.");
        repaint();
    }

    private void countBlobs() {

        int count = 0;
        for (int r = 0; r < rows; r++)
            for (int c = 0; c < columns; c++)
                visited[r][c] = false;
        for (int r = 0; r < rows; r++)
            for (int c = 0; c < columns; c++) {
                if (getBlobSize(r,c) > 0)
                    count++;
            }

        repaint(); 
        message.setText("The number of blobs is " + count);

    } // end countBlobs()

     private int getBlobSize(int r, int c) {
        if (r < 0 || r >= rows || c < 0 || c >= columns) {
            return 0;
        }
        if (filled[r][c] == false || visited[r][c] == true) {               
            return 0;
        }
        visited[r][c] = true; 
        int size = 1; 
        size += getBlobSize(r-1,c);
        size += getBlobSize(r+1,c);
        size += getBlobSize(r,c-1);
        size += getBlobSize(r,c+1);
        return size;
    }  // end getBlobSize()

    public void mousePressed(MouseEvent evt) {
        int row = (evt.getY() - 10) / SQUARE_SIZE;
        int col = (evt.getX() - 10) / SQUARE_SIZE;
        if (row < 0 || row >= rows || col < 0 || col >= columns) {
            message.setText("Please click on a square!");
            return;
        }
        for (int r = 0; r < rows; r++)
            for (int c = 0; c < columns; c++)
                visited[r][c] = false;  // Clear visited array before counting.
        int size = getBlobSize(row,col);
        if (size == 0)
            message.setText("There is no blob at (" + row + "," + col + ").");
        else if (size == 1)
            message.setText("Blob at (" + row + "," + col + ") contains 1 square.");
        else
            message.setText("Blob at (" + row + "," + col + ") contains " + size + " squares.");
        repaint();
    }


    public void mouseReleased(MouseEvent e) { } 
    public void mouseClicked(MouseEvent e) { }
    public void mouseEntered(MouseEvent e) { }
    public void mouseExited(MouseEvent e) { }

     public void paintComponent(Graphics g) {

        super.paintComponent(g);        

        g.setColor(Color.WHITE);
        g.fillRect(10, 10, columns*SQUARE_SIZE, rows*SQUARE_SIZE);

        g.setColor(Color.BLACK);
        for (int i = 0; i <= rows; i++)
            g.drawLine(10, 10 + i*SQUARE_SIZE, columns*SQUARE_SIZE + 10, 10 + i*SQUARE_SIZE);
        for (int i = 0; i <= columns; i++)
            g.drawLine(10 + i*SQUARE_SIZE, 10, 10 + i*SQUARE_SIZE, rows*SQUARE_SIZE + 10);

       
        for (int r = 0; r < rows; r++)
            for (int c = 0; c < columns; c++) {
                if (visited[r][c]) {
                    g.setColor(Color.RED);
                    g.fillRect(11 + c*SQUARE_SIZE, 11 + r*SQUARE_SIZE, SQUARE_SIZE - 1, SQUARE_SIZE - 1);
                }
                else if (filled[r][c]) {
                    g.setColor(Color.GRAY);
                    g.fillRect(11 + c*SQUARE_SIZE, 11 + r*SQUARE_SIZE, SQUARE_SIZE - 1, SQUARE_SIZE - 1);
                }
            }

    } // end paintComponent();

} // end class Blobs

Output:

Leave a Reply

Subscribe to Posts | Subscribe to Comments

Welcome to My Blog

Translate

Popular Post

Total Pageviews

Blog Archive

- Copyright © Learning Java Program - Powered by Blogger -