>i'm having a problem "resetting" a display and associating it with a new
>data set. What i'd like to do is choose a set of data to render to a
>DisplayImplJ3D from a menu (the menus are all set up). When the user
>chooses the set of data from the menu, the application should go and read
>and load the new data from another data file and renderer it (using the
>same display and controls).
Bob,
I wrote a little application that lets you switch between multiple
Data objects in a single display. I've included the source below.
I don't know if there's a good way to reuse the same ContourWidget
object with a different Data object (and thus a different ScalarMap),
so my MultiData app just throws the old widgets away, then adds the
new widgets to the GUI. It works fine as long as you refresh the
layout of the widget's GUI panel using validate() and repaint().
Hope this helps you out.
-Curtis
-------
// MultiData.java
import java.awt.Dimension;
import java.awt.event.*;
import java.io.IOException;
import java.rmi.RemoteException;
import javax.swing.*;
import visad.*;
import visad.data.*;
import visad.java3d.DisplayImplJ3D;
/** Demonstrates how to switch multiple data objects
between a single display. */
public class MultiData extends JFrame {
/** imports data objects from the given list of files */
private static Data[] loadData(String[] files)
throws VisADException, RemoteException, BadFormException, IOException
{
DefaultFamily loader = new DefaultFamily("loader");
Data[] d = new Data[files.length];
for (int i=0; i<files.length; i++) {
try {
d[i] = loader.open(files[i]);
}
catch (BadFormException exc) {
exc.printStackTrace();
}
catch (IOException exc) {
exc.printStackTrace();
}
}
return d;
}
/** sets up the given display to use the specified data reference and data */
private static void setupDisplay(Display display, DataReferenceImpl ref,
Data data) throws VisADException, RemoteException
{
// get a list of decent mappings for this data
MathType type = data.getType();
ScalarMap[] maps = type.guessMaps(true);
// add the maps to the display
for (int i=0; i<maps.length; i++) {
display.addMap(maps[i]);
}
// add the data reference to the display
ref.setData(data);
display.addReference(ref);
}
/** constructs a new MultiData application */
public MultiData(String[] files) throws Exception {
// load all data files and set up VisAD display
final Data[] data = loadData(files);
final DisplayImplJ3D display = new DisplayImplJ3D("display");
final DataReferenceImpl ref = new DataReferenceImpl("ref");
setupDisplay(display, ref, data[0]);
// construct user interface
setTitle("Multiple data viewer");
JPanel pane = new JPanel();
setContentPane(pane);
pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));
JPanel left = new JPanel();
left.setLayout(new BoxLayout(left, BoxLayout.Y_AXIS));
left.add(display.getComponent());
final JComboBox combo = new JComboBox();
combo.setEditable(false);
for (int i=0; i<files.length; i++) {
combo.addItem(files[i]);
}
left.add(combo);
pane.add(left);
final JPanel widgetPanel = new JPanel();
widgetPanel.setPreferredSize(new Dimension(400, 0));
widgetPanel.setMaximumSize(new Dimension(400, Integer.MAX_VALUE));
widgetPanel.add(display.getWidgetPanel());
pane.add(widgetPanel);
// update the GUI whenever the user selects new data from the list
combo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int index = combo.getSelectedIndex();
try {
// remove the old widgets from the user interface
widgetPanel.remove(0);
// remove the old data from the display
display.removeReference(ref);
display.clearMaps();
// add the new data to the display
try {
setupDisplay(display, ref, data[index]);
}
catch (VisADException exc) {
exc.printStackTrace();
}
catch (RemoteException exc) {
exc.printStackTrace();
}
// add the new widgets to the user interface and refresh it
widgetPanel.add(display.getWidgetPanel());
widgetPanel.validate();
widgetPanel.repaint();
}
catch (VisADException exc) {
exc.printStackTrace();
}
catch (RemoteException exc) {
exc.printStackTrace();
}
}
});
}
/** tests the MultiData application */
public static void main(String[] argv) throws Exception {
if (argv.length < 2) {
System.err.println("Please specify at least two data files " +
"on the command line.");
System.exit(1);
}
MultiData md = new MultiData(argv);
md.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
md.setSize(700, 400);
md.setVisible(true);
}
}