import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;

import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.Color;

import java.util.Vector;

// Schalter Event
import java.awt.event.*;


import java.awt.*;  // Font

import java.util.Collections; // sortieren



// Tabelle mit einer Klasse
// manuelle Sortierung
// automatische Sortierung
// Doppelklick liefert Dialogfenster
// Behebt das Problem der internen Sortierung

public class TabelleSortierung extends JFrame {

  JTable tabelle;
  Vector liste;
  JButton BnNr;
  JButton BnName;
  JButton BnMatrnr;

  public TabelleSortierung() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocation(100,100);
    this.setSize(550, 450);
    this.setTitle("Tabelle Vorlesung");
    liste = new Vector();
    setGUI();
    setToolBar();
  }


    private void setGUI() {

        setdata();
        tabelle = createTable();
        tabelle.setFont( new Font("Arial", Font.PLAIN,24));

        JTableHeader th = tabelle.getTableHeader();
        th.setFont( new Font("Arial", Font.BOLD,24));

        tabelle.setRowHeight(26);

        // Finish setting up the table.
        JScrollPane scrollpane = new JScrollPane(tabelle);
      	scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED));

        scrollpane.setPreferredSize(new Dimension(430, 200));
        this.getContentPane().add(scrollpane, BorderLayout.CENTER);

        tabelle.addMouseListener(
              new java.awt.event.MouseAdapter() {

          public void mouseClicked(MouseEvent e) {
            tabelle_mouseClicked(e);
          }
        });
    }  // setGUI

  private void  setToolBar() {
    JToolBar  toolBar = new JToolBar();

    BnNr = new JButton("Nr");
    BnNr.setFont( new Font("Arial", Font.BOLD,28));
    BnNr.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
         Bn_Click(e);
      }
    });
    toolBar.add(BnNr);


    BnName = new JButton("Name");
    BnName.setFont( new Font("Arial", Font.BOLD,28));
    BnName.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
         Bn_Click(e);
      }
    });
    toolBar.add(BnName);


    BnMatrnr = new JButton("Matrnr");
    BnMatrnr.setFont( new Font("Arial", Font.BOLD,28));
    BnMatrnr.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
         Bn_Click(e);
      }
    });
    toolBar.add(BnMatrnr);

    this.getContentPane().add(toolBar, BorderLayout.NORTH);
  }

  private void Bn_Click(ActionEvent e) {
    if (e.getSource() == BnNr )
      Sort_click(0);
    if (e.getSource() == BnName )
      Sort_click(1);
    if (e.getSource() == BnMatrnr )
      Sort_click(2);
  }

  // createTable
  public JTable createTable() {
    // Create a model of the data.
        TableModel dataModel = new AbstractTableModel() {
            // These methods always need to be implemented.
            public int getColumnCount() {
              return 4;
            }
            public int getRowCount() {
              return liste.size();
            }

             // Spalte 0, Nr, zeigt den echten Index in der Liste
            public Object getValueAt(int row, int col) {
              CData data = (CData) liste.elementAt(row);
              switch (col) {
                case 0: return Integer.toString(row);  
                case 1: return data.getNr();
                case 2: return data.getName();
                case 3: return data.getMatrNummer();
                default: return "xxxxxxx";
              }
            }

            public String getColumnName(int column) {
              switch (column) {
                case 0: return "Nr";
                case 1: return "Phys. Nr";
                case 2: return "Name";
                case 3: return "Matrnr";
                default: return "xxxxxxx";
              }
            }

            public Class getColumnClass(int c) {
              return getValueAt(0, c).getClass();
            }
            public boolean isCellEditable(int row, int col) {
              return false;  // Dialog
            }

            public void setValueAt(Object aValue, int row, int column) {
              CData data = (CData) liste.elementAt(row);
              switch( column ) {
                case 2: data.setName( (String) aValue );
                        break;
                case 3: String sNumber = (String) aValue;
                        int number = Integer.parseInt(sNumber);
                        data.setMatrNummer( number );
                        break;
              }
            }
         };

     JTable table = new JTable(dataModel);
     table.setAutoCreateRowSorter(true);
     return table;
  } // createTable



   private void Sort_click(int nr) {
      if (nr>=0) {
        if (CData.sorttyp==nr) {
          CData.Sortfactor=(-1)*CData.Sortfactor;
        }
        else {
          CData.sorttyp =nr;
          CData.Sortfactor=+1;
        }

        // Aufruf der statische Methode
        Collections.sort( liste );
        tabelle.updateUI();
        // testausgabe
        for (int i=0; i<liste.size(); i++) {
          CData d = (CData) liste.elementAt(i);
          System.out.println(d);
        }
      }
   }

      void tabelle_mouseClicked(MouseEvent e) {
        if (  getButton(e) == 1) {
           if ( e.getClickCount() == 2) {
            editTabellenEintrag();
           }
         }
      }


      void editTabellenEintrag() {
        int row= tabelle.getSelectedRow();
            // hole die erste Zelle in der aktuellen Zeile
            // Problem Splaten verschieben ?
        String sNr = (String) tabelle.getValueAt( row, 0 ) ;
        System.out.println("sNr: "+sNr);
        int row2 = ((Integer) Integer.parseInt(sNr)).intValue();
        CData data = (CData) liste.elementAt(row2);
        // Aufruf JDialog
        FrameDialog d = new FrameDialog(this, data);
        if ( d.result ) {
          // Ok wurde gedrückt, daten übernehmen
          System.out.println("Ok wurde gedrückt, daten übernehmen");
          data.setName( d.getName()  );
          data.setMatrNummer( d.getMatrnr()  );
          tabelle.updateUI();
        }
      }  // edit Tabelle
      

     // Eintragen
    private void setdata() {
      CData data;

      data = new CData(5, "Hold", 6614);
        liste.add(data);

      data = new CData(6, "Boll", 6613);
        liste.add(data);

      data = new CData(2, "Meyer", 4712);
        liste.add(data);

      data = new CData(1, "Mueller", 4722);
        liste.add(data);


      data = new CData(3, "Schmidt", 4714);
        liste.add(data);

      data = new CData(4, "Brian", 6714);
        liste.add(data);

      data = new CData(9, "Braeunl", 1623);
        liste.add(data);
      data = new CData(10, "Doug", 2613);
        liste.add(data);
      data = new CData(11, "Rauber", 1612);
        liste.add(data);
      data = new CData(12, "Walrath", 1613);
        liste.add(data);

      data = new CData(7, "Seneca", 6314);
        liste.add(data);

      data = new CData(8, "Kredel", 1613);
        liste.add(data);


      data = new CData(13, "Weber", 1613);
        liste.add(data);

    } // setData


    public int getButton(MouseEvent e) {
        int mode = e.getModifiers();
        if ((mode & e.BUTTON2_MASK) > 0) {
            return 2;
        }
        if ((mode & e.BUTTON3_MASK) > 0) {
            return 3;
        }
        return 1;
    } // getButton



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

}


//  Speichert die Daten
class CData implements  Comparable {
    public static int sorttyp=0;
    public static int Sortfactor=+1;

    private int _Nr;
    private String _Name;
    private int _MatrNummer;

    public CData() {
       this(0,"leer",0);
    }


    // speichert die Parameter
    // in den globalen Variablen
    public CData( int Nr, String Name, int MatrNummer) {
      _Nr = Nr;
      _Name = Name;
      _MatrNummer = MatrNummer;
    }


  public int compareTo(Object obj) {
     CData myD;
     myD = (CData) obj;
     //System.out.println("   "+toString()+"  "+myD);
     int result=0;
     // Integer.compareTo
     switch (sorttyp) {
      case 0: if (_Nr < myD._Nr )
                 result=-1;
               else {
                 if (_Nr > myD._Nr )
                   result=1;
                 else
                   result=0;
               }
              break;
      case 1: result=_Name.compareToIgnoreCase(myD._Name );
              break;
      case 2: if (_MatrNummer < myD._MatrNummer )
                 result=-1;
               else {
                 if (_MatrNummer > myD._MatrNummer )
                   result=1;
                 else
                   result=0;
               }
              break;
      default: result=0;
     }
     // Variable Sortfactor bestimmt
     // auf- oder absteigend
     return result*Sortfactor;

   }

   public String toString() {
     return "  Nr: "+_Nr+"    Name: "+_Name+"     Matrnr: "+_MatrNummer;
   }

   public String getNr() {
     return Integer.toString(_Nr);
   }

   public String getName() {
     return _Name;
   }
   public void setName(String Name) {
     _Name = Name;
   }


   public String getMatrNummer() {
     return Integer.toString(_MatrNummer);
   }
   public void setMatrNummer(int MatrNummer) {
     _MatrNummer = MatrNummer;
   }

}  // CData





// modaler Dialog
// zur Eingabe der Daten
class FrameDialog extends JDialog {
    private JLabel label1;
    private JLabel label2;

    private JTextField Name;
    private JSpinner spMatrnr;


    // Variablen, die den Rückgabewert speichern
    private String sName;
    private int iMatrnr;

    public boolean result;  // gibt an, ob Ok oder Esc gedrückt wurde

  public FrameDialog( Frame parent, CData data) {
   super(parent);
   setModal(true);
   setTitle("Bearbeiten eines Datensatzes");
   setSize(350,250);
   result=false;
   setGUI(data);

   setVisible(true);

  }

  private void setGUI(CData data) {
        this.getContentPane().setLayout( new GridBagLayout() );

        label1= new JLabel("Name");
        label2= new JLabel("MatrNr");

        Name= new JTextField();
                                          //Aktueller Wert, Min, Max, Increment
        spMatrnr = new JSpinner( new SpinnerNumberModel(1,1, 10000, 1)   );

        Name.setText( data.getName() );
        // Umwandeln der int-Zahl in eine Integer (Wrapper-Klasse)
        spMatrnr.setValue(  new Integer( data.getMatrNummer() ) );

       label1.setFont( new Font("Arial", Font.BOLD,18)  );
       label2.setFont( new Font("Arial", Font.BOLD,18)  );

       Name.setFont( new Font("Arial", Font.BOLD,18)  );
       spMatrnr.setFont( new Font("Arial", Font.BOLD,18)  );

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

      this.getContentPane().add(Name,
           new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            new Insets(30,40,0,20), 00, 0));
      // -------------------------------

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

      this.getContentPane().add(spMatrnr,
           new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0,
            GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
            new Insets(30,40,0,20), 00, 0));
      // -------------------------------

        JPanel pn = new JPanel();
        pn.setLayout( new FlowLayout() );


        JButton BnOk = new JButton("Ok");
        BnOk.setFont( new Font("Arial", Font.BOLD,18)  );
        pn.add( BnOk);

        JButton BnESC = new JButton("Abbruch");
        BnESC.setFont( new Font("Arial", Font.BOLD,18)  );
        pn.add( BnESC);

        this.getContentPane().add(pn,   new GridBagConstraints(0, 4, 2, 1, 0.0, 0.0
            ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(25,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();
        }
      });


  }

  void BnESC_click() {
    result=false;
    setVisible(false);
    dispose();
  }

  void BnOk_click() {
    // check der Daten
    String s = Name.getText().trim();  // Leerstellen links rechts löschen
    if ( s.length()<2) {
      CBasis.Error("Eingabe","Bitte eine gültige Eingabe im Namen");
      Name.requestFocus();  // erhaelt Fokus
      return;
    }
    sName = s;


    Integer I = (Integer) spMatrnr.getValue();
    int matrnr = I.intValue();
    if ( matrnr <= 0) {
      CBasis.Error("Eingabe","Keine gültige Eingabe in der MatrNr");
      spMatrnr.requestFocus();  // erhaelt Fokus
      return;
    }
    iMatrnr = matrnr;
    result=true;
    // Speichern in lokale variable
    setVisible(false);
    dispose();
  }

  // Rückgabe-Methoden
  public String getName() {
    return sName;
  }

  public int getMatrnr() {
    return iMatrnr;
  }

}  // FrameDialog



class CBasis {




    /**
    * description: Zeigt eine Fehlermeldung an   
    * @see Message, Yes-No, Yes-No-Esc, Ok-Esc
    *
    * @version     1.0  07.07.2002
    * @author      Michael Wilhelm HS Harz, FB AI
    * @param String sTitle, String sMessage
    * @return keinen
    * @exception keine
    */
  public static void Error( String sTitle, String sMessage) {
    JOptionPane.showConfirmDialog(null,sMessage,sTitle,
      JOptionPane.DEFAULT_OPTION,
      JOptionPane.ERROR_MESSAGE);  // Symbol
    /*  Optionen der Schalter:
         DEFAULT_OPTION    Ok
         YES_NO_OPTION
         YES_NO_CANCEL_OPTION
         OK_CANCEL_OPTION
     */
     /*  Symbole:
      ERROR_MESSAGE
      INFORMATION_MESSAGE
      WARNING_MESSAGE
      QUESTION_MESSAGE
      PLAIN_MESSAGE
     */

  } // Error

    /**
    * description: Zeigt eine Nachricht an   
    * @see Message, Yes-No, Yes-No-Esc, Ok-Esc
    *
    * @version     1.0  07.07.2002
    * @author      Michael Wilhelm HS Harz, FB AI
    * @param String sTitle, String sMessage
    * @return keinen
    * @exception keine
    */
  public static void Message( String sTitle, String sMessage) {
    JOptionPane.showConfirmDialog(null,sMessage,sTitle,
      JOptionPane.DEFAULT_OPTION,
      JOptionPane.INFORMATION_MESSAGE);  // Symbol
    /*  Optionen der Schalter:
         DEFAULT_OPTION    Ok
         YES_NO_OPTION
         YES_NO_CANCEL_OPTION
         OK_CANCEL_OPTION
     */
     /*  Symbole:
      ERROR_MESSAGE
      INFORMATION_MESSAGE
      WARNING_MESSAGE
      QUESTION_MESSAGE
      PLAIN_MESSAGE
     */

  } // Message

    /**
    * description: Zeigt einen Ja-Nein-Dialog   
    * @see Message, Error, Yes-No-Esc, Ok-Esc
    *
    * @version     1.0  07.07.2002
    * @author      Michael Wilhelm HS Harz, FB AI
    * @param String sTitle, String sMessage
    * @return boolean
    * @exception keine
    */
  public static boolean YesNo( String sTitle, String sMessage) {
    int retcode;
    retcode = JOptionPane.showConfirmDialog(null,sMessage,sTitle,
      JOptionPane.YES_NO_OPTION,
      JOptionPane.QUESTION_MESSAGE);  // Symbol

    switch (retcode) {
       case JOptionPane.YES_OPTION:
         // ja, Änderungen speichern
         return true;
       case JOptionPane.NO_OPTION:
         return false;
       case JOptionPane.CANCEL_OPTION:
       default:
         // abbrechen
         return false;
    }
  } // YesNo



    /**
    * description: Eingabe eines Strings
    * @see getInput
    *
    * @version     1.0  07.07.2002
    * @author      Michael Wilhelm HS Harz, FB AI
    * @param String sTitle, String sMessage
    * @return String
    * @exception keine
    */
  public static String getInput( String sTitle, String sMessage) {
    return JOptionPane.showInputDialog(null, sTitle, sMessage, 1);
  } // getInput



    /**
    * description: Eingabe eines Strings mit Vorgabe
    * @see getInput
    *
    * @version     1.0  07.07.2002
    * @author      Michael Wilhelm HS Harz, FB AI
    * @param String sTitle, String sMessage, String sInput
    * @return String
    * @exception keine
    */
  public static String getInput( String sTitle, String sMessage, String sInput) {
    return (String) JOptionPane.showInputDialog( null,sMessage, sTitle, JOptionPane.PLAIN_MESSAGE,
       null, null, sInput);
  } // getInput

  





}  // CBasis

