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

// Beispiel mit der Transform-Methode
// Möglichkeiten: Shearing
// Verschoben wird ein Path
// Ein Path hat mehrere Grafikelemente in einem Paket (Path) !


import java.awt.geom.*;

public class Dialog_Transform3_2D extends JFrame {


  JLabel LShear = new JLabel("Zerrung");
  JCheckBox BoolShear = new JCheckBox("BoolShearing");
  JLabel LX = new JLabel("X:");
  JTextField TX = new JTextField("-0.5");
  JLabel LY = new JLabel("Y:");
  JTextField TY = new JTextField("0");

  JButton BnDraw= new JButton("Draw");

  CCanvas _canvas = new CCanvas();


  public Dialog_Transform3_2D(String caption) {
    setTitle(caption);
    setGUI();
  }

  private void setGUI() {
    this.getContentPane().setLayout( new BorderLayout() );

    JPanel pnTop = new JPanel();
    pnTop.setBackground( Color.lightGray );
    pnTop.setLayout( new GridBagLayout() );

    this.getContentPane().add(pnTop, BorderLayout.NORTH);

    pnTop.add(LShear,
        new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.NONE,
            new Insets(20,20,20,20), 0, 0));


    pnTop.add(BoolShear,
        new GridBagConstraints(1, 0, 1, 1, 100.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.NONE,
            new Insets(20,20,20,20), 0, 0));

    pnTop.add(LX,
        new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.NONE,
            new Insets(20,20,20,20), 0, 0));

    pnTop.add(TX,
        new GridBagConstraints(3, 0, 1, 1, 100.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.HORIZONTAL,
            new Insets(20,20,20,20), 0, 0));

    pnTop.add(LY,
        new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.NONE,
            new Insets(20,20,20,20), 0, 0));

    pnTop.add(TY,
        new GridBagConstraints(5, 0, 1, 1, 100.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.HORIZONTAL,
            new Insets(20,20,20,20), 0, 0));


   // ------------------------------
    JPanel panelBn = new JPanel();
    panelBn.setLayout( new GridBagLayout() );
    panelBn.add(BnDraw);
    pnTop.add(panelBn,
        new GridBagConstraints(0, 3, 6, 1, 100.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.HORIZONTAL,
            new Insets(20,20,20,20), 0, 0));



    BnDraw.addActionListener(new java.awt.event.ActionListener() {

      public void actionPerformed(ActionEvent e) {
        BnDraw_Click();
      }
    });


    this.getContentPane().add(_canvas, BorderLayout.CENTER);
  }

  private void BnDraw_Click() {
    _canvas.bShear = BoolShear.isSelected();
    if ( CBasis.DVal(TX.getText() ) ) {
      System.out.println("x: "+CBasis.getDValResult());
      _canvas.Tx =  CBasis.getDValResult();
    }
    if ( CBasis.DVal(TY.getText() ) ) {
      System.out.println("y: "+CBasis.getDValResult());
      _canvas.Ty =  CBasis.getDValResult();
    }

    _canvas.updateUI();

  }

    // dient zum Beenden
  protected void processWindowEvent(WindowEvent e) {
    super.processWindowEvent(e);
    if(e.getID() == WindowEvent.WINDOW_CLOSING) {
      System.exit(0);
    }
  }



    public static void main(String args[]) {
      Dialog_Transform3_2D f = new Dialog_Transform3_2D("Dialog_Transform3_2D");
     	f.setSize(600,600);
    	f.setVisible(true);
    }


}




class CCanvas extends JPanel {

  public boolean bShear=false;
  public double Tx=-5.0;
  public double Ty=0.0;


  public void paint (Graphics g) {
    GeneralPath path = new GeneralPath();

    // holt die Abmessungen des Canvas
    Rectangle r = new Rectangle();  // double wert
    g.getClipBounds(r);
        // Löschen des Bildschirms
    g.setColor(Color.white);
    g.fillRect(0,0, (int)r.getWidth(), (int)r.getHeight() );

    Graphics2D g2 = (Graphics2D) g;

    g2.setStroke(  new BasicStroke(3) );
    g2.setPaint( Color.black );

    // setzt den Nullpunkt neu
    AffineTransform at = AffineTransform.getTranslateInstance(10.0,11.0);
    g2.transform(at);

    int ImageH = (int) r.getHeight();
    int ImageW = (int) r.getWidth();

    int top = (int) (r.getHeight()/2.0);
    int left = (int) (r.getWidth()/4.0);
    int width = (int) (r.getWidth()/6.0);
    int height = (int) (r.getHeight()/4.0);


    // Rectangle2D rect = new Rectangle2D.Double(left,top,width,height);
    // Viereck zeichnen
    path.moveTo(left+50, top);
    path.lineTo(width+20, top);
    path.lineTo(width+20, top+height);
    path.lineTo(left+50, top+height);
    path.lineTo(left+50, top);


    path.moveTo(50, 50);
    path.lineTo(50, ImageH-50);
    path.moveTo(50, top-50);
    path.lineTo(left+100, top-50);


    g2.setPaint( Color.blue );
    g2.draw(path); // Rechteck zeichnen

    float [] dashsT = {30.0f, 5.0f};  // dash
    g2.setStroke( new BasicStroke(3,  BasicStroke.CAP_BUTT,
    BasicStroke.JOIN_ROUND, 1.0f, dashsT, 0.0f ) );
    g2.draw(path);
    if (bShear) {
       g2.setPaint( Color.red );
       // neues Bild verschieben
       // x = Breite / 2
       AffineTransform at2 =
        AffineTransform.getTranslateInstance(ImageW >> 1,0);
       at2.shear(Tx, Ty);
       g2.transform( at2 );
       g2.draw(path);

    }

  }

}




class CBasis {
    public static final int C_LEER = 1;
    public static final int C_KEINEZAHL = 2;
    public static final int C_ZUKLEIN = 3;
    public static final int C_ZUGROSS = 4;

      // Konstanten für den Error Code als String
    public static final String SZ_LEER = "Leerer Text";
    public static final String SZ_KEINEZAHL = "Konvertierung schlug fehl";
    public static final String SZ_ZUKLEIN = "Für den Bereich zu klein";
    public static final String SZ_ZUGROSS = "Für den Bereich zu groß";

    private static int intVal;          // speichert das Ergebnis
    private static long longVal;        // speichert das Ergebnis
    private static double dblVal;       // speichert das Ergebnis

    private static int ValError = 0;   // speichert den Konvertierungfehler


    /**
    * description: überprüft, ob der String eine Integerzahl ist
    * Verwendet eine interne Variable zum Speichern des Wertes
    * @see DVal, LVal, getErrorCode
    *
    * @version     1.0  07.07.2002
    * @author      Michael Wilhelm HS Harz, FB AI
    * @param String sText
    * @return boolean
    * @exception keine
    */
    public static boolean IVal(String sText) {
        // erläuterung von iIVal = Integer.valueOf(szText).intValue();
        boolean result = true;
        String s;
        s = new String(sText); // neues Objekt
        s.trim();
        if (s.length() == 0) {
            ValError = C_LEER;
            intVal = 0;
            result = false;
        }
        else {
            try {
                intVal = Integer.valueOf(sText).intValue();
                ValError = 0;
            }
            catch (NumberFormatException e) {
                // Check ob die "Zahl" für den Integerbereich zu klein oder zu groß
                // System.err.println(e);
                try {
                    dblVal = Double.valueOf(sText).doubleValue();
                    if ( dblVal<Integer.MIN_VALUE) {
                      ValError = C_ZUKLEIN;
                    }
                    if ( dblVal>Integer.MAX_VALUE) {
                      ValError = C_ZUGROSS;
                    }
                }
                catch (NumberFormatException e2) {
                    // Hier könnte noch eine genauere Abfrage integriert werde,
                    // ob die Zahl nicht zu groß für den int-Bereich ist
                    // System.err.println(e);
                    ValError = C_KEINEZAHL;
                    intVal = 0;
                    result = false;
                }
                intVal = 0;
                result = false;
            }
        }
        return result;
    } // IVal


    /**
    * description: gibt den konvertierten Wert aus
    * @see IVal, DVal, LVal, getErrorCode
    *
    * @version     1.0  07.07.2002
    * @author Michael Wilhelm HS Harz, FB AI
    * @param String sText
    * @return String
    * @exception keine
    * @use gibt den Wert der Konvertierung aus
    * @see #setIValError
    * @see #setLValError
    * @see #setDValError
    */
    public static int getIValResult() {
       return intVal;
    }



    /**
    * DVal
    * description: überprüft, ob der String eine Double-Zahl ist
    * Verwendet eine interne Variable zum Speichern des Wertes
    * @see IVal, LVal, getErrorCode
    *
    * @version     1.0  07.07.2002
    * @author      Michael Wilhelm HS Harz, FB AI
    * @param String sText
    * @return boolean
    * @exception keine
    */
    public static boolean DVal(String sText) {
        // erläuterung von iIVal = Integer.valueOf(szText).intValue();
        boolean result = true;
        String s;
        s = new String(sText); // neues Objekt
        s.trim();
        if (s.length() == 0) {
            ValError = C_LEER;
            dblVal = 0;
            result = false;
        }
        else {
            try {
                sText = sText.replace(',','.');
                dblVal = Double.valueOf(sText).doubleValue();
                ValError = 0;
            }
            catch (NumberFormatException e) {
                ValError = C_KEINEZAHL;
                dblVal = 0;
                result = false;
            }
        }
        return result;
    } // DVal


    /**
    * description: gibt den konvertierten Wert aus
    * @see IVal, DVal, LVal, getErrorCode
    *
    * @version     1.0  07.07.2002
    * @author Michael Wilhelm HS Harz, FB AI
    * @param keinen
    * @return double
    * @exception keine
    * @use gibt den Wert der Konvertierung aus
    * @see #getIValError
    * @see #setLValError
    * @see #setDValError
    */
    public static double getDValResult() {
       return dblVal;
    }


}

    
