/***************************************************
*
* cismet GmbH, Saarbruecken, Germany
*
* ... and it just works.
*
****************************************************/
package Sirius.navigator.ui;
/*******************************************************************************
*
* Copyright (c) : EIG (Environmental Informatics Group)
* http://www.htw-saarland.de/eig
* Prof. Dr. Reiner Guettler
* Prof. Dr. Ralf Denzer
*
* HTWdS
* Hochschule fuer Technik und Wirtschaft des Saarlandes
* Goebenstr. 40
* 66117 Saarbruecken
* Germany
*
* Programmers : Pascal
*
* Project : WuNDA 2
* Version : 2.0
* Purpose :
* Created : 01.11.1999
* History : 01.05.2000, new Version + UI
*
*******************************************************************************/
import Sirius.navigator.tools.MetaToolkit;
import Sirius.navigator.ui.widget.*;
import org.apache.log4j.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
//import Sirius.navigator.PlugIn.*;
/**
* Ein flexibler Container in dem bis zu 7 Komponenten (JComponent) unterschiedlich angeordnet werden koennen.<br>
* Der NavigatorLayoutManager ist durch 2 JSplitPanes in 3 Bereiche aufgeteilt: LEFT_TOP, LEFT_BOTTOM und RIGHT. In
* LEFT_BOTTOM ist Platz fuer nur eine Komponente in LEFT_TOP und RIGHT passen jeweils 3 Komponeten, die durch Tabs
* (JTabbedPane) voneinander abgetrennt sind. Die Komponeten koennen optional noch in eine JScrollPane oder ein
* zentriert in ein JPanel eingebettet werden.<br>
* Ausserdem kann sich die Groesse der 3 Bereiche proportional der Groesse des NavigatorLayoutManager anpassen. Dafuer
* musste das BasicSplitPaneUI angepasst werden.
*
* @author Pascal Dihe
* @version 2.0
*/
public final class MutableContainer implements GUIContainer {
//~ Static fields/initializers ---------------------------------------------
private static final Logger logger = Logger.getLogger(MutableContainer.class);
//~ Instance fields --------------------------------------------------------
private final Hashtable components = new Hashtable();
private final JSplitPane rootSplitPane;
private final JSplitPane leftSplitPane;
private final JTabbedPane p1Pane;
private final JTabbedPane p2Pane;
private final JTabbedPane p3Pane;
private final ConstrainsChangeListener constrainsChangeListener;
private final FloatingFrameListener floatingFrameListener;
private boolean continuousLayout = false;
private boolean oneTouchExpandable = false;
private boolean proportionalResize = false;
private boolean obeyMinimumSize = false;
private final MutableToolBar toolBar;
private final MutableMenuBar menuBar;
//~ Constructors -----------------------------------------------------------
/**
* Creates a new MutableContainer object.
*
* @param toolBar DOCUMENT ME!
* @param menuBar DOCUMENT ME!
*/
public MutableContainer(final MutableToolBar toolBar, final MutableMenuBar menuBar) {
this(toolBar, menuBar, false);
}
/**
* Creates a new MutableContainer object.
*
* @param toolBar DOCUMENT ME!
* @param menuBar DOCUMENT ME!
* @param advancedLayout DOCUMENT ME!
*/
public MutableContainer(final MutableToolBar toolBar, final MutableMenuBar menuBar, final boolean advancedLayout) {
this(toolBar, menuBar, advancedLayout, advancedLayout, advancedLayout, advancedLayout);
}
/**
* Creates a new MutableContainer object.
*
* @param toolBar DOCUMENT ME!
* @param menuBar DOCUMENT ME!
* @param continuousLayout DOCUMENT ME!
* @param oneTouchExpandable DOCUMENT ME!
* @param proportionalResize DOCUMENT ME!
* @param obeyMinimumSize DOCUMENT ME!
*/
public MutableContainer(final MutableToolBar toolBar,
final MutableMenuBar menuBar,
final boolean continuousLayout,
final boolean oneTouchExpandable,
final boolean proportionalResize,
final boolean obeyMinimumSize) {
if (logger.isDebugEnabled()) {
logger.debug("creating MutableContainer instance"); // NOI18N
}
this.toolBar = toolBar;
this.menuBar = menuBar;
this.continuousLayout = continuousLayout;
this.oneTouchExpandable = oneTouchExpandable;
this.proportionalResize = proportionalResize;
this.obeyMinimumSize = obeyMinimumSize;
p1Pane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
p2Pane = new JTabbedPane(JTabbedPane.BOTTOM, JTabbedPane.SCROLL_TAB_LAYOUT);
p3Pane = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.WRAP_TAB_LAYOUT);
this.leftSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, this.continuousLayout, p1Pane, p2Pane);
this.rootSplitPane = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT,
this.continuousLayout,
this.leftSplitPane,
this.p3Pane);
this.leftSplitPane.setOneTouchExpandable(oneTouchExpandable);
this.rootSplitPane.setOneTouchExpandable(oneTouchExpandable);
if (this.proportionalResize) {
// this.leftSplitPane.setResizeWeight(0.75);
// this.rootSplitPane.setResizeWeight(0.25);
this.leftSplitPane.setResizeWeight(0.60);
this.rootSplitPane.setResizeWeight(0.30);
}
if (this.obeyMinimumSize) {
p1Pane.setMinimumSize(new Dimension(240, 200));
}
if (Sirius.navigator.resource.PropertyManager.getManager().isAdvancedLayout()) {
p1Pane.setBorder(new javax.swing.border.EmptyBorder(1, 1, 1, 1));
p2Pane.setBorder(new javax.swing.border.EmptyBorder(1, 1, 1, 1));
p3Pane.setBorder(new javax.swing.border.EmptyBorder(1, 1, 1, 1));
this.leftSplitPane.setBorder(new javax.swing.border.EmptyBorder(1, 1, 1, 1));
this.rootSplitPane.setBorder(new javax.swing.border.EmptyBorder(1, 1, 1, 1));
}
// this.leftSplitPane.setDividerLocation(600);
// this.rootSplitPane.setDividerLocation(250);
constrainsChangeListener = new ConstrainsChangeListener();
floatingFrameListener = new FloatingFrameListener();
}
//~ Methods ----------------------------------------------------------------
/**
* DOCUMENT ME!
*
* @param rootSplitPaneDividerLocation DOCUMENT ME!
* @param leftSplitPaneDividerLocation DOCUMENT ME!
*/
public void setDividerLocations(final double rootSplitPaneDividerLocation,
final double leftSplitPaneDividerLocation) {
this.rootSplitPane.setDividerLocation(rootSplitPaneDividerLocation);
this.leftSplitPane.setDividerLocation(leftSplitPaneDividerLocation);
}
@Override
public synchronized void add(final MutableConstraints constraints) {
if (logger.isInfoEnabled()) {
logger.info("adding component '" + constraints.getName() + "' to mutable container at position '"
+ constraints.getPosition() + "'"); // NOI18N
}
if (logger.isDebugEnabled()) {
logger.debug(constraints.toString());
}
if (!components.containsKey(constraints.getId())) {
components.put(constraints.getId(), constraints);
if (!this.rootSplitPane.isDisplayable() || SwingUtilities.isEventDispatchThread()) {
doAdd(constraints);
} else {
if (logger.isDebugEnabled()) {
logger.debug("add(): synchronizing method"); // NOI18N
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
doAdd(constraints);
}
});
}
if (constraints.isMutable()) {
constraints.addPropertyChangeListener(constrainsChangeListener);
}
} else {
logger.error("a component with the same id '" + constraints.getId() + "' is already in this container"); // NOI18N
}
}
/**
* DOCUMENT ME!
*
* @param constraints DOCUMENT ME!
*/
private void doAdd(final MutableConstraints constraints) {
final JTabbedPane tabbedPane = this.getTabbedPaneAt(constraints.getPosition());
if ((constraints.getPreferredIndex() != -1) && (tabbedPane.getTabCount() > constraints.getPreferredIndex())) {
if (logger.isDebugEnabled()) {
logger.debug("inserting component at index '" + constraints.getPreferredIndex() + "'"); // NOI18N
}
if (constraints.getContainerType().equals(MutableConstraints.FLOATINGFRAME)) {
tabbedPane.insertTab(constraints.getName(),
constraints.getIcon(),
((FloatingFrame)constraints.getContainer()).getFloatingPanel(),
constraints.getToolTip(),
constraints.getPreferredIndex());
tabbedPane.setSelectedIndex(constraints.getPreferredIndex());
this.addFloatingFrame(constraints);
} else {
tabbedPane.insertTab(constraints.getName(),
constraints.getIcon(),
constraints.getContainer(),
constraints.getToolTip(),
constraints.getPreferredIndex());
tabbedPane.setSelectedIndex(constraints.getPreferredIndex());
}
} else {
if (constraints.getContainerType().equals(MutableConstraints.FLOATINGFRAME)) {
tabbedPane.addTab(constraints.getName(),
constraints.getIcon(),
((FloatingFrame)constraints.getContainer()).getFloatingPanel(),
constraints.getToolTip());
this.addFloatingFrame(constraints);
} else {
tabbedPane.addTab(constraints.getName(),
constraints.getIcon(),
constraints.getContainer(),
constraints.getToolTip());
}
}
}
/**
* DOCUMENT ME!
*
* @param constraints DOCUMENT ME!
*/
private void addFloatingFrame(final MutableConstraints constraints) {
if (logger.isDebugEnabled()) {
logger.debug("adding FloatingFrame"); // NOI18N
}
final FloatingFrameConfigurator configurator = constraints.getFloatingFrameConfigurator();
// logger.info("FloatingFrame constraints '" + constraints + "'");
// logger.info("FloatingFrame constraints id: '" + constraints.getId() + "'");
// logger.info("FloatingFrame configurator '" + configurator + "'");
// logger.info("FloatingFrame configurator id: '" + configurator.getId() + "'");
if (!configurator.getId().equals(constraints.getId())) {
logger.warn("FloatingFrame constraints id: '" + constraints.getId()
+ "' != FloatingFrame configurator id: '" + configurator.getId() + "'"); // NOI18N
}
if (configurator.isSwapMenuBar() || configurator.isSwapToolBar()) {
if (logger.isDebugEnabled()) {
logger.debug("enabling Floating Listener"); // NOI18N
}
((FloatingFrame)constraints.getContainer()).addPropertyChangeListener(
FloatingFrame.FLOATING,
floatingFrameListener);
}
if (configurator.isSwapMenuBar()) {
if (logger.isInfoEnabled()) {
logger.info("adding FloatingFrameMenuBar '" + configurator.getId() + "' to MutableMenuBar"); // NOI18N
}
menuBar.addMoveableMenues(configurator.getId(), configurator.getMenues());
}
if (configurator.isSwapToolBar()) {
if (logger.isInfoEnabled()) {
logger.info("adding FloatingFrameToolBar '" + configurator.getId() + "' to MutableToolBar"); // NOI18N
}
toolBar.addMoveableToolBar(((FloatingFrame)constraints.getContainer()).getToolBar());
}
}
/**
* DOCUMENT ME!
*
* @param constraints DOCUMENT ME!
*/
private void removeFloatingFrame(final MutableConstraints constraints) {
if (logger.isDebugEnabled()) {
logger.debug("removing FloatingFrame"); // NOI18N
}
final FloatingFrameConfigurator configurator = constraints.getFloatingFrameConfigurator();
if (configurator.isSwapMenuBar() || configurator.isSwapToolBar()) {
((FloatingFrame)constraints.getContainer()).removePropertyChangeListener(floatingFrameListener);
}
if (configurator.isSwapMenuBar()) {
logger.info("removing FloatingFrameMenuBar '" + configurator.getId() + "' from MutableMenuBar"); // NOI18N
menuBar.removeMoveableMenues(configurator.getId());
}
if (configurator.isSwapToolBar()) {
logger.info("removing FloatingFrameToolBar '" + configurator.getId() + "' from MutableToolBar"); // NOI18N
toolBar.removeMoveableToolBar(configurator.getId());
}
}
@Override
public synchronized void remove(final String id) {
if (logger.isInfoEnabled()) {
logger.info("removing component '" + id + "'"); // NOI18N
}
if (components.containsKey(id)) {
final MutableConstraints constraints = (MutableConstraints)components.remove(id);
if (constraints.isMutable()) {
constraints.removePropertyChangeListener(constrainsChangeListener);
}
if (SwingUtilities.isEventDispatchThread()) {
doRemove(constraints);
} else {
if (logger.isDebugEnabled()) {
logger.debug("remove(): synchronizing method"); // NOI18N
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
doRemove(constraints);
}
});
}
} else {
logger.error("component '" + id + "' not found in this container"); // NOI18N
}
}
/**
* DOCUMENT ME!
*
* @param constraints DOCUMENT ME!
*/
private void doRemove(final MutableConstraints constraints) {
if (logger.isDebugEnabled()) {
logger.debug("removing component '" + constraints.getName() + "' at position '" + constraints.getPosition()
+ "'"); // NOI18N
}
final JTabbedPane tabbedPane = this.getTabbedPaneAt(constraints.getPosition());
if (constraints.getContainerType().equals(MutableConstraints.FLOATINGFRAME)) {
tabbedPane.remove(((FloatingFrame)constraints.getContainer()).getFloatingPanel());
this.removeFloatingFrame(constraints);
} else {
tabbedPane.remove(constraints.getContainer());
}
}
@Override
public synchronized void select(final String id) {
if (logger.isDebugEnabled()) {
logger.debug("selecting component '" + id + "'"); // NOI18N
}
if (components.containsKey(id)) {
final MutableConstraints constraints = (MutableConstraints)components.get(id);
if (SwingUtilities.isEventDispatchThread()) {
doSelect(constraints);
} else {
if (logger.isDebugEnabled()) {
logger.debug("select(): synchronizing method"); // NOI18N
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
doSelect(constraints);
}
});
}
} else {
logger.error("component '" + id + "' not found in this container"); // NOI18N
}
}
/**
* DOCUMENT ME!
*
* @param constraints DOCUMENT ME!
*/
private void doSelect(final MutableConstraints constraints) {
if (!constraints.getView().isClosable()) {
constraints.getView().restore();
}
final JTabbedPane tabbedPane = this.getTabbedPaneAt(constraints.getPosition());
if (constraints.getContainerType().equals(MutableConstraints.FLOATINGFRAME)) {
tabbedPane.setSelectedComponent(((FloatingFrame)constraints.getContainer()).getFloatingPanel());
} else {
tabbedPane.setSelectedComponent(constraints.getContainer());
}
}
/**
* DOCUMENT ME!
*
* @param position DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
private JTabbedPane getTabbedPaneAt(final String position) {
if (position.equals(MutableConstraints.P1)) {
return p1Pane;
} else if (position.equals(MutableConstraints.P2)) {
return p2Pane;
} else if (position.equals(MutableConstraints.P3)) {
return p3Pane;
} else {
logger.warn("unknown position '" + position + "', using default '" + MutableConstraints.P3 + "'"); // NOI18N
return p3Pane;
}
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
public JComponent getContainer() {
return rootSplitPane;
}
//~ Inner Classes ----------------------------------------------------------
/**
* DOCUMENT ME!
*
* @version $Revision$, $Date$
*/
private class FloatingFrameListener implements PropertyChangeListener {
//~ Methods ------------------------------------------------------------
/**
* This method gets called when a bound property is changed.
*
* @param evt A PropertyChangeEvent object describing the event source and the property that has changed.
*/
@Override
public void propertyChange(final PropertyChangeEvent evt) {
final FloatingFrame floatingFrame = (FloatingFrame)evt.getSource();
if (floatingFrame.getConfigurator().isSwapMenuBar()) {
if (logger.isDebugEnabled()) {
logger.debug("setting floating frame meneus visible: '" + !floatingFrame.isFloating() + "'"); // NOI18N
}
menuBar.setMoveableMenuesVisible(floatingFrame.getConfigurator().getId(), !floatingFrame.isFloating());
}
if (floatingFrame.getConfigurator().isSwapToolBar()) {
if (logger.isDebugEnabled()) {
logger.debug("setting floating frame toolbar visible: '" + !floatingFrame.isFloating() + "'"); // NOI18N
}
toolBar.setMoveableToolBarVisible(floatingFrame.getConfigurator().getId(), !floatingFrame.isFloating());
}
}
}
/**
* DOCUMENT ME!
*
* @version $Revision$, $Date$
*/
private class ConstrainsChangeListener implements PropertyChangeListener {
//~ Methods ------------------------------------------------------------
@Override
public void propertyChange(final PropertyChangeEvent e) {
if (e.getSource() instanceof MutableConstraints) {
final MutableConstraints constraints = (MutableConstraints)e.getSource();
if (logger.isDebugEnabled()) {
logger.debug("setting new value of property '" + e.getPropertyName() + "' of component '"
+ constraints.getId() + "'"); // NOI18N
}
final JTabbedPane tabbedPane = getTabbedPaneAt(constraints.getPosition());
final int index = tabbedPane.indexOfComponent(constraints.getContainer());
if (e.getPropertyName().equals("name")) // NOI18N
{
tabbedPane.setTitleAt(index, constraints.getName());
} else if (e.getPropertyName().equals("tooltip")) // NOI18N
{
tabbedPane.setToolTipTextAt(index, constraints.getToolTip());
} else if (e.getPropertyName().equals("icon")) // NOI18N
{
tabbedPane.setIconAt(index, constraints.getIcon());
} else if (e.getPropertyName().equals("position") || e.getPropertyName().equals("preferredIndex")) // NOI18N
{
// add() f\u00FChrt automatisch zu einem remove()
// doRemove(constraints);
// Extrawurst bei FLoatingFrame: Men\u00FCs und Toolbars entfernen
if (constraints.getContainerType().equals(MutableConstraints.FLOATINGFRAME)) {
removeFloatingFrame(constraints);
}
doAdd(constraints);
doSelect(constraints);
} else {
logger.warn("unsupported property change of '" + e.getPropertyName() + "'"); // NOI18N
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("unexpected property change event '" + e.getPropertyName() + "'"); // NOI18N
}
}
}
}
}