Package cranks.ui

Source Code of cranks.ui.CopyMoveTriangle

/*
* @(#)CopyMoveTriangle.java 1.0
* Copyright (C) 2004,2005 Aravind Alwan
*
* This file is part of CRANKS.
*
* CRANKS is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* CRANKS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details. A copy of the GNU
* General Public License is provided in LICENSE.txt, which is located
* in the installation directory of CRANKS.
*
* You may also obtain a copy of the GNU General Public License
* by writing to the Free Software Foundation, Inc., 51 Franklin St,
* Fifth Floor, Boston, MA  02110-1301  USA
*/

package cranks.ui;

import javax.swing.*;
import javax.swing.event.UndoableEditEvent;
import java.awt.GridLayout;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Vector;
import cranks.undo.ConstructionStep;
import cranks.geom.Triangle;
import cranks.geom.Line;
import cranks.geom.Point;
import cranks.geom.Angle;
import cranks.geom.GeometricalObject;

/**
* This class is used to create a copy of a triangle with one of its sides
* aligned with another line of the same length as the side
*/

public class CopyMoveTriangle extends EditDialog implements PropertyChangeListener,
                                      ActionListener {
  public static final int COPY_MOVE = 1;

  JOptionPane optionPane;
  JPanel pMainPanel = new JPanel();

  JPanel pObjectSelection = new JPanel();
  JLabel lTriangle = new JLabel("Select Triangle");
  JComboBox cTriangle = new JComboBox();
  JLabel lPickSide = new JLabel("Pick Side to align");
  JComboBox cPickSide = new JComboBox();
  JLabel lNewSide = new JLabel("Select new Side");
  JComboBox cNewSide = new JComboBox();
  JPanel pOrientation = new JPanel();
  JLabel lOrientation = new JLabel("");
  JComboBox cSelectOrientation = new JComboBox();

  private boolean initialized;

  public CopyMoveTriangle(JFrame frame, String title,
                          Vector<GeometricalObject> Objects) {
    super(frame, title, false, Objects);
    setID(5);
    jbInit();
    pack();
    initialized = false;
  }

  private void jbInit() {

    pMainPanel.setLayout(new GridLayout(2,1));

    pObjectSelection.setLayout(new GridLayout(4,2,20,10));
    pObjectSelection.setBorder(BorderFactory.createEmptyBorder(20,20,0,20));
    pObjectSelection.add(lTriangle);
    pObjectSelection.add(cTriangle);
    cTriangle.addActionListener(this);
    cTriangle.setActionCommand("Triangle");
    pObjectSelection.add(lPickSide);
    pObjectSelection.add(cPickSide);
    cPickSide.addActionListener(this);
    cPickSide.setActionCommand("Old Side");
    pObjectSelection.add(lNewSide);
    pObjectSelection.add(cNewSide);
    cNewSide.addActionListener(this);
    cNewSide.setActionCommand("New Side");

    pOrientation.setLayout(new BoxLayout(pOrientation, BoxLayout.Y_AXIS));
    pOrientation.setBorder(BorderFactory.createCompoundBorder(
                              BorderFactory.createEmptyBorder(5,20,5,20),
                              BorderFactory.createTitledBorder("Orientation")));
    pOrientation.add(lOrientation);
    pOrientation.add(cSelectOrientation);
    lOrientation.setAlignmentX(JComponent.CENTER_ALIGNMENT);
    lOrientation.setHorizontalAlignment(SwingConstants.CENTER);
    cSelectOrientation.setMaximumSize(new Dimension(100, 25));
    pMainPanel.add(pObjectSelection);
    pMainPanel.add(pOrientation);

    Object[] options = {"Ok", "Cancel"};
    optionPane = new JOptionPane(pMainPanel, JOptionPane.PLAIN_MESSAGE,
                     JOptionPane.OK_CANCEL_OPTION, null, options, options[0]);
    setContentPane(optionPane);
    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
    addWindowListener(new JDialogWindowAdapter(this));
    optionPane.addPropertyChangeListener(this);
  }

  public void propertyChange(PropertyChangeEvent e) {
    if (isVisible() && (e.getSource() == optionPane) &&
        (JOptionPane.VALUE_PROPERTY.equals(e.getPropertyName()))) {
      Object value = optionPane.getValue();

      if (value == JOptionPane.UNINITIALIZED_VALUE) {
        return;
      }

      //Reset the JOptionPane's value.
      //If you don't do this, then if the user
      //presses the same button next time, no
      //property change event will be fired.
      optionPane.setValue(JOptionPane.UNINITIALIZED_VALUE);
      if (value.equals("Ok")) {
        copyAndMoveTriangle();
      }
      else { //user closed dialog or clicked cancel
        constructionCancelled();
        clearAndHide();
      }
    }
  }

  public void actionPerformed(ActionEvent e) {
    if (initialized && (e.getActionCommand().equalsIgnoreCase("Triangle"))) {
      Triangle T1 = (Triangle)(cTriangle.getSelectedItem());
      Line[] sides = T1.getSides();
      cPickSide.removeAllItems();
      for (int i = 0; i<sides.length; i++)
        cPickSide.addItem(sides[i]);
      lPickSide.setVisible(true);
      cPickSide.setVisible(true);
    }
    if (initialized && ((e.getActionCommand().equalsIgnoreCase("Old Side")) ||
                        (e.getActionCommand().equalsIgnoreCase("New Side")))) {
      Line selectedSide = (Line)(cPickSide.getSelectedItem());
      Line newSide = (Line)(cNewSide.getSelectedItem());
      lOrientation.setText("<HTML><CENTER>Select final position of<p>" +
                           selectedSide.getStart() + " of " + selectedSide +
                           "<p>after move</CENTER></HTML>");
      cSelectOrientation.removeAllItems();
      cSelectOrientation.addItem(newSide.getStart());
      cSelectOrientation.addItem(newSide.getEnd());
      pOrientation.setVisible(true);
      lOrientation.setVisible(true);
      cSelectOrientation.setVisible(true);
    }
  }

  private void copyAndMoveTriangle() {
    Triangle tri = (Triangle)(cTriangle.getSelectedItem());
    Line selectedSide = (Line)(cPickSide.getSelectedItem());
    Line newSide = (Line)(cNewSide.getSelectedItem());
    boolean orientation = (cSelectOrientation.getSelectedIndex() == 0);
    ConstructionStep step = new ConstructionStep(this, new Object[] {tri,
              selectedSide, newSide, new Boolean(orientation)}, COPY_MOVE);
    doConstruction(step);
  }

  public void doConstruction(ConstructionStep step) {
    if (step.getConstructionType() == COPY_MOVE) {
      Triangle tri = (Triangle)step.getInputs()[0];
      Line selectedSide = (Line)step.getInputs()[1];
      Line newSide = (Line)step.getInputs()[2];
      boolean orientation = ((Boolean)step.getInputs()[3]).booleanValue();
      if (Math.abs(selectedSide.getLength()-newSide.getLength()) < Point.LEAST_COUNT) {
        Point[] vertices = tri.getVertices();
        Point ptOppSelSide = new Point();
        if (vertices[0].canIntersect(selectedSide))
          if (vertices[1].canIntersect(selectedSide))
            ptOppSelSide.setCoordinates(vertices[2].getX(), vertices[2].getY());
          else
            ptOppSelSide.setCoordinates(vertices[1].getX(), vertices[1].getY());
        else
          ptOppSelSide.setCoordinates(vertices[0].getX(), vertices[0].getY());

        Line line1 = (orientation)?
                  (new Line(selectedSide.getStart(), newSide.getStart())):
                  (new Line(selectedSide.getStart(), newSide.getEnd()));
        Line line2 = (orientation)?
                  (new Line(selectedSide.getEnd(), newSide.getEnd())):
                  (new Line(selectedSide.getEnd(), newSide.getStart()));
        Point centreOfRotation;
        Angle angleOfRotation;
        if (line1.getLength() < Point.LEAST_COUNT) {
          centreOfRotation = new Point(line1.getStart().getX(),line1.getStart().getY());
          angleOfRotation = (new Line(centreOfRotation, line2.getEnd())).getSlope().
                    sub((new Line(centreOfRotation, line2.getStart())).getSlope());
        }
        else if (line2.getLength() < Point.LEAST_COUNT) {
          centreOfRotation = new Point(line2.getStart().getX(),line2.getStart().getY());
          angleOfRotation = (new Line(centreOfRotation, line1.getEnd())).getSlope().
                    sub((new Line(centreOfRotation, line1.getStart())).getSlope());
        }
        else {
          Line perpLine1 = new Line(line1.midPoint(),line1.getSlope().
                              add(new Angle(Math.PI/2)),1);
          Line perpLine2 = new Line(line2.midPoint(),line2.getSlope().
                              add(new Angle(Math.PI/2)),1);
          if (perpLine1.canIntersect(perpLine2)) {
            centreOfRotation = perpLine1.intersect(perpLine2)[0];
            angleOfRotation = (new Line(centreOfRotation, line1.getEnd())).getSlope().
                    sub((new Line(centreOfRotation, line1.getStart())).getSlope());
          }
          else {
            Point translation = new Point(
                      line1.getEnd().getX() - line1.getStart().getX(),
                      line1.getEnd().getY() - line1.getStart().getY());
            ptOppSelSide.move(translation, new Angle(0), new Point());
            Triangle newTriangle = new Triangle(ptOppSelSide, newSide);
            newTriangle.addToObjects(objects);
            clearAndHide();
            step.setOutputs(new Object[]{ptOppSelSide, newTriangle.getSides()[1],
                        newTriangle.getSides()[2], newTriangle});
            fireUndoableEditUpdate(new UndoableEditEvent(this, step));
            return;
          }
        }
        ptOppSelSide.move(new Point(), angleOfRotation, centreOfRotation);
        Triangle newTriangle = new Triangle(ptOppSelSide, newSide);
        newTriangle.addToObjects(objects);
        clearAndHide();
        step.setOutputs(new Object[]{ptOppSelSide, newTriangle.getSides()[1],
                    newTriangle.getSides()[2], newTriangle});
        fireUndoableEditUpdate(new UndoableEditEvent(this, step));
      }
      else {
        JOptionPane.showMessageDialog(this, "Lengths of old & new sides must be equal",
                        "Try Again", JOptionPane.ERROR_MESSAGE);
        initDialog();
      }
    }
    else
      System.err.println("Bad construction type");
  }

  public void undoConstruction(ConstructionStep step) {
    if (step.getConstructionType() == COPY_MOVE) {
      ((GeometricalObject)step.getOutputs()[0]).removeFromObjects(objects);
      for (int i = 0; i<objects.size(); i++)
        objects.elementAt(i).setNumber(i+1);
    }
    else
      System.err.println("Bad construction type");
  }

  public void redoConstruction(ConstructionStep step) {
    if (step.getConstructionType() == COPY_MOVE) {
      for (int i = 0; i<step.getOutputs().length; i++)
      ((GeometricalObject)step.getOutputs()[i]).addToObjects(objects);
    }
    else
      System.err.println("Bad construction type");
  }

  public void initDialog() {
    initialized = false;
    showTriangles();
    lPickSide.setVisible(false);
    cPickSide.setVisible(false);
    pOrientation.setVisible(false);
    lOrientation.setVisible(false);
    cSelectOrientation.setVisible(false);
    initialized = true;
    setLocationRelativeTo(null);
    setVisible(true);
  }

  private void showTriangles() {
    cTriangle.removeAllItems();
    cPickSide.removeAllItems();
    cNewSide.removeAllItems();
    cSelectOrientation.removeAllItems();
    lOrientation.setText("");
    for (int i = (objects.size() - 1); i>=0; i--) {
      GeometricalObject o = objects.elementAt(i);
      if (o.getType() == Line.TYPE)
        cNewSide.addItem(o);
      if (o.getType() == Triangle.TYPE)
        cTriangle.addItem(o);
    }
  }

  public void clearAndHide() {
    dispose();
    initialized = false;
  }

  public String getPresentationName(ConstructionStep step) {
    if (step.getConstructionType() == COPY_MOVE)
      return ("Copy & Move " + step.getInputs()[0]);
    else {
      System.err.println("Bad construction type");
      return "";
    }
  }

  public String getDisplayName(ConstructionStep step) {
    if (step.getConstructionType() == COPY_MOVE) {
      String displayName = "Copy " + step.getInputs()[0] + " and move onto " +
         step.getInputs()[2]+", aligning "+((Line)step.getInputs()[1]).getStart()+
         " of "+step.getInputs()[1]+" with ";
      displayName = (((Boolean)step.getInputs()[3]).booleanValue())?
                      (displayName + ((Line)step.getInputs()[2]).getStart()):
                      (displayName + ((Line)step.getInputs()[2]).getEnd());
      displayName +=  " - Output: ";
      for(int i = 0; i < step.getOutputs().length - 1; i++)
        displayName += step.getOutputs()[i] + ", ";
      displayName += step.getOutputs()[step.getOutputs().length - 1];
      return displayName;
    }
    else {
      System.err.println("Bad construction type");
      return "";
    }
  }

}
TOP

Related Classes of cranks.ui.CopyMoveTriangle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.