[Schmitzm-commits] r2356 - in trunk: schmitzm-core/src/main/java/de/schmitzm/swing/table schmitzm-core/src/main/resources/de/schmitzm/swing/resource/locales schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales

scm-commit at wald.intevation.org scm-commit at wald.intevation.org
Fri Jul 12 18:40:25 CEST 2013


Author: mojays
Date: 2013-07-12 18:40:25 +0200 (Fri, 12 Jul 2013)
New Revision: 2356

Added:
   trunk/schmitzm-core/src/main/java/de/schmitzm/swing/table/AbstractMutableListPanel.java
   trunk/schmitzm-core/src/main/java/de/schmitzm/swing/table/AbstractReadonlyTableModel.java
   trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/AbstractDatabaseTableMaintainencePanel.java
   trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/AbstractDatabaseTableModel.java
   trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/BasicTypeTableModel.java
   trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTable.java
   trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTablePanel.java
   trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTablesOverviewTableModel.java
Modified:
   trunk/schmitzm-core/src/main/resources/de/schmitzm/swing/resource/locales/SwingResourceBundle.properties
   trunk/schmitzm-core/src/main/resources/de/schmitzm/swing/resource/locales/SwingResourceBundle_de.properties
   trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateSessionFactory.java
   trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle.properties
   trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle_de.properties
Log:
Many hibernate stuff (GUI) generalized and moved to schmitzm-hibernate

Added: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/table/AbstractMutableListPanel.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/table/AbstractMutableListPanel.java	                        (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/table/AbstractMutableListPanel.java	2013-07-12 16:40:25 UTC (rev 2356)
@@ -0,0 +1,225 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program 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.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.swing.table;
+
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+
+import net.miginfocom.swing.MigLayout;
+import de.schmitzm.swing.JPanel;
+import de.schmitzm.swing.SwingUtil;
+
+/**
+ * Abstract panel to show a {@link JList} or {@link JTable}, which elements can
+ * be added or removed by 2 buttons (hidden when panel is in readonly mode).
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public abstract class AbstractMutableListPanel<E extends Component> extends JPanel {
+  /** Icon for "ADD" button. */
+  public static final ImageIcon ICON_RECORD_ADD = SwingUtil.createImageIconFromResourcePath("resource/icons/small/database_add.png", null);
+  /** Icon for "REMOVE" button. */
+  public static final ImageIcon ICON_RECORD_REMOVE = SwingUtil.createImageIconFromResourcePath("resource/icons/small/database_delete.png", null);
+
+  /** Holds the "readonly" property of the panel. */
+  protected boolean readonly = false;
+
+  protected JPanel buttonPanel;
+  protected ActionListener buttonActionListener;
+  protected Action addAction;
+  protected JButton addButton;
+  protected Action removeAction;
+  protected JButton removeButton; 
+  
+  protected E table;
+  
+  /**
+   * Creates a new panel.
+   */
+  protected AbstractMutableListPanel(boolean readonly, boolean initGUI) {
+    super();
+//    setLayout( new MigLayout("wrap 2","[grow][]","top") );
+    setLayout( new MigLayout("wrap 2, insets 0 0 0 0","[grow][]","top") );
+    this.readonly = readonly;
+
+    // ActionListener fuer Buttons
+    this.buttonActionListener = new ActionListener() {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+        if ( "ADD".equalsIgnoreCase(e.getActionCommand()) )
+          performAddAction();
+        if ( "REMOVE".equalsIgnoreCase(e.getActionCommand()) ) {
+          int selRowCount = getSelectedRowCount();
+          if ( selRowCount > 0 ) {
+            int ret = JOptionPane.showConfirmDialog(
+                AbstractMutableListPanel.this,
+                SwingUtil.R("AbstractMutableListPanel.action.remove.conf.mess", selRowCount),
+                SwingUtil.R("AbstractMutableListPanel.action.remove.conf.title"),
+                JOptionPane.YES_NO_OPTION,
+                JOptionPane.QUESTION_MESSAGE);
+            if ( ret == JOptionPane.YES_OPTION )
+              performRemoveAction();
+          } else {
+            JOptionPane.showMessageDialog(
+                AbstractMutableListPanel.this,
+                SwingUtil.R("AbstractMutableListPanel.action.remove.err.mess"),
+                SwingUtil.R("AbstractMutableListPanel.action.remove.conf.title"),
+                JOptionPane.ERROR_MESSAGE);
+          }
+        }
+      }
+    };
+    
+    this.table = createListComponent();
+    add(new JScrollPane(table),"growx");
+
+    this.buttonPanel = new JPanel();
+    this.buttonPanel.setLayout(new MigLayout("wrap 1","[grow]","[top]"));
+    add(buttonPanel,"");
+    
+    initButtonPanel();
+
+    if ( initGUI ) {
+      initGUI();
+    }
+  }
+
+  /**
+   * Creates new panel in read-only mode.
+   */
+  public AbstractMutableListPanel() {
+    this(false,true);
+  }
+
+  /**
+   * Initializes the GUI.
+   */
+  public void initGUI() {
+  }
+
+
+  /**
+   * Creates a new table/list instance, which will be automatically added to a
+   * {@link JScrollPane}.
+   */
+  public abstract E createListComponent();
+
+  /**
+   * Returns the number of selected items/rows in the maintained table/list.
+   */
+  public abstract int getSelectedRowCount();
+  
+  
+  /**
+   * Updates the table/list view (after data change).
+   */
+  public abstract void updateGUI();
+  
+  /**
+   * Initializes the buttons for add/remove actions.
+   */
+  protected void initButtonPanel() {
+    addAction = SwingUtil.createAction(null,
+                                       buttonActionListener,
+                                       "ADD",
+                                       SwingUtil.R("AbstractMutableListPanel.action.add"),
+                                       ICON_RECORD_ADD); 
+    removeAction = SwingUtil.createAction(null,
+                                          buttonActionListener,
+                                          "REMOVE",
+                                          SwingUtil.R("AbstractMutableListPanel.action.remove"),
+                                          ICON_RECORD_REMOVE); 
+    addButton = new JButton(addAction);
+    removeButton = new JButton(removeAction);
+    this.buttonPanel.add( addButton, "growx, height 20" );
+    this.buttonPanel.add( removeButton, "growx, height 20" );
+    updateActions();
+  }
+
+  /**
+   *  Updates the button visibility according to read-only state.
+   */
+  protected void updateActions() {
+//    if ( addButton != null )
+//      addButton.setVisible( !isReadonly() );
+//    if ( removeButton != null )
+//      removeButton.setVisible( !isReadonly() );
+    if ( isReadonly() ) {
+      buttonPanel.remove(addButton);
+      buttonPanel.remove(removeButton);
+    } else {
+      buttonPanel.add(addButton);
+      buttonPanel.add(removeButton);
+    }
+    validate();
+  }
+
+  /**
+   * Returns whether the panel is in read-only mode.
+   */
+  public boolean isReadonly() {
+    return readonly;
+  }
+  
+  /**
+   * Sets whether the panel is in read-only mode.
+   */
+  public void setReadonly(boolean readonly) {
+    this.readonly = readonly;
+    updateActions();
+  }
+  
+  /**
+   * Returns the list/table which is maintained by the panel.
+   */
+  public E getList() {
+    return this.table;
+  }
+  
+  /**
+   * Implements the action to add an item to list/table.
+   */
+  public abstract void performAddAction();
+  
+  /**
+   * Implements the action to remove an item from list/table.
+   */
+  public abstract void performRemoveAction();
+  
+}

Added: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/table/AbstractReadonlyTableModel.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/table/AbstractReadonlyTableModel.java	                        (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/table/AbstractReadonlyTableModel.java	2013-07-12 16:40:25 UTC (rev 2356)
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program 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.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.swing.table;
+
+/**
+ * {@link AbstractTableModel}, which editable state is set according
+ * to read-only flag.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public abstract class AbstractReadonlyTableModel extends AbstractTableModel {
+  /** If {@code true} liefert {@link #isCellEditable(int, int)} always
+   *  returns {@code false}. */
+  protected boolean readonly = false;
+
+  /**
+   * Creates a new table model.
+   */
+  public AbstractReadonlyTableModel(boolean readonly) {
+    super();
+    this.readonly = readonly;
+  }
+
+  /**
+   * Creates a new table model.
+   */
+  public AbstractReadonlyTableModel() {
+    this(true);
+  }
+  
+  /**
+   * Checks whether table is in read-only mode.
+   */
+  public boolean isReadonly() {
+    return readonly;
+  }
+  
+  /**
+   * Checks whether table is in read-only mode or can be edited.
+   */
+  public void setReadonly(boolean readonly) {
+    this.readonly = readonly;
+  }
+
+  /**
+   * Checks whether a cell is editable according to read-only mode.
+   * @return {@code false} if table is in read-only mode
+   */
+  @Override
+  public boolean isCellEditable(int row, int col) {
+    return !isReadonly();
+  }
+
+}

Modified: trunk/schmitzm-core/src/main/resources/de/schmitzm/swing/resource/locales/SwingResourceBundle.properties
===================================================================
--- trunk/schmitzm-core/src/main/resources/de/schmitzm/swing/resource/locales/SwingResourceBundle.properties	2013-07-12 16:36:48 UTC (rev 2355)
+++ trunk/schmitzm-core/src/main/resources/de/schmitzm/swing/resource/locales/SwingResourceBundle.properties	2013-07-12 16:40:25 UTC (rev 2356)
@@ -349,4 +349,9 @@
 ListMaintainancePanel.action.moveDown=Dn
 ListMaintainancePanel.action.moveDown.desc=Move selected elements down in list
 
+AbstractMutableListPanel.action.add=Add
+AbstractMutableListPanel.action.remove=Remove
+AbstractMutableListPanel.action.remove.conf.title=Delete...
+AbstractMutableListPanel.action.remove.conf.mess=All ${0} selected items will be deleted. Continue?
+AbstractMutableListPanel.action.remove.err.mess=No items selected!
 

Modified: trunk/schmitzm-core/src/main/resources/de/schmitzm/swing/resource/locales/SwingResourceBundle_de.properties
===================================================================
--- trunk/schmitzm-core/src/main/resources/de/schmitzm/swing/resource/locales/SwingResourceBundle_de.properties	2013-07-12 16:36:48 UTC (rev 2355)
+++ trunk/schmitzm-core/src/main/resources/de/schmitzm/swing/resource/locales/SwingResourceBundle_de.properties	2013-07-12 16:40:25 UTC (rev 2356)
@@ -320,3 +320,9 @@
 ListMaintainancePanel.action.moveUp.desc=Ausgew\u00e4hlte Elemente in der Liste nach oben/vorne verschieben
 ListMaintainancePanel.action.moveDown=Runter
 ListMaintainancePanel.action.moveDown.desc=Ausgew\u00e4hlte Elemente in der Liste nach unten/hinten verschieben
+
+AbstractMutableListPanel.action.add=Hinzufügen
+AbstractMutableListPanel.action.remove=Entfernen
+AbstractMutableListPanel.action.remove.conf.title=Löschen...
+AbstractMutableListPanel.action.remove.conf.mess=Alle ${0} ausgewählten Elemente werden gelöscht. Aktion fortsetzen?
+AbstractMutableListPanel.action.remove.err.mess=Keine Datensätze ausgewählt!

Modified: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateSessionFactory.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateSessionFactory.java	2013-07-12 16:36:48 UTC (rev 2355)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/HibernateSessionFactory.java	2013-07-12 16:40:25 UTC (rev 2356)
@@ -68,6 +68,14 @@
 	}
 	
 	/**
+	 * Returns whether application deals with multiple sessions (TRUE) or only with the
+	 * one global session (FALSE)
+	 */
+	public boolean isMultipleSessionsUsed() {
+	  return MULTIPLE_SESSIONS;
+	}
+	
+	/**
 	 * Returns the application wide instance of {@link HibernateSessionFactory}.
      * @param checkNull if {@code true} an exception is thrown if {@link #INST}
      *                  is not set yet or not connected.

Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/AbstractDatabaseTableMaintainencePanel.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/AbstractDatabaseTableMaintainencePanel.java	                        (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/AbstractDatabaseTableMaintainencePanel.java	2013-07-12 16:40:25 UTC (rev 2356)
@@ -0,0 +1,308 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program 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.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.db.hibernate.gui;
+
+import java.awt.BorderLayout;
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+
+import org.hibernate.Session;
+
+import de.schmitzm.db.hibernate.DBUtil;
+import de.schmitzm.db.hibernate.types.UniqueIDType;
+import de.schmitzm.swing.JPanel;
+import de.schmitzm.swing.SelectableJTable;
+
+/**
+ * Panel which shows an overview of several database tables and provides 
+ * the possibility to maintain the content of these tables. Although the panel
+ * does not provide OK, CANCEL and APPLY buttons (so that the panel can be integrated
+ * in any kind of frame!), the class does provides methods for this actions.<br>
+ * 
+ * @author Martin O.J. Schmitz
+ *
+ */
+public abstract class AbstractDatabaseTableMaintainencePanel<E extends UniqueIDType> extends JPanel {
+  
+  protected DatabaseTablesOverviewTableModel<DatabaseTablePanel<? extends E>> tablesTableModel;
+  protected JTable tablesTable;
+  protected JSplitPane splitPane;
+  protected JPanel detailsPanel;
+  protected boolean readonly;
+  
+  private ListSelectionListener selectionListener;
+  private DetailsTableListener detailsTableListener;
+
+  private DatabaseTablePanel<? extends E> selectedPanel = null;
+
+  /**
+   * Creates new panel.
+   */
+  public AbstractDatabaseTableMaintainencePanel(boolean readonly) {
+    super( new BorderLayout() );
+    this.readonly = readonly;
+    // SelectionListener fuer Stammdaten-Auswahl
+    this.selectionListener = new ListSelectionListener() {
+        @Override
+        public void valueChanged(ListSelectionEvent e) {
+            performSelectionChange(e);
+        }
+    };
+    this.detailsTableListener = new DetailsTableListener();
+
+    // Tabelle mit den verschiedenen Stammdaten-Typen
+    this.tablesTableModel = new DatabaseTablesOverviewTableModel<DatabaseTablePanel<? extends E>>();
+    this.tablesTable = new SelectableJTable(tablesTableModel);
+    this.tablesTable.setTableHeader(null);
+    this.tablesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+    this.tablesTable.getSelectionModel().addListSelectionListener(selectionListener);
+
+    // Panel fuer die Anzeige des angewaehlten Stammdaten-Typs
+    this.detailsPanel = new JPanel(new BorderLayout());
+
+    // Split-Pane
+    this.splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+            new JScrollPane(tablesTable), detailsPanel);
+    this.splitPane.setDividerLocation(200);
+    
+    add(splitPane, BorderLayout.CENTER);
+
+    for ( DatabaseTablePanel<? extends E> tablePanel : createTablePanels() )
+      tablesTableModel.addPanel(tablePanel, detailsTableListener);
+    
+    updateActions();
+  }
+  
+  /**
+   * Performs the APPLY action.
+   * @return {@code true} if action was performed successfully; {@code false} if
+   * action was canceled.
+   */
+  public boolean performApply() {
+    Session session = selectedPanel != null ? selectedPanel.getTable().getSession() : null;
+    if ( !DBUtil.endTransaction(session,true) ) {
+      selectedPanel.getTable().updateFromDatabase();
+      return false;
+    }
+    return true;
+
+  }
+  
+  /**
+   * Performs the OK action.
+   * @return {@code true} if action was performed successfully; {@code false} if
+   * action was canceled.
+   */
+  public boolean performOk() {
+    Session session = selectedPanel != null ? selectedPanel.getTable().getSession() : null;
+    if ( !DBUtil.endTransaction(session,true) ) {
+      selectedPanel.getTable().updateFromDatabase();
+      return false;
+    }
+    disposeSessions();
+    return true;
+
+  }
+  
+  /**
+   * Performs the CANCEL action.
+   * @return {@code true} if action was performed successfully; {@code false} if
+   * action was canceled.
+   */
+  public boolean performCancel() {
+    Session session = selectedPanel != null ? selectedPanel.getTable().getSession() : null;
+    if ( selectedPanel != null ) {
+      boolean confirmed = GUIUtil.confirmTransactionEnd(this,session);
+      if ( !confirmed )
+        return false;
+//MS-2012-11-16: passiert in setVisible(.)
+//      // aktuell selektierte Tabelle zurueck setzen
+//      // damit beim naechsten Aufrufen nicht noch der
+//      // alte Stand (vor Cancel) angezeigt wird
+//      selectedPanel.getTable().updateFromDatabase();
+    }
+    disposeSessions();
+    return true;
+  }
+  
+  /**
+   * Disposes all table sessions.
+   */
+  protected void disposeSessions() {
+    for (DatabaseTable<?> table : getAllDatabaseTables())
+      table.dispose();
+  }
+
+  /**
+   * Updates the visible table from database.
+   */
+  public void updateFromDatebase() {
+    if ( selectedPanel != null )
+      selectedPanel.updateFromDatabase();
+  }
+
+  /**
+   * Returns whether panel is read-only.
+   * @return
+   */
+  public boolean isReadonly() {
+    return readonly;
+  }
+  
+  /**
+   * Creates the table panels which define the tables to be maintained
+   * by the panel.
+   */
+  protected abstract List<DatabaseTablePanel<? extends E>> createTablePanels();
+  
+  /**
+   * Updates the actions of the superior frame which controls the panel
+   * and operations.
+   * @param okEnabled     indicates whether the OK action must be enabled
+   * @param applyEnabled  indicates whether the APPLY action must be enabled
+   * @param cancelEnabled indicates whether the CANCEL action must be enabled
+   */
+  protected abstract void performUpdateActions(boolean okEnabled, boolean applyEnabled, boolean cancelEnabled);
+  
+  /**
+   * Determines whether OK-, APPLY- and CANCEL-action must be enabled or
+   * disables (according to session state of currently selected table) and respectively
+   * calls {@link #performUpdateActions(boolean, boolean, boolean)}.
+   */
+  public void updateActions() {
+    boolean cancelEnabled = true;
+    boolean okEnabled     = selectedPanel != null;
+    boolean applyEnabled  = selectedPanel != null && selectedPanel.getTable().getSession().isDirty();
+    performUpdateActions(okEnabled, applyEnabled, cancelEnabled);
+  }
+  
+  /**
+   * Returns all database tables ({@link JTable}), which are maintained by the
+   * panel.
+   */
+  protected List<DatabaseTable<? extends E>> getAllDatabaseTables() {
+    List<DatabaseTable<? extends E>> tables = new ArrayList<DatabaseTable<? extends E>>();
+    for (int i=0; i<tablesTableModel.getRowCount(); i++) {
+      DatabaseTablePanel<? extends E> panel = tablesTableModel.getPanelAt(i,0);
+      if ( panel != null )
+        tables.add(panel.getTable());
+    }
+    return tables;
+  }
+
+  /**
+   * Called when a new row in the tables list is selected.
+   * If data was changed these will be saved in database (after confirmation).
+   */
+  protected void performSelectionChange(ListSelectionEvent e) {
+      if (e.getValueIsAdjusting())
+          return;
+
+//Now automatically done by SwingUtil.setAutoStopTableCellEditing(.) called in SelectableJTable.initTable():
+//    // Wenn gerade eine Zelle in den Stammdaten-Details
+//    // editiert wird, dies zuerst beenden
+//    if (selectedPanel != null && selectedPanel.getTable().isEditing())
+//        selectedPanel.getTable().getCellEditor().stopCellEditing();
+
+      int newSelectedRow = tablesTable.getSelectedRow();
+      DatabaseTablePanel<? extends E> newSelectedPanel = tablesTableModel.getPanelAt(newSelectedRow, 0);
+
+      // wenn selektierte Zeile manuell wieder zurueckgesetzt
+      // wird (beim Abbrechen des Dialogs) nichts machen
+      if (selectedPanel == newSelectedPanel)
+          return;
+
+      // Aenderungen am alten Panel speichern
+      if (selectedPanel != null) {
+          Session session = selectedPanel.getTable().getSession();
+          boolean confirmed = GUIUtil.confirmTransactionEnd(this,session);
+          // Stammdaten-Wechsel abbrechen und zur vorangegangenen
+          // Auswahl zurueck kehren
+          if (!confirmed) {
+              int lastSelectedRow = tablesTableModel.getRowFor(selectedPanel);
+              this.tablesTable.getSelectionModel().setSelectionInterval(lastSelectedRow, lastSelectedRow);
+              return;
+          }
+      }
+
+      // Neues Panel aktivieren
+      this.selectedPanel = newSelectedPanel;
+      selectedPanel.getTable().updateFromDatabase();
+      this.detailsPanel.removeAll();
+      this.detailsPanel.add(selectedPanel, BorderLayout.CENTER);
+      this.detailsPanel.validate();
+      this.detailsPanel.repaint();
+      updateActions();
+  }
+  
+  
+  
+
+  /**
+   * Wird aufgerufen, wenn sich "etwas" an der Stammdaten-Detail-Tabelle
+   * aendert.
+   */
+  protected void performDetailsTableEvent(EventObject e) {
+      // Wenn sich die Selektion geaendert hat, die Actions
+      // neu (de)aktivieren
+      if (e instanceof ListSelectionEvent)
+          updateActions();
+
+      // Wenn sich die Daten geaendert haben, die "Ubernehmen"-Action
+      // neu (de)aktivieren
+      if (e instanceof TableModelEvent)
+          updateActions();
+  }
+
+  private class DetailsTableListener implements ListSelectionListener,
+          TableModelListener {
+      @Override
+      public void tableChanged(TableModelEvent e) {
+          performDetailsTableEvent(e);
+      }
+
+      @Override
+      public void valueChanged(ListSelectionEvent e) {
+          performDetailsTableEvent(e);
+      }
+
+  }
+
+}

Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/AbstractDatabaseTableModel.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/AbstractDatabaseTableModel.java	                        (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/AbstractDatabaseTableModel.java	2013-07-12 16:40:25 UTC (rev 2356)
@@ -0,0 +1,190 @@
+package de.schmitzm.db.hibernate.gui;
+
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.table.TableModel;
+
+import org.apache.log4j.Logger;
+import org.hibernate.Session;
+import org.hibernate.criterion.Criterion;
+import org.hibernate.criterion.Order;
+
+import de.schmitzm.db.hibernate.DBUtil;
+import de.schmitzm.db.hibernate.HibernateSessionFactory;
+import de.schmitzm.db.hibernate.types.BasicType;
+import de.schmitzm.db.hibernate.types.UniqueIDType;
+import de.schmitzm.lang.LangUtil;
+import de.schmitzm.swing.ExceptionDialog;
+import de.schmitzm.swing.table.AbstractReadonlyTableModel;
+
+/**
+ * {@link TableModel} for a database table. Number of columns and content
+ * is specified by individual implementation. This class only provides
+ * standardized methods for the data access and maintenence (add/remove).
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ */
+public abstract class AbstractDatabaseTableModel<E extends UniqueIDType> extends AbstractReadonlyTableModel {
+  public final Logger LOGGER = LangUtil.createLogger(this);
+
+  /** Value which is shown in ID column for new records. */
+  public static final String NEW_RECORD_ID = GUIUtil.R("AbstractDatabaseTableModel.new");
+  
+  /** Holds the data type of the model items. */
+  protected Class<E> tableType;
+  /** Holds the database table name which is represented by the table model. */
+  protected String tableName = null;
+  /** Holds the database table records.. */
+  protected List<E> content = new Vector<E>();
+  
+  /**
+   * Creates a new table model.
+   * @param tableType data type (record type) which is represented by table model 
+   * @param readonly  if {@code true} {@link #isCellEditable(int, int)} always returns
+   *                  {@code false} and the methods {@link #addRecord()}, {@link #addRecord(BasicType)}
+   *                  {@link #removeRecord(BasicType)} and {@link #setValueAt(Object, int, int)}
+   *                  does nothing
+   */
+  public AbstractDatabaseTableModel(Class<E> tableType, boolean readonly) {
+    super(readonly);
+    this.tableName = DBUtil.getDatabaseTable(tableType);
+    this.tableType = tableType;
+  }
+
+  /**
+   * Returns the {@link Session} which is used for the database operations of the table.
+   * @return {@link HibernateSessionFactory#getSession(Object) HibernateSessionFactory.getGlobalFactory().getSession(this)}
+   */
+  public Session getSession() {
+    return HibernateSessionFactory.getGlobalFactory().getSession(this);
+  }
+
+  /**
+   * Closes the session of the table.
+   */
+  public void closeSession() {
+    HibernateSessionFactory.getGlobalFactory().closeSession(getSession());
+  }
+
+  /**
+   * Adds a (new default) record to the table and automatically stores it in database.
+   * Does nothing if table is in read-only mode.
+   */
+  public E addRecord() {
+    if ( isReadonly() )
+      return null;
+    E record = createDefaultInstance();
+    addRecord(record);
+    return record;
+  }
+  
+  /**
+   * Creates a default instance for a new record.
+   */
+  protected abstract E createDefaultInstance();
+
+  /**
+   * Adds a new record to the table. Does nothing if table is in read-only
+   * mode.
+   * @param insert if {@code true} the record is automatically stored in database;
+   *               otherwise {@link #saveOrUpdateUnsavedRecords()} must be called before
+   *               committing the transaction to make the new records persistent.
+   *               This may be useful if the new (default) record does not
+   *               satisfies all required constraints immediately.
+   */
+  public boolean addRecord(E record, boolean insert) {
+    if ( isReadonly() )
+      return false;
+    if ( insert ) {
+      getSession().saveOrUpdate(record);
+    }
+    content.add(record);
+    fireTableDataChanged();
+    return true;
+  }
+  
+  /**
+   * Adds a new record to the table and stored it immediately in database.
+   * Does nothing if table is in read-only mode.
+   */
+  public boolean addRecord(E record) {
+    return addRecord(record,true);
+  }
+
+  /**
+   * Adds/Updates all not yet stored records in database. All constraints
+   * are checked so that exeptions may occur.<br>
+   * The current transaction will not be committed by this method!
+   */
+  public void saveOrUpdateUnsavedRecords() {
+    Session session = getSession();
+    for ( E record : content )
+      session.saveOrUpdate(record);
+  }
+  
+  /**
+   * Returns a record of the table.
+   */
+  public E getRecord(int row) {
+    return content.get(row);
+  }
+
+  /**
+   * Removes a record from database and automatically deletes it from database.
+   * Does nothing if table is in read-only mode.
+   */
+  public boolean removeRecord(E record) {
+    if ( isReadonly() )
+      return false;
+    getSession().delete(record);
+    content.remove(record);
+    fireTableDataChanged();
+    return true;
+  }
+
+  /**
+   * Updates (re-reads) the list/table from database.
+   */
+  public void updateFromDatabase() {
+    updateFromDatabase(null,null);
+  }
+  
+
+  /**
+   * Updates (re-reads) the list/table from database.
+   * @param filter filter to reduce the data (can be {@code null})
+   * @param order ordering for the records (can be {@code null})
+   */
+  public void updateFromDatabase(Criterion filter, Order order) {
+    try {
+      content = DBUtil.determineAllRecords( getSession(), getTableType(), filter, order );
+      fireTableDataChanged();
+    } catch (Exception err) {
+      ExceptionDialog.show(null, err, "Fehler beim Aktualisieren der Tabelle '"+getDatabaseTable()+"'", null);
+    }
+  }
+
+  /**
+   * Returns the number of records in table.
+   */
+  @Override
+  public int getRowCount() {
+    return content.size();
+  }
+
+  /**
+   * Returns the type of the table model.
+   */
+  public Class<E> getTableType() {
+    return tableType;
+  }
+
+  /**
+   * Returns the database table name which the table model represents.
+   */
+  public String getDatabaseTable() {
+    return tableName;
+  }
+  
+  
+}
\ No newline at end of file

Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/BasicTypeTableModel.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/BasicTypeTableModel.java	                        (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/BasicTypeTableModel.java	2013-07-12 16:40:25 UTC (rev 2356)
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program 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.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.db.hibernate.gui;
+
+import javax.swing.table.TableModel;
+
+import org.hibernate.criterion.Order;
+
+import de.schmitzm.db.hibernate.DBUtil;
+import de.schmitzm.db.hibernate.HibernateSessionFactory;
+import de.schmitzm.db.hibernate.types.BasicType;
+import de.schmitzm.db.hibernate.types.BasicTypeInterface;
+
+/**
+ * {@link TableModel} for a basic type table, which is implemented by
+ * {@link BasicTypeInterface BasicType} (ID, Bezeichnung).
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public class BasicTypeTableModel<F extends BasicTypeInterface> extends AbstractDatabaseTableModel<F> {
+  /** Anzahl der Standard-Spalten fuer {@link BasisType}. */
+  public static final int BASIC_TYPE_COLUMNS = 1;
+  
+  /**
+   * Creates a new table model
+   * @param basicType basic type
+   * @param readonly  if {@code true} {@link #isCellEditable(int, int)} always returns
+   *                  {@code false} and the methods {@link #addRecord()}, {@link #addRecord(BasicType)}
+   *                  {@link #removeRecord(BasicType)} and {@link #setValueAt(Object, int, int)}
+   *                  does nothing
+   */
+  public BasicTypeTableModel(Class<F> basicType, boolean readonly) {
+    super(basicType,readonly);
+  }
+
+  /**
+   * Updates the table from database, ordered by description.
+   */
+  @Override
+  public void updateFromDatabase() {
+    updateFromDatabase(null,Order.asc(BasicType.DESCRIPTION_COL));
+  }
+
+  /**
+   * Returns the column names of the {@link TableModel}.
+   */
+  @Override
+  public String[] createColumnNames() {
+    return new String[] {
+//        GUIUtil.R("BasicTypeTableModel.col.id"),
+        GUIUtil.R("BasicTypeTableModel.col.desc")
+    };
+  }
+  
+  /**
+   * Creates a default instance of the represented {@link BasicType} sub class.
+   */
+  @Override
+  protected F createDefaultInstance() {
+    return DBUtil.createBasicType( getTableType(), NEW_RECORD_ID );
+  }
+  
+  /**
+   * Returns a value of the table.
+   */
+  @Override
+  public Object getValueAt(int row, int col) {
+    BasicTypeInterface data = content.get(row);
+    switch ( col ) {
+//      case 0: return data.getId() != null ? data.getId() : NEW_RECORD_ID;
+      case 0: return data.getDescription();
+    }
+    return null;
+  }
+  
+  /**
+   * Sets a value of the table and transfers it to the underlying {@link BasicType}
+   * instance.
+   */
+  @Override
+  public void setValueAt(Object value, int row, int col) {
+    if ( isReadonly() )
+      return;
+    
+    HibernateSessionFactory.beginTransactionIfNeeded( getSession() );
+    BasicTypeInterface data = content.get(row);
+    switch ( col ) {
+//      case 0: if ( NEW_RECORD_ID.equals(value) )
+//                 value = null;
+//              data.setId( value == null ? null : Integer.valueOf(value.toString()) );
+//              break;
+      case 0: data.setDescription( value == null ? null : value.toString() ); break;
+    }
+//    getSession().saveOrUpdate(data);
+  }
+
+  /**
+   * Prueft, ob eine Zelle editierbar ist. Spalte 0 (ID)
+   * ist nicht editierbar, Spalte 1 (Bezeichnung) ist
+   * aenderbar.
+   */
+  @Override
+  public boolean isCellEditable(int row, int col) {
+    if ( !super.isCellEditable(row, col) )
+      return false;
+    switch ( col ) {
+//      case 0: return false;
+      case 0: return true;
+    }
+    return true;
+  }
+}
+

Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTable.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTable.java	                        (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTable.java	2013-07-12 16:40:25 UTC (rev 2356)
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program 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.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.db.hibernate.gui;
+
+
+import javax.swing.JTable;
+import javax.swing.event.ChangeEvent;
+
+import org.apache.log4j.Logger;
+import org.hibernate.Session;
+
+import de.schmitzm.db.hibernate.DBUtil;
+import de.schmitzm.db.hibernate.HibernateSessionFactory;
+import de.schmitzm.db.hibernate.types.UniqueIDType;
+import de.schmitzm.lang.LangUtil;
+import de.schmitzm.swing.ExceptionDialog;
+import de.schmitzm.swing.SortableJTable;
+
+/**
+ * Generic class for a {@link JTable}, which represents a database table and which
+ * allows modifications on the table (as long as the table is not in read-only mode).
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ * @param <E> database type
+ */
+public class DatabaseTable<E extends UniqueIDType> extends SortableJTable {
+  public final Logger LOGGER = LangUtil.createLogger(this);
+  
+  /**
+   * Creates a new table.
+   */
+  public DatabaseTable(AbstractDatabaseTableModel<E> model) {
+    super(model);
+  } 
+
+  /**
+   * Catches all exceptions during {@link #setValueAt(Object, int, int)}
+   * and shows the respective error message.
+   * Furthermore {@link Session#isDirty()} is called to check possible
+   * constraint violations.
+   * In case of errors the cell value is reset to its previous value!
+   */
+  @Override
+  public void editingStopped(ChangeEvent e) {
+    int    editingRow = getEditingRow();
+    int    editingCol = getEditingColumn();
+    Object oldValue = getValueAt(editingRow,editingCol);
+    try {
+      super.editingStopped(e);
+      // Auf etwaige Constraint-Verletzungen pruefen!!
+      getSession().isDirty();
+    } catch (Exception err) {
+      ExceptionDialog.show(err);
+      if ( getCellEditor() != null )
+        getCellEditor().cancelCellEditing();
+      else
+        setValueAt(oldValue,editingRow,editingCol);
+    }
+  }
+  
+  /**
+   * Returns the {@link Session} which is used for table operations.
+   */
+  public Session getSession() {
+    return getModel().getSession();
+  }
+
+  /**
+   * Closes the {@link Session} used for table operations.
+   */
+  public void dispose() {
+    // only close session if session is not the global session
+//    if ( HibernateSessionFactory.MULTIPLE_SESSIONS )
+    if ( getSession() != DBUtil.getGlobalSession() )
+      getModel().closeSession();
+  }
+  
+  /**
+   * Updates (re-reads) the table content from database.
+   */
+  public void updateFromDatabase() {
+    getModel().updateFromDatabase();
+  }
+  
+  /**
+   * Checks whether the table in in read-only mode.
+   */
+  public boolean isReadonly() {
+    return getModel().isReadonly();
+  }
+
+  /**
+   * Returns the table model.
+   */
+  @Override
+  public AbstractDatabaseTableModel<E> getModel() {
+    return (AbstractDatabaseTableModel)super.getModel();
+  }
+
+  /**
+   * Returns the record type of the table.
+   */
+  public Class<E> getTableType() {
+    return getModel().getTableType();
+  }
+
+  /**
+   * Return the database table name of the underlying table.
+   */
+  public String getDatabaseTable() {
+    return getModel().getDatabaseTable();
+  }
+  
+
+  /**
+   * Scrolls to the end of the table and automatically selects the new row.
+   */
+  protected void scrollToNewRow() {
+    int lastRow = getRowCount()-1;
+    scrollRectToVisible(getCellRect(lastRow, 0, true));
+    getSelectionModel().setSelectionInterval(lastRow, lastRow);
+  }
+  
+  /**
+   * Adds a default record to table and automatically stores it in database.
+   * Does nothing if table is in read-only mode.
+   */
+  public E addRecord() {
+    E addedRecord = getModel().addRecord();
+    if ( addedRecord != null )
+      scrollToNewRow();
+    return addedRecord;
+  }
+
+  /**
+   * Adds a record to table and automatically stores it in database.
+   * Does nothing if table is in read-only mode.
+   */
+  public boolean addRecord(E newRecord) {
+    boolean added = getModel().addRecord(newRecord);
+    if ( added )
+      scrollToNewRow();
+    return added;
+  }
+
+  /**
+   * Adds a new record to the table and automatically stores it in database.
+   * Does nothing if table is in read-only
+   * mode.
+   * @param insert if {@code true} the record is automatically stored in database;
+   *               otherwise {@link #saveOrUpdateUnsavedRecords()} must be called before
+   *               committing the transaction to make the new records persistent.
+   *               This may be useful if the new (default) record does not
+   *               satisfies all required constraints immediately.
+   */
+  public boolean addRecord(E record, boolean insert) {
+    boolean added = getModel().addRecord(record,insert);
+    if ( added )
+      scrollToNewRow();
+    return added;
+  }
+
+  /**
+   * Adds/Updates all not yet stored records in database. All constraints
+   * are checked so that exeptions may occur.<br>
+   * The current transaction will not be committed by this method!
+   */
+  public void saveOrUpdateUnsavedRecords() {
+    getModel().saveOrUpdateUnsavedRecords();
+  }
+
+  /**
+   * Returns a record of the table.
+   * @param row row number of the table model (starting with 0); should be
+   *            converted with {@link #convertRowIndexToModel(int)}! 
+   */
+  public E getRecord(int row) {
+    return getModel().getRecord(row);
+  }
+
+  /**
+   * Returns a record of the table.
+   * @param row row number of the selection model (starting with 0);
+   *            is automatically converted by {@link #convertRowIndexToModel(int)}! 
+   */
+  public E getRecordBySelectionIndex(int row) {
+    return getRecord( convertRowIndexToModel(row) );
+  }
+
+  /**
+   * Removes a record from table and automatically deletes it in database.
+   * Does nothing if table is in read-only mode.
+   * @param row row number of the table model (starting with 0); should be
+   *            converted with {@link #convertRowIndexToModel(int)}! 
+   */
+  public boolean removeRecordBySelectionIndex(int row) {
+    E record = getRecordBySelectionIndex(row);
+    return removeRecord(record);
+  }
+
+  /**
+   * Removes a record from table and automatically deletes it in database.
+   * Does nothing if table is in read-only mode.
+   */
+  public boolean removeRecord(E record) {
+    return getModel().removeRecord(record);
+  }
+}

Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTablePanel.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTablePanel.java	                        (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTablePanel.java	2013-07-12 16:40:25 UTC (rev 2356)
@@ -0,0 +1,228 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program 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.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.db.hibernate.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Font;
+
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JTextPane;
+
+import de.schmitzm.db.hibernate.types.UniqueIDType;
+import de.schmitzm.swing.JPanel;
+import de.schmitzm.swing.SwingUtil;
+import de.schmitzm.swing.table.AbstractMutableListPanel;
+
+/**
+ * Panel to maintain a database table. Besides the table the panel contains
+ * a title label above and a {@link JTextPane} below to show a table description.
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ * @param <E> table data type
+ */
+public class DatabaseTablePanel<E extends UniqueIDType> extends JPanel {
+  /** Titel of the panel (e.g. table name). */
+  protected JLabel title = null;
+  
+  /** Table description shown below the table. */
+  protected JTextPane description = null;
+ 
+  /** Short description of the table used as tooltip. */
+  protected String tooltip = null;
+  
+  /** Tabelle in der die Stammdaten angezeigt werden. */
+  protected DatabaseTable<E> table = null;
+  
+  /** Table panel to show/maintain the data. */
+  protected AbstractMutableListPanel<DatabaseTable<E>> tablePanel = null;
+
+  /**
+   * Creates a new panel.
+   * @param model   table model of the data
+   * @param title   title of the table (used as header title in panel)
+   * @param desc    description of the table (used as description below the data table)
+   * @param tooltip short description of the table (used as tooltip)
+   */
+  public DatabaseTablePanel(AbstractDatabaseTableModel<E> model, String title, String desc, String tooltip) {
+    this(new DatabaseTable<>(model),title,desc,tooltip);
+  }
+  
+  /**
+   * Creates a new panel.
+   * @param table   table of the data
+   * @param title   title of the table (used as header title in panel)
+   * @param desc    description of the table (used as description below the data table)
+   * @param tooltip short description of the table (used as tooltip)
+   */
+  public DatabaseTablePanel(DatabaseTable<E> table, String title, String desc, String tooltip) {
+    super(new BorderLayout(5,5));
+    this.setBorder( BorderFactory.createEmptyBorder(5,5,5,5) );
+    this.title = new JLabel();
+    this.title.setFont( this.title.getFont().deriveFont(Font.BOLD) );
+    this.title.setHorizontalAlignment(JLabel.CENTER);
+    add(this.title, BorderLayout.NORTH);
+    
+    
+    this.description = new JTextPane();
+//    description.setContentType("text/html");
+    description.setBackground( SwingUtil.getDefaultBackground() );
+    add(description, BorderLayout.SOUTH);
+    
+    this.table = table;
+    this.tablePanel = new AbstractMutableListPanel<DatabaseTable<E>>() {
+      @Override
+      public DatabaseTable<E> createListComponent() {
+        return getTable();
+      }
+      @Override
+      public void performAddAction() {
+        DatabaseTablePanel.this.performAddAction();
+      }
+      @Override
+      public void performRemoveAction() {
+        DatabaseTablePanel.this.performRemoveAction();
+      }
+      @Override
+      public boolean isReadonly() {
+        return getTable().isReadonly();
+      }
+      @Override
+      public int getSelectedRowCount() {
+        return getTable().getSelectedRowCount();
+      }
+      @Override
+      public void updateGUI() {
+        getTable().getModel().fireTableDataChanged();
+      }
+    };
+    add( tablePanel, BorderLayout.CENTER);
+    
+    setTitle(title);
+    setDescription(desc);
+    setTooltipDesc(tooltip);
+  }
+
+  /**
+   * Returns the data table of the panel.
+   */
+  public DatabaseTable<E> getTable() {
+    return table;
+  }
+  
+  /**
+   * Updates (re-reads) the data from database.
+   */
+  public void updateFromDatabase() {
+    if ( table != null )
+      table.updateFromDatabase();
+  }
+  
+  /**
+   * Returns the data type of the table.
+   */
+  public Class<E> getBasicType() {
+    return table.getTableType();
+  }
+
+  /**
+   * Returns the header title of the table.
+   */
+  public String getTitle() {
+    return title.getText();
+  }
+  
+  /**
+   * Sets the header title of the table.
+   */
+  public void setTitle(String title) {
+    this.title.setText(title);
+    this.title.setVisible( title != null );
+  }
+
+  /**
+   * Returns the table description (shown below the table).
+   */
+  public String getDescription() {
+    return description.getText();
+  }
+  
+  /**
+   * Sets the table description (shown below the table).
+   */
+  public void setDescription(String description) {
+    this.description.setText(description);
+    this.description.setVisible( description != null );
+  }
+
+  /**
+   * Returns the short description (can be used by other components as tooltip).
+   */
+  public String getTooltipDesc() {
+    return tooltip;
+  }
+  
+  /**
+   * Sets the short description (can be used by other components as tooltip).
+   */
+  public void setTooltipDesc(String tooltip) {
+    this.tooltip = tooltip;
+  }
+
+  /**
+   * Called by {@link DatabaseTable} to add a table row.
+   * This standard implementation calls {@link DatabaseTable#addRecord()}.
+   * Sub-classes can override this method to implement more complex procedures (e.g.
+   * open dialog) to specify a new record.
+   */
+  public void performAddAction() {
+    getTable().addRecord();
+  }
+  
+  /**
+   * Called by {@link DatabaseTable} to remove the selected table rows.
+   * This standard implementation calls {@link DatabaseTable#removeRecord(UniqueIDType)}.
+   * Sub-classes can override this method to implement more complex procedures (e.g.
+   * open dialog).
+   */
+  public void performRemoveAction() {
+    int[] rows = getTable().getSelectedRows();
+    for (int i=rows.length-1; i>=0; i--) {
+      E record = getTable().getRecordBySelectionIndex(rows[i]);
+      getTable().removeRecord(record);
+    }
+    // Panel neu von Datenbank einlesen
+//PROBLEM: Danach ist die Session nicht mehr dirty, so dass das mit
+//        mit dem Check fuer die Confirm-Message nicht mehr klappt
+//        --> nicht neu einlesen, sondern JTable-Zeile manuell
+//            entfernen (in selectedPanel.getTable().removeRecord(record))
+//  getTable().updateFormDatabase();
+  }
+}
\ No newline at end of file

Added: trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTablesOverviewTableModel.java
===================================================================
--- trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTablesOverviewTableModel.java	                        (rev 0)
+++ trunk/schmitzm-hibernate/src/main/java/de/schmitzm/db/hibernate/gui/DatabaseTablesOverviewTableModel.java	2013-07-12 16:40:25 UTC (rev 2356)
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ * 
+ * This program 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.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ * 
+ * Contributors:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.db.hibernate.gui;
+
+import java.util.Vector;
+
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.TableModel;
+
+import de.schmitzm.db.hibernate.types.UniqueIDType;
+import de.schmitzm.swing.table.AbstractTableModel;
+
+/**
+ * This {@link TableModel} represents an overview list (one column table) of
+ * database tables to be maintained. For this purpose the model holds an
+ * {@link DatabaseTablePanel} for each panel.
+ * @see AbstractDatabaseTableMaintainencePanel
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *
+ */
+public class DatabaseTablesOverviewTableModel<E extends DatabaseTablePanel<? extends UniqueIDType>> extends AbstractTableModel {
+  /** Holds the detail panels */
+  protected Vector<E> tablePanels = new Vector<E>();
+  
+  /**
+   * Creates a new table model. 
+   */
+  public DatabaseTablesOverviewTableModel() {
+    super();
+  }
+
+  /**
+   * Returns the column names of the table model.
+   * This {@link AbstractDatabaseTablesOverviewTableModel} has only one column
+   * with no name.
+   */
+  @Override
+  public String[] createColumnNames() {
+    return new String[] {""};
+  }
+
+  /**
+   * Always returns {@code false}.
+   */
+  @Override
+  public boolean isCellEditable(int col, int row) {
+    return false;
+  }
+
+  /**
+   * Returns the number of master data tables in the model.
+   */
+  @Override
+  public int getRowCount() {
+    return tablePanels.size();
+  }
+  
+  /**
+   * Returns the table title of the respective row.
+   * @see DatabaseTablePanel#getTitle()
+   */
+  @Override
+  public Object getValueAt(int row, int col) {
+    E tablePanel = tablePanels.elementAt(row);
+    return tablePanel.getTitle();
+  }
+  
+  /**
+   * Return the underlying {@link DatabaseTablePanel} of a row.
+   */
+  public E getPanelAt(int row, int col) {
+    return tablePanels.elementAt(row);
+  }
+
+  /**
+   * Returns the row for a given {@link DatabaseTablePanel}.
+   */
+  public int getRowFor(E panel) {
+    return tablePanels.indexOf(panel);
+  }
+
+  /**
+   * Add a panel to the table model.
+   */
+  public boolean addPanel(E panel, Object listener) {
+    if ( tablePanels.contains(panel) )
+      return false;
+    if ( listener instanceof TableModelListener )
+      panel.getTable().getModel().addTableModelListener((TableModelListener)listener);
+    if ( listener instanceof ListSelectionListener )
+      panel.getTable().getSelectionModel().addListSelectionListener((ListSelectionListener)listener);
+    
+    tablePanels.add( panel );
+    return true;
+  }
+
+}

Modified: trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle.properties
===================================================================
--- trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle.properties	2013-07-12 16:36:48 UTC (rev 2355)
+++ trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle.properties	2013-07-12 16:40:25 UTC (rev 2356)
@@ -53,3 +53,7 @@
 DatabaseEntityEditorFrame.action.delete.desc=Delete record
 DatabaseEntityEditorFrame.error.lock=The record is locked. You can not make chances until the external edit action has been finished.
 DatabaseEntityEditorFrame.error.lock.desc=Record locked
+
+AbstractDatabaseTableModel.new=<new>
+BasicTypeTableModel.col.id=ID
+BasicTypeTableModel.col.desc=Description

Modified: trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle_de.properties
===================================================================
--- trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle_de.properties	2013-07-12 16:36:48 UTC (rev 2355)
+++ trunk/schmitzm-hibernate/src/main/resources/de/schmitzm/db/hibernate/resource/locales/HibernateResourceBundle_de.properties	2013-07-12 16:40:25 UTC (rev 2356)
@@ -53,3 +53,7 @@
 DatabaseEntityEditorFrame.action.delete.desc=Datensatz l\u00f6schen
 DatabaseEntityEditorFrame.error.lock=Der Datensatz wird gerade extern bearbeitet. Sie k\u00f6nnen solange keine \u00c4nderungen vornehmen.
 DatabaseEntityEditorFrame.error.lock.desc=Datensatz wird bereits bearbeitet
+
+AbstractDatabaseTableModel.new=<neu>
+BasicTypeTableModel.col.id=ID
+BasicTypeTableModel.col.desc=Bezeichnung



More information about the Schmitzm-commits mailing list