/*******************************************************************************
* Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.tools.workbench.framework.internal;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.eclipse.persistence.tools.workbench.framework.app.EditorNode;
import org.eclipse.persistence.tools.workbench.framework.context.WorkbenchContext;
import org.eclipse.persistence.tools.workbench.framework.resources.ResourceRepository;
import org.eclipse.persistence.tools.workbench.uitools.app.ValueModel;
/**
* This view lays out a swappable properties page in a JPanel.
* When the selected node changes, the newly-selected node is asked for
* its properties page; and the previously selected node is notified that its
* properties page is no longer needed. The selected nodes must implement
* the EditorNode interface.
*
* @see org.eclipse.persistence.tools.workbench.framework.app.EditorNode
*/
abstract class AbstractEditorView {
private WorkbenchContext context;
/**
* The node whose properties page is currently
* displayed by the view. The node should never be null.
*/
private ValueModel nodeHolder;
EditorNode node;
private PropertyChangeListener nodeListener;
/**
* The currently displayed properties page.
*/
private Component propertiesPage;
/**
* The panel holding the current properties page.
*/
private JPanel panel;
// ********** constructors/initialization **********
AbstractEditorView(ValueModel nodeHolder, WorkbenchContext context) {
super();
if (nodeHolder == null) {
throw new NullPointerException();
}
this.nodeHolder = nodeHolder;
this.node = (EditorNode) this.nodeHolder.getValue();
this.nodeListener = this.buildNodeListener();
nodeHolder.addPropertyChangeListener(ValueModel.VALUE, this.nodeListener);
this.context = context;
this.propertiesPage = this.node.propertiesPage(null);
}
private PropertyChangeListener buildNodeListener() {
return new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
AbstractEditorView.this.nodeChanged((EditorNode) e.getNewValue());
}
};
}
// ********** queries **********
/**
* lazy-initialize the panel to give subclasses a chance to
* pass in stuff via the constructor
*/
Component getComponent() {
if (this.panel == null) {
this.panel = this.buildPanel();
this.installNewPropertiesPage();
}
return this.panel;
}
ResourceRepository resourceRepository() {
return this.context.getApplicationContext().getResourceRepository();
}
Component getPropertiesPage() {
return this.propertiesPage;
}
// ********** behavior **********
/**
* partially build the panel, the properties page will be added later...
*/
private JPanel buildPanel() {
JPanel result = new JPanel(new BorderLayout());
result.setBorder(BorderFactory.createEtchedBorder());
result.setMinimumSize(new Dimension(0, 0));
JLabel label = this.buildLabel();
label.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createMatteBorder(0, 0, 1, 0, result.getBackground().brighter()),
BorderFactory.createMatteBorder(0, 0, 1, 0, result.getBackground().darker())
),
BorderFactory.createEmptyBorder(2, 2, 2, 2)
)
);
label.setLabelFor(result);
result.add(label, BorderLayout.PAGE_START);
return result;
}
/**
* Build and return a label for the top of the view.
*/
abstract JLabel buildLabel();
/**
* the node has changed, remove the old properties page and
* install the new one
*/
void nodeChanged(EditorNode newNode) {
this.node.releasePropertiesPage(this.propertiesPage);
this.node = newNode;
Component newPropertiesPage = this.node.propertiesPage(this.context);
// if the node returns the same properties page as what we already have,
// do nothing; the page's contents will have been refreshed by the node
if (newPropertiesPage != this.propertiesPage) {
this.panel.remove(this.propertiesPage);
this.propertiesPage = newPropertiesPage;
this.installNewPropertiesPage();
}
}
/**
* the properties page has changed, put it in the panel
*/
void installNewPropertiesPage() {
this.panel.add(this.propertiesPage, BorderLayout.CENTER);
// since the panel is already displayed, we need to refresh it
if (this.panel.isVisible()) {
this.panel.revalidate();
this.panel.repaint();
}
}
/**
* This is called when the window containing the editor is closed.
*/
void close() {
this.nodeHolder.removePropertyChangeListener(ValueModel.VALUE, this.nodeListener);
}
}