//Titel:            JTextField mit Listener
//Version:          2.0, 06.11.2010
//Copyright:        HS-Harz, FB AI
//Autor:            Dipl.-Inf.(TU) Dipl.-Ing.(FH) Michael Wilhelm
//Beschreibung:     Beispiel eines abgeleiteten JTextField mit Listener

// ein JTextField wird mit einem Listener abgeleitet
// stammt aus dem Pattern_MVC3

// hier werden bei beiden Editorfelder die onChange-Events abgefragt

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


// DocumentListener
import javax.swing.event.*;

import javax.swing.text.*;  // Document


public class JTextFieldDocListenerTest4 extends JFrame implements IJTextFieldDocListener {

  JLabel jLabel1 = new JLabel("A");
  JTextFieldDblDocListener TName1 = new JTextFieldDblDocListener("123");
  JLabel jLabel2 = new JLabel("B");
  JTextFieldDblDocListener TName2 = new JTextFieldDblDocListener("42");
  JLabel jLabel3 = new JLabel("Ergebnis in Ok");
  JTextField TOk = new JTextField("");
  JLabel jLabelOnChange = new JLabel("onChange");

  JButton BnOk = new JButton("Ok");
  JButton BnEsc = new JButton("Abbruch");

  public JTextFieldDocListenerTest4() {
    setSize(650, 330);
    setTitle("Test eines JTextFieldDblDocListenerTest4");
    setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    setGUI();
  }

  private void setGUI() {
    setLayout( new GridBagLayout() );

    jLabel1.setFont( new Font("Arial", Font.BOLD,18)  );
    TName1.setFont( new Font("Arial", Font.BOLD,18)  );
    jLabel2.setFont( new Font("Arial", Font.BOLD,18)  );
    TName2.setFont( new Font("Arial", Font.BOLD,18)  );
    jLabel3.setFont( new Font("Arial", Font.BOLD,18)  );
    TOk.setFont( new Font("Arial", Font.BOLD,14)  );
    jLabelOnChange.setFont( new Font("Arial", Font.BOLD,18)  );

    TName1.addListener(this);  // hier werden beide Event auf onChange laufen
    TName2.addListener(this);
    BnOk.setFont( new Font("Arial", Font.BOLD,18)  );
    BnEsc.setFont( new Font("Arial", Font.BOLD,18)  );
    BnOk.setPreferredSize( BnEsc.getPreferredSize() );

    this.getContentPane().add(jLabel1,
         new GridBagConstraints(
             0, 0, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.NONE,
            new Insets(10,20,20,0), 0, 0));

    this.getContentPane().add(TName1,
        new GridBagConstraints(
               1, 0, 1, 1, 80.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.HORIZONTAL,
            new Insets(10,20,20,20), 0, 0));


    this.getContentPane().add(jLabel2,
         new GridBagConstraints(
             0, 1, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.NONE,
            new Insets(0,20,20,0), 0, 0));

    this.getContentPane().add(TName2,
        new GridBagConstraints(
             1, 1, 1, 1, 100.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            new Insets(0,20,20,20), 0, 0));

    this.getContentPane().add(jLabel3,
         new GridBagConstraints(
             0, 2, 1, 1, 0.0, 0.0
            ,GridBagConstraints.WEST,
            GridBagConstraints.NONE,
            new Insets(0,20,20,0), 0, 0));


    this.getContentPane().add(TOk,
        new GridBagConstraints(
             1, 2, 1, 1, 100.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            new Insets(0,20,20,20), 0, 0));

    this.getContentPane().add(jLabelOnChange,
        new GridBagConstraints(
             0, 3, 2, 1, 100.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            new Insets(0,20,20,20), 0, 0));

    JPanel pn = new JPanel();
    pn.add(BnOk);
    pn.add(BnEsc);
    this.getContentPane().add(pn,
           new GridBagConstraints(0, 4, 2, 1, 1.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            new Insets(0,0,0,0), 0, 0));

     BnOk.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              BnOk_Click();
            }
          });
     BnEsc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
              BnEsc_Click();
            }
          });

  } // setGUI

  public void onChange(JTextFieldDblDocListener edit) {
     if (edit.equals(TName1) ) {
       jLabelOnChange.setText("1. JTextField geändert");
     }
     if (edit.equals(TName2) ) {
       jLabelOnChange.setText("2. JTextField geändert");
     }
  }



    private void BnOk_Click() {
       String sErg;
       if (TName1.bModify)
         sErg = "TName1 wurde modifiziert";
       else
         sErg = "TName1 wurde nicht geändert";

       if (TName2.bModify)
         sErg += "   TName2 wurde modifiziert";
       else
         sErg += "   TName2 wurde nicht geändert";
       TOk.setText(sErg);
    }

    private void BnEsc_Click() {
        setVisible(false);
        System.exit(0);
    }

  public static void main(String[] args) {
    JTextFieldDocListenerTest4 frame = new JTextFieldDocListenerTest4();
    frame.setVisible(true);
 }

}  // JTextFieldDocListenerTest1

interface  IJTextFieldDocListener {
  public void onChange(JTextFieldDblDocListener edit);
}


class JTextFieldDblDocListener extends JTextField   {
   public  boolean bModify=false;
   private IJTextFieldDocListener _parent;
   private gDoubleTextDocument DoubleTextDocument;

   public JTextFieldDblDocListener() {
     super();
     init();
   }

   public JTextFieldDblDocListener(String sText) {
     super(sText);
     init();
   }

   private void init() {
     _parent = null;
    DoubleTextDocument = new gDoubleTextDocument();
    this.setDocument( DoubleTextDocument );

       // ableiten der Update-Methoden des Listeners
     this.getDocument().addDocumentListener(new DocumentListener(){
         public void changedUpdate(DocumentEvent ev) {
             Document doc = ev.getDocument();
             onChanged();
         }
         
         public void insertUpdate(DocumentEvent ev) {
             onChanged();
         }
         
         public void removeUpdate(DocumentEvent ev) {
             onChanged();
         }
     });     
    } // init

    private void onChanged() {
       bModify=true;
       if (_parent != null) {
          _parent.onChange(this);  // Uebergabe der Quelle
       }
    }

    public void addListener(IJTextFieldDocListener parent) {
      _parent = parent;
    }
    public void removeListener() {
      _parent = null;
    }

    // innere Klasse
    class gDoubleTextDocument extends PlainDocument {
    
        public gDoubleTextDocument() {
          System.out.println("           gDoubleTextDocument");
        }
    
        public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
          System.out.println("           gDoubleTextDocument: insertString");
            if (str == null) {
                return;
            }
            int n = getLength(); // alter Wert
                System.out.println("         Eingabe: "+str);
            String oldString = getText(0, getLength());
            // Parameters:
            // beginIndex - the beginning index, inclusive.
            // endIndex - the ending index, exclusive.
            String newString = oldString.substring(0, offs) + str + oldString.substring(offs);
            try {
                Double.valueOf(newString + "0"); //  hinzufügen, falls nur ein Punkt eingegeben wird
                super.insertString(offs, str, a);
            }
            catch (NumberFormatException e) {
                 System.out.println("           exception");
            }
        }
    
      public void remove(int offs, int len)  throws BadLocationException {
          System.out.println("           gDoubleTextDocument: remove: "+getText(0, getLength()) );
          String oldString = getText(0, getLength() );
    
          if (len == 0) return;
          int n = getLength();
          // Parameters:
          // beginIndex - the beginning index, inclusive.
          // endIndex - the ending index, exclusive.
          String newString = oldString.substring(0,offs) + oldString.substring(offs+len);
    
          //                           0 bis offs-1
          try {
            Double.parseDouble(newString + "0");  //
            super.remove(offs, len);
          }
          catch(NumberFormatException e) {
            // super.remove(offs, len); ??????
          }
      }
    }  // gDoubleTextDocument


}  // JTextFieldDblDocListener

