/*
* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.visualvm.core.ui;
import com.sun.tools.visualvm.core.datasource.DataSource;
import com.sun.tools.visualvm.core.datasource.descriptor.DataSourceDescriptor;
import com.sun.tools.visualvm.core.datasource.descriptor.DataSourceDescriptorFactory;
import com.sun.tools.visualvm.core.ui.DataSourceView.Alert;
import com.sun.tools.visualvm.uisupport.UISupport;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Image;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collections;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.openide.util.RequestProcessor;
import org.openide.util.WeakListeners;
import org.openide.windows.TopComponent;
/**
*
* @author Jiri Sedlacek
*/
class DataSourceWindow extends TopComponent implements PropertyChangeListener {
private static final RequestProcessor PROCESSOR =
new RequestProcessor("DataSourceWindow Processor", 5); // NOI18N
private int viewsCount = 0;
private DataSource dataSource;
private DataSourceDescriptor dataSourceDescriptor;
private DataSourceWindowTabbedPane.ViewContainer singleViewContainer;
private JPanel multiViewContainer;
private AlertListener alertListener;
public DataSourceWindow(DataSource dataSource) {
this.dataSource = dataSource;
initAppearance();
initComponents();
}
public DataSource getDataSource() {
return dataSource;
}
public void addView(DataSourceView view) {
if (viewsCount == 0) {
singleViewContainer = new DataSourceWindowTabbedPane.ViewContainer(new DataSourceCaption(dataSource), view);
add(singleViewContainer, BorderLayout.CENTER);
doLayout();
alertListener = new AlertListener();
} else if (viewsCount == 1) {
remove(singleViewContainer);
add(multiViewContainer, BorderLayout.CENTER);
tabbedContainer.addView(dataSource, singleViewContainer.getView());
tabbedContainer.addView(dataSource, view);
doLayout();
singleViewContainer.getCaption().finish();
singleViewContainer = null;
} else {
tabbedContainer.addView(dataSource, view);
}
viewsCount++;
view.addPropertyChangeListener(WeakListeners.propertyChange(alertListener,view));
}
public void selectView(DataSourceView view) {
if (viewsCount > 1) {
int viewIndex = indexOf(view);
if (viewIndex == -1) throw new RuntimeException("View " + view + " not present in DataSourceWindow " + this); // NOI18N
else tabbedContainer.setViewIndex(viewIndex);
}
}
public void removeView(final DataSourceView view) {
if (viewsCount == 1) {
if (view != singleViewContainer.getView()) throw new RuntimeException("View " + view + " not present in DataSourceWindow " + this); // NOI18N
remove(singleViewContainer);
singleViewContainer.getCaption().finish();
singleViewContainer = null;
} else {
int viewIndex = indexOf(view);
if (viewIndex == -1) throw new RuntimeException("View " + view + " not present in DataSourceWindow " + this); // NOI18N
else tabbedContainer.removeView(viewIndex);
if (viewsCount == 2) {
singleViewContainer = new DataSourceWindowTabbedPane.ViewContainer(new DataSourceCaption(dataSource), tabbedContainer.getViews().get(0));
remove(multiViewContainer);
tabbedContainer.removeView(0);
add(singleViewContainer, BorderLayout.CENTER);
doLayout();
}
}
PROCESSOR.post(new Runnable() {
public void run() { view.viewRemoved(); }
});
DataSourceWindowManager.sharedInstance().unregisterClosedView(view);
viewsCount--;
if (viewsCount == 0 && isOpened()) close();
}
public void removeAllViews() {
List<DataSourceView> views = getViews();
for (DataSourceView view : views) removeView(view);
}
public List<DataSourceView> getViews() {
if (viewsCount == 1) {
return Collections.singletonList(singleViewContainer.getView());
} else {
return tabbedContainer.getViews();
}
}
public boolean containsView(DataSourceView view) {
return indexOf(view) != -1;
}
private int indexOf(DataSourceView view) {
if (viewsCount == 1) {
return view == singleViewContainer.getView() ? 0 : -1;
} else {
return tabbedContainer.indexOfView(view);
}
}
protected final void componentActivated() {
super.componentActivated();
if (singleViewContainer != null) singleViewContainer.requestFocusInWindow();
else if (getComponentCount() > 0) getComponent(0).requestFocusInWindow();
}
protected final void componentClosed() {
dataSourceDescriptor.removePropertyChangeListener(this);
removeAllViews();
DataSourceWindowManager.sharedInstance().unregisterClosedWindow(this);
super.componentClosed();
}
public void propertyChange(final PropertyChangeEvent evt) {
String propertyName = evt.getPropertyName();
if (DataSourceDescriptor.PROPERTY_NAME.equals(propertyName)) {
SwingUtilities.invokeLater(new Runnable() {
public void run() { setName((String)evt.getNewValue()); }
});
} else if (DataSourceDescriptor.PROPERTY_ICON.equals(propertyName)) {
SwingUtilities.invokeLater(new Runnable() {
public void run() { setIcon((Image)evt.getNewValue()); }
});
} else if (tabbedContainer.isCloseEvent(evt)) {
removeView(tabbedContainer.getView((DataSourceWindowTabbedPane.ViewContainer)evt.getNewValue()));
}
}
private void initAppearance() {
dataSourceDescriptor = DataSourceDescriptorFactory.getDescriptor(dataSource);
dataSourceDescriptor.addPropertyChangeListener(this);
setName(dataSourceDescriptor.getName());
setIcon(dataSourceDescriptor.getIcon());
}
private void initComponents() {
setLayout(new BorderLayout());
// tabbedContainer
tabbedContainer = new DataSourceWindowTabbedPane();
tabbedContainer.addCloseListener(this);
// multiViewContainer
multiViewContainer = new JPanel(new BorderLayout());
if (UISupport.isAquaLookAndFeel()) {
multiViewContainer.setOpaque(true);
multiViewContainer.setBackground(UISupport.getDefaultBackground());
}
multiViewContainer.add(tabbedContainer, BorderLayout.CENTER);
add(multiViewContainer, BorderLayout.CENTER);
}
private void setAlert(DataSourceView view, Alert alert) {
int viewIndex = tabbedContainer.indexOfView(view);
tabbedContainer.setViewBackground(viewIndex,getAlertColor(alert));
if (alert != Alert.OK) {
requestAttention(false);
} else if (getApplicationAlert(alert) == Alert.OK) {
cancelRequestAttention();
}
}
private Color getAlertColor(final Alert alert) {
Color color = null;
switch (alert) {
case ERROR:
color = Color.RED;
break;
case WARNING:
color = Color.YELLOW;
break;
case OK:
color = null;
break;
}
return color;
}
private Alert getApplicationAlert(Alert alert) {
if (alert == Alert.ERROR) {
return alert;
}
for (DataSourceView view : getViews()) {
Alert a = view.getAlert();
if (a == Alert.ERROR) {
return a;
}
if (a == Alert.WARNING) {
alert = a;
}
}
return alert;
}
private DataSourceWindowTabbedPane tabbedContainer;
public int getPersistenceType() { return TopComponent.PERSISTENCE_NEVER; }
protected String preferredID() { return getClass().getName(); }
private class AlertListener implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent evt) {
if (DataSourceView.ALERT_PROP.equals(evt.getPropertyName())) {
setAlert((DataSourceView) evt.getSource(), (Alert) evt.getNewValue());
}
}
}
}