/******************************************************************************* * 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.uitools; import java.awt.BorderLayout; import java.awt.Component; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JPanel; import org.eclipse.persistence.tools.workbench.uitools.app.PropertyValueModel; import org.eclipse.persistence.tools.workbench.uitools.app.ValueModel; import org.eclipse.persistence.tools.workbench.utility.Transformer; /** * A <code>SwitcherPanel</code> will keeps its child component in synch * with a provided component holder. Alternatively, a value holder and a * transformer can be provided, and the panel will use the transformer to * convert the value into a component when necessary. If the component * to be displayed is null, nothing will be displayed. */ public class SwitcherPanel extends JPanel { /** * The value that drives which component will be displayed by the panel. */ private PropertyValueModel valueHolder; /** * The transformer that will convert the value, above, * into a component to be displayed by the panel. */ private Transformer transformer; /** * The listener that keeps us in synch with the value. */ private PropertyChangeListener listener; /** * Creates a new <code>SwitcherPanel</code> with a <code>BorderLayout</code>. */ private SwitcherPanel() { super(new BorderLayout()); this.initialize(); } /** * Creates a new <code>SwitcherPanel</code> that will display the * component generated by passing the specified value to the * specified transformer. * * @param valueHolder A <code>PropertyValueModel</code> holding the * value to be passed to the transformer to generate a component * to be displayed. * @param transformer A <code>Transformer</code> that converts * value into a component. */ public SwitcherPanel(PropertyValueModel valueHolder, Transformer transformer) { this(); this.initialize(valueHolder, transformer); } /** * Creates a new <code>SwitcherPanel</code> using the component * held by the specified component holder. * * @param componentHolder A <code>ValueModel</code> holding the * component to be displayed. */ public SwitcherPanel(PropertyValueModel componentHolder) { this(componentHolder, Transformer.NULL_INSTANCE); } protected void initialize() { this.listener = this.buildListener(); } /** * Creates the listener that will will keep us in sync with the value * holder. */ protected PropertyChangeListener buildListener() { return new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent e) { SwitcherPanel.this.valueChanged(e.getNewValue()); } public String toString() { return "value listener"; } }; } protected void initialize(PropertyValueModel pvm, Transformer t) { if (pvm == null) { throw new NullPointerException(); } this.valueHolder = pvm; this.valueHolder.addPropertyChangeListener(ValueModel.VALUE, this.listener); this.transformer = t; this.valueChanged(pvm.getValue()); } /** * The value has changed, transform it into a component and display * the component. */ protected void valueChanged(Object value) { Component oldComponent = null; Component newComponent = (Component) this.transformer.transform(value); // Remove the old component, if necessary if (this.getComponentCount() > 0) { oldComponent = this.getComponent(0); if (oldComponent == newComponent) { return; } this.remove(0); } if ((oldComponent == null) && (newComponent == null)) { return; } // Add the new pane, if necessary if (newComponent != null) { this.add(newComponent, BorderLayout.CENTER); } // Revalidate only if we are visible; otherwise, we will be // revalidated when we are displayed again if (this.isShowing()) { this.revalidate(); this.repaint(); } } }