import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.beans.*;

// This is an action that tiles all of the internal frames.

public class TileAction extends AbstractAction {
  private JDesktopPane desktop;

  public TileAction(JDesktopPane desk) {
    super("Tile");
    desktop = desk;
  }

  public void actionPerformed(ActionEvent event) {
    
    // Find out the number of open frames.
    JInternalFrame[] allframes = desktop.getAllFrames();
    int count = allframes.length;
    if (count == 0) return;

    // Determine the correct grid size.
    int sqrt = (int)Math.sqrt(count);
    int rows = sqrt;
    int cols = sqrt;

    if ((rows*cols) < count) {
      cols++;
      if ((rows*cols) < count) {
	rows++;
      }
    }

    // Define some initial values for size and location.
    Dimension size = desktop.getSize();

    int w = size.width/cols;
    int h = size.height/rows;
    int x = 0;
    int y = 0;

    // Iterate over the frames, deiconifying any iconified frames
    // and then relocating and resizing each
    for (int i=0; i<rows; i++) {
      for (int j=0; j<cols; j++) {
	JInternalFrame f = allframes[(i*cols)+j];
	
	if ((f.isClosed() == false) && (f.isIcon() == true)) {
	  try {
	    f.setIcon(false);
	  } catch (PropertyVetoException ex) {}
	}
	
	desktop.getDesktopManager().resizeFrame(f, x, y, w, h);
	x += w;
      }
      
      y += h; // the next row
      x = 0;
    }
  }
}
