import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;

/** A figure to help you visualize coordinate transformations
 *  with Java2D. The dotted rectangle represents a "picture frame"
 *  into which a person is drawing. The gray rectangle represents
 *  a sheet of paper under the frame, onto which the drawing occurs.
 *  The idea is that the transformation results in the frame (and
 *  drawer) being moved, the drawing being performed, and then
 *  the frame moved back to see the final result. The view an outside
 *  observer would see (where the drawer and frame moves to do the
 *  drawing) is illustrated in the second column. The view the drawer
 *  himself would see (where the paper appears to move in the opposite
 *  direction from that specified in the transformation) is shown
 *  in the third column. The last column shows the result.
 *
 *  From tutorial on learning Java2D at
 *  http://www.apl.jhu.edu/~hall/java/Java2D-Tutorial.html
 *
 *  1998 Marty Hall, http://www.apl.jhu.edu/~hall/java/
 */

public class TransformTest {
  public static void main(String[] args) {
    WindowUtilities.setNativeLookAndFeel();
    double[][] transforms =
      { { 15, 25, 0 },
        {  0,  0, Math.PI/25 },
        { 15, 25, Math.PI/25 } };
    TransformExample[][] transformExamples =
      new TransformExample[3][4];
    for(int i=0; i<transforms.length; i++) {
      double x = transforms[i][0];
      double y = transforms[i][1];
      double rotation = transforms[i][2];
      transformExamples[i][0] =
          new TransformExample(0, 0, 0, 0, 0, 0, 0, 0, 0);
      transformExamples[i][1] =
        new TransformExample(x, y, rotation, 0, 0, 0, x, y, rotation);
      transformExamples[i][2] =
        new TransformExample(0, 0, 0, -x, -y, -rotation, 0, 0, 0);
      transformExamples[i][3] =
        new TransformExample(0, 0, 0, 0, 0, 0, x, y, rotation);
    }
    JTable table = new JTable(new TransformModel(transformExamples));
    table.setDefaultRenderer(Object.class, new ComponentRenderer());
    table.setRowHeight(210);
    table.setIntercellSpacing(new Dimension(20, 40));
    JTableHeader header = table.getTableHeader();
    header.setFont(new Font("SansSerif", Font.BOLD, 18));
    JScrollPane pane = new JScrollPane(table);
    int width = 900;
    int height = table.getPreferredSize().height +
                 table.getTableHeader().getPreferredSize().height +
                 31;
    String title =
      "Row1: positive x/y translation. Row 2: positive rotation. " +
      "Row3: positive translation and rotation.";
    WindowUtilities.openInJFrame(pane, width, height, title);
  }
}

/** A model for a 4-column table with fixed column names,
 *  where the data for the cells is supplied via a 2D array
 *  of TransformExample values.
 */

class TransformModel extends AbstractTableModel {
  private TransformExample[][] transformExamples;

  public int getRowCount() {
    return(transformExamples.length);
  }

  public int getColumnCount() {
    return(transformExamples[0].length);
  }

  public TransformModel(TransformExample[][] transformExamples) {
    this.transformExamples = transformExamples;
  }

  public String getColumnName(int col) {
    String[] columnNames =
      { "Before Transformation",
        "Outsider's Perspective",
        "Drawer's Perspective",
        "Final Result" };
    return(columnNames[col]);
  }

  public Object getValueAt(int row, int col) {
    return(transformExamples[row][col]);
  }
}

/** A renderer which draws a graphical component in a table cell. */

class ComponentRenderer implements TableCellRenderer {
  public Component getTableCellRendererComponent(JTable table,
                                                 Object value,
                                                 boolean isSelected,
                                                 boolean hasFocus,
                                                 int row,
                                                 int column) {
    if (value == null) return(null); // To handle tool tips
    if (value instanceof JComponent) {
      JComponent val = (JComponent)value;
      val.setOpaque(true);
      val.setBackground(Color.white);
      return(val);
    } else {
      String s = value.toString();
      JLabel label = new JLabel(s, SwingConstants.CENTER);
      label.setBackground(Color.white);
      return(label);
    }
  }
}

