/*
* Copyright 2003-2008 Tufts University Licensed under the
* Educational Community License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may
* obtain a copy of the License at
*
* http://www.osedu.org/licenses/ECL-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS IS"
* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package tufts.vue;
import tufts.Util;
import tufts.vue.gui.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
/**
* DataFinder - replacement for old Digital Repository Browser (DRBrowser.java),
* currently use DataSourceHandler as a replacement for DataSourceViewer,
* tho would probably make more sense to move that code here instead
* of having DataSourceHandler at all, which is really just event handling
* code, and doesn't need to be a UI component at all, as it simply
* wraps a JList (previously, a DataSourceList).
*
* [ below comments are deprecated ]
*
* This single panel abstracts the collective handling of a list of
* selectable data sources, a search pane to be automatically
* displayed and updated when searchable data sources are selected,
* and a browse pane to be automatically populated and displayed when
* browseable data sources are selected.
*
* The impl provideds for either splitting these up as separate
* DockWindow's, or having them be combined into one panel as separate
* Widget's. This is probably overkill -- at this point -- we're
* unlikely to split these back up into separate windows. That version
* of the code is long untestest and probably out of date, and most
* everything is now actually handled by the DataSourceViewer,
* including the production and display of search-result panes when a
* search is run.
*
* This code, along with DataSourceViewer, DataSourceList, and
* DataSourceListCellRenderer, are due for collective refactoring. It
* would be best to do away with the JList / renderer impl, which adds
* much complexity, and doesn't get us much: we're unlikely to ever
* have so many data sources that the GUI performance gain of not
* having full-time swing components present for each data source line
* is worth it, and without having to go through a ListCellRenderer,
* we'd have much more flexibility in layout out, drawing and
* repainting the data sources (e.g., we could add spinners to loading
* data sources -- that's wouldn't possible now without adding a
* special timer thread to repaint the entire least each time the
* spinner wanted to draw the next image.)
*
* Also, it would be very handy to have a single interface or class
* that abstracts BOTH types of data-sources: OSID's (edu.tufts.vue.dsm.DataSource),
* and browseable VUE ("old-style") data sources (tufts.vue.DataSource).
* We'd probably need a delegating impl tho to handle that.
*
*
* @version $Revision: 1.1 $ / $Date: 2010-01-14 17:58:31 $ / $Author: sfraize $
*/
public class DataFinder extends WidgetStack
{
private static final org.apache.log4j.Logger Log = org.apache.log4j.Logger.getLogger(DataFinder.class);
public static final Object SEARCH_EDITOR = "search_editor_layout_constraint";
public static final Object SEARCH_RESULT = "search_result_layout_constraint";
final JComponent searchPane = new Widget("Search") {
private Component editor, result;
{
setOpaque(false);
}
@Override
protected void addImpl(Component c, Object constraints, int idx) {
if (DEBUG.DR) out("SEARCH-WIDGET addImpl: " + GUI.name(c) + " " + constraints + " idx=" + idx);
JComponent jc = null;
if (c instanceof JComponent)
jc = (JComponent) c;
if (constraints == SEARCH_EDITOR) {
if (editor != null)
remove(editor);
editor = c;
constraints = BorderLayout.NORTH;
if (jc != null)
jc.setBorder(GUI.WidgetInsetBorder);
} else if (constraints == SEARCH_RESULT) {
// this method of setting this is a crazy hack for now, but
// it's perfect for allowing us to try different layouts
resultsPane.removeAll();
resultsPane.add(jc);
resultsPane.setHidden(false);
resultsPane.validate();
} else {
tufts.Util.printStackTrace("illegal search pane constraints: " + constraints);
}
//constraints = bc;
super.addImpl(c, constraints, idx);
revalidate();
}
//public void doLayout() { GUI.dumpSizes(this, "doLayout"); super.doLayout(); }
//public void setPreferredSize(Dimension d) { Util.printStackTrace("setPreferredSize " + d);}
//public void setLayout(LayoutManager m) {Util.printStackTrace("setLayout; " + m);super.setLayout(m);}
};
final Widget sourcesPane = new Widget("Sources");
final Widget browsePane = new Widget("Browse");
final Widget resultsPane = new Widget("Search Results");
private JLabel loadingLabel;
private Class[] includedSources;
private Class[] excludedSources;
private DataSourceHandler DSH;
public DataFinder(String name, Class[] included, Class[] excluded)
{
includedSources = included;
excludedSources = excluded;
//super(new BorderLayout());
if (DEBUG.DR || DEBUG.INIT) out("DataFinder construct");
setName(name);
//Dimension startSize = new Dimension(300,160);
//setPreferredSize(startSize);
//setMinimumSize(startSize);
//this.dockWindow = dockWindow;
//this.dockWindow = resourceDock;
//this.resourceDock = resourceDock;
//this.searchDock = searchDock;
//this.sourcesPane = this;
//setOpaque(true);
//setBackground(Color.white);
buildWidgets();
//if (delayedLoading) {
if (true) {
// if (Util.isMacLeopard()) {
// JProgressBar bar = new JProgressBar();
// bar.setAlignmentX(SwingConstants.CENTER); // no effect
// bar.setIndeterminate(true);
// bar.putClientProperty("JProgressBar.style", "circular");
// bar.setString("Loading...");// no effect
// bar.setStringPainted(true); // no effect
// add(bar);
// }
loadingLabel = new JLabel(VueResources.getString("dockWindow.Resources.loading.label"), SwingConstants.CENTER);
loadingLabel.setMinimumSize(new Dimension(150, 80));
loadingLabel.setBorder(new EmptyBorder(8,0,8,0));
GUI.apply(GUI.StatusFace, loadingLabel);
sourcesPane.add(loadingLabel);
} else {
loadDataSourceViewer();
}
buildUI();
if (DEBUG.DR || DEBUG.INIT) out("Instantiated.");
}
private void buildUI()
{
resultsPane.setTitleHidden(true);
resultsPane.setHidden(true);
//WidgetStack stack = new WidgetStack(getName());
Widget.setWantsScroller(this, true);
// TODO: can any of these (beyond refresh), ever have an effect?
Widget.setHelpAction(this,VueResources.getString("dockWindow.Resources.libraryPane.helpText"));;
//Widget.setMiscAction(this, new MiscActionMouseListener(), "dockWindow.addButton");
Widget.setHelpAction(browsePane,VueResources.getString("dockWindow.Resources.browsePane.helpText"));;
Widget.setHelpAction(resultsPane,VueResources.getString("dockWindow.Resources.resultsPane.helpText"));;
Widget.setHelpAction(searchPane,VueResources.getString("dockWindow.Resources.searchPane.helpText"));;
Widget.setRefreshAction(browsePane, new MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent e) {
DSH.refreshBrowser();
//Log.error("UNIMPLEMENTED: REFRESH BROWSER");
}
});
addPane(sourcesPane, 0f);
addPane(searchPane, 0f);
addPane(browsePane, 1f);
addPane(resultsPane, 0f);
// if (false) {
// JLabel startLabel = new JLabel("Search Results", JLabel.CENTER);
// startLabel.setPreferredSize(new Dimension(100, 100));
// startLabel.setBorder(new MatteBorder(1,0,0,0, Color.darkGray));
// resultsPane.add(startLabel);
// }
//this.dockWindow.setContent(stack);
}
private void buildWidgets()
{
Dimension startSize = new Dimension(tufts.vue.gui.GUI.isSmallScreen() ? 250 : 400,
100);
//-----------------------------------------------------------------------------
// Search
//-----------------------------------------------------------------------------
searchPane.setBackground(Color.white);
JLabel please = new JLabel(VueResources.getString("jlabel.searchableresource"), JLabel.CENTER);
GUI.apply(GUI.StatusFace, please);
searchPane.add(please, SEARCH_EDITOR);
//-----------------------------------------------------------------------------
// Local File Data Source and Favorites
//-----------------------------------------------------------------------------
try {
browsePane.setBackground(Color.white);
browsePane.setExpanded(false);
browsePane.setLayout(new BorderLayout());
//startSize = new Dimension(tufts.vue.gui.GUI.isSmallScreen() ? 250 : 400, 300);
//startSize.height = GUI.GScreenHeight / 5;
//browsePanel.setPreferredSize(startSize);
if (false) {
// SMF 2008-04-17: This is redundant, and can dramatically slow down startup,
// and make diagnosing problems much harder. Appears vestigal.
LocalFileDataSource localFileDataSource = new LocalFileDataSource("My Computer","");
JComponent comp = localFileDataSource.getResourceViewer();
comp.setVisible(true);
browsePane.add(comp);
}
} catch (Exception ex) {
if (DEBUG.DR) out("Problem loading local file library");
}
//-----------------------------------------------------------------------------
// Saved Resources
//-----------------------------------------------------------------------------
//savedResourcesPane.setBackground(Color.white);
//savedResourcesPane.setPreferredSize(startSize);
//savedResourcesPane.add(new JLabel("saved resources"));
if (DEBUG.DR) out("build widgets complete");
}
public void loadDataSourceViewer()
{
Log.debug("loading the DataSourceViewer...");
try {
// TODO: DataSourceHandler shouldn't really be an AWT component -- it just
// wraps a data-sources list -- it's code is just about handling the user interactions
//DataSourceHandler DSH = new DataSourceHandler(this, includedSources, excludedSources);
DSH = new DataSourceHandler(this, includedSources, excludedSources);
DSH.setName("dataSourceHandler");
/*
if (dsViewer == null) {
// set the statics to the first initialized DRBrowser only
dsViewer = dsv;
//tufts.vue.VUE.dataSourceViewer = dsv;
}
*/
// if (loadingLabel != null)
// sourcesPane.remove(loadingLabel);
sourcesPane.removeAll();
sourcesPane.add(DSH);
revalidate();
// must do this to get re-laid out: apparently, the hierarchy
// events from the add don't automatically do this!
// TODO; As the DSV top-level is normally a scroll-pane, it's
// preferred/min size is useless (always will go down
// to one line), so either we'll need a manual size
// set anytime there's a scroll pane, or maybe the WidgetStack
// can detect the scroll pane, and look at the pref size of it's
// contents.
//setPreferredSize(dsv.getPreferredSize());
} catch (Throwable e) {
Log.error(e);
e.printStackTrace();
loadingLabel.setText(e.toString());
}
if (DEBUG.DR || DEBUG.Enabled) out("done loading DataSourceViewer");
}
private static void out(String s) {
//System.out.println("DRBrowser: " + s);
Log.info(s);
}
// public static void main(String args[])
// {
// VUE.init(args);
// // Frame owner = new Frame("parentWindow");
// // owner.setVisible(true);
// // //owner.setFocusable(true);
// // //owner.setFocusableWindowState(true);
// Log.debug("loading disk cache...");
// Images.loadDiskCache();
// Log.debug("loading disk cache: done");
// DockWindow.setManagedWindows(false);
// DockWindow drDock = GUI.createDockWindow("Content");
// //DockWindow drDock = new DockWindow("Content", owner);
// DataFinder drBrowser = new DataFinder(true, drDock);
// //drDock.setFocusableWindowState(true);
// tufts.vue.ui.InspectorPane inspectorPane = new tufts.vue.ui.InspectorPane();
// //ObjectInspector = GUI.createDockWindow("Info");
// //ObjectInspector.setContent(inspectorPane.getWidgetStack());
// DockWindow inspector = GUI.createDockWindow("Info", new tufts.vue.ui.InspectorPane());
// //DockWindow inspector = new DockWindow("Info", owner, inspectorPane.getWidgetStack(), false);
// inspector.setMenuName("Info / Preview");
// VUE._setInfoDock(inspector);
// int maxHeight = GUI.getMaximumWindowBounds().height;
// int inspectorWidth = GUI.GScreenWidth / 2;
// if (inspectorWidth > 800)
// inspectorWidth = 800;
// inspector.setSize(inspectorWidth, maxHeight);
// inspector.setUpperRightCorner(GUI.GScreenWidth, GUI.GInsets.top);
// inspector.setVisible(true);
// inspector.setFocusableWindowState(true);
// drDock.setSize(300, (int) (GUI.GScreenHeight * 0.75));
// drDock.setUpperRightCorner(GUI.GScreenWidth - inspector.getWidth(), GUI.GInsets.top);
// drDock.setVisible(true);
// drDock.setFocusableWindowState(true);
// drBrowser.loadDataSourceViewer();
// GUI.invokeAfterAWT(new Runnable() { public void run() {
// DataSourceViewer.cacheDataSourceViewers();
// }});
// DataSourceViewer.configureOSIDs();
// }
}