diff --git a/src/main/java/bdv/ij/BigDataBrowserPlugIn.java b/src/main/java/bdv/ij/BigDataBrowserPlugIn.java
index 96e072a..36069ee 100644
--- a/src/main/java/bdv/ij/BigDataBrowserPlugIn.java
+++ b/src/main/java/bdv/ij/BigDataBrowserPlugIn.java
@@ -1,5 +1,6 @@
package bdv.ij;
+import bdv.ij.util.SpringUtilities;
import ij.IJ;
import ij.ImageJ;
import ij.plugin.PlugIn;
@@ -7,25 +8,52 @@
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.net.Authenticator;
+import java.net.HttpURLConnection;
+import java.net.PasswordAuthentication;
import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.SpringLayout;
import mpicbg.spim.data.SpimDataException;
@@ -47,6 +75,8 @@ public class BigDataBrowserPlugIn implements PlugIn
public static String serverUrl = "http://";
+ public static String domain = "/public";
+
@Override
public void run( final String arg )
{
@@ -60,33 +90,259 @@ public void run( final String arg )
e.printStackTrace();
}
- final Object remoteUrl = JOptionPane.showInputDialog( null, "Enter BigDataServer Remote URL:", "BigDataServer",
- JOptionPane.QUESTION_MESSAGE, new ImageIcon( image ), null, serverUrl );
+ if ( null == arg || arg == "" )
+ {
+ final JRadioButton publicButton = new JRadioButton( "Public" );
+ publicButton.setActionCommand( "Public" );
+
+ final JRadioButton privateButton = new JRadioButton( "Private" );
+ privateButton.setActionCommand( "Private" );
+
+ ButtonGroup group = new ButtonGroup();
+ group.add( publicButton );
+ group.add( privateButton );
+
+ final JTextField id = new JTextField();
+ final JPasswordField password = new JPasswordField();
+
+ final JPanel userPanel = new JPanel( new SpringLayout() );
+ userPanel.setBorder( BorderFactory.createTitledBorder( "" ) );
+
+ userPanel.add( new JLabel( "Enter ID" ) );
+ userPanel.add( id );
+ userPanel.add( new JLabel( "Enter Password" ) );
+ userPanel.add( password );
+
+ SpringUtilities.makeCompactGrid( userPanel,
+ 2, 2, //rows, cols
+ 6, 6, //initX, initY
+ 6, 6 ); //xPad, yPad
+
+ for ( Component c : userPanel.getComponents() )
+ {
+ c.setEnabled( false );
+ }
+
+ Object[] inputFields = {
+ publicButton,
+ privateButton,
+ userPanel,
+ "Remote URL" };
+
+ publicButton.addActionListener( new ActionListener()
+ {
+ @Override public void actionPerformed( ActionEvent e )
+ {
+ for ( Component c : userPanel.getComponents() )
+ {
+ c.setEnabled( !publicButton.isSelected() );
+ }
+ }
+ } );
+
+ privateButton.addActionListener( new ActionListener()
+ {
+ @Override public void actionPerformed( ActionEvent e )
+ {
+ for ( Component c : userPanel.getComponents() )
+ {
+ c.setEnabled( privateButton.isSelected() );
+ }
+ }
+ } );
- if ( remoteUrl == null )
- return;
+ publicButton.setSelected( true );
- serverUrl = remoteUrl.toString();
+ final Object remoteUrl = JOptionPane.showInputDialog( null, inputFields, "BigDataServer",
+ JOptionPane.QUESTION_MESSAGE, new ImageIcon( image ), null, serverUrl );
- final ArrayList< String > nameList = new ArrayList< String >();
+ if ( remoteUrl == null )
+ return;
+
+ serverUrl = remoteUrl.toString();
+
+ if ( privateButton.isSelected() )
+ {
+ Authenticator.setDefault( new Authenticator()
+ {
+ protected PasswordAuthentication getPasswordAuthentication()
+ {
+ return new PasswordAuthentication( id.getText(), password.getPassword() );
+ }
+ } );
+ domain = "/private";
+ }
+ else
+ {
+ domain = "/public";
+ }
+ }
+ else
+ {
+ String line = null;
+ FileReader fileReader = null;
+
+ try
+ {
+ fileReader = new FileReader( new File( arg ) );
+ }
+ catch ( FileNotFoundException e )
+ {
+ e.printStackTrace();
+ }
+
+ BufferedReader br = new BufferedReader( fileReader );
+
+ try
+ {
+ if ( ( line = br.readLine() ) != null )
+ {
+ serverUrl = line;
+ }
+ }
+ catch ( IOException e )
+ {
+ e.printStackTrace();
+ }
+
+ if ( line == null )
+ return;
+ }
+
+ final ArrayList< Object > nameList = new ArrayList< Object >();
+
+ String tag = "";
try
{
- getDatasetList( serverUrl, nameList );
+ // TODO: search datasets by tag name should be provided soon
+ getDatasetList( serverUrl, nameList, tag );
}
catch ( final IOException e )
{
IJ.showMessage( "Error connecting to server at " + serverUrl );
e.printStackTrace();
}
- createDatasetListUI( serverUrl, nameList.toArray() );
+ catch ( NoSuchAlgorithmException e )
+ {
+ e.printStackTrace();
+ }
+ catch ( KeyManagementException e )
+ {
+ e.printStackTrace();
+ }
+ createDatasetListUI( tag, serverUrl, nameList.toArray() );
+ }
+
+ class DataSet
+ {
+ private final String index;
+ private final String name;
+ private final String description;
+ private final String tags;
+ private final String sharedBy;
+ private final Boolean isPublic;
+
+ DataSet( String index, String name, String description, String tags, String sharedBy, Boolean isPublic )
+ {
+ this.index = index;
+ this.name = name;
+ this.description = description;
+ this.tags = tags;
+ this.sharedBy = sharedBy;
+ this.isPublic = isPublic;
+ }
+
+ public String getIndex()
+ {
+ return index;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public String getTags()
+ {
+ return tags;
+ }
+
+ public String getSharedBy()
+ {
+ return sharedBy;
+ }
+
+ public Boolean isPublic()
+ {
+ return isPublic;
+ }
}
- private boolean getDatasetList( final String remoteUrl, final ArrayList< String > nameList ) throws IOException
+ class Category
{
- // Get JSON string from the server
- final URL url = new URL( remoteUrl + "/json/" );
+ private final String name;
+
+ Category( String name )
+ {
+ this.name = name;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+ }
+
+ private boolean getDatasetList( final String remoteUrl, final ArrayList< Object > nameList, final String searchTag ) throws IOException, NoSuchAlgorithmException, KeyManagementException
+ {
+ TrustManager[] trustAllCerts = new TrustManager[] {
+ new X509TrustManager()
+ {
+ public java.security.cert.X509Certificate[] getAcceptedIssuers()
+ {
+ return null;
+ }
+
+ public void checkClientTrusted( X509Certificate[] certs, String authType )
+ {
+ }
+
+ public void checkServerTrusted( X509Certificate[] certs, String authType )
+ {
+ }
- final InputStream is = url.openStream();
+ }
+ };
+
+ SSLContext sc = SSLContext.getInstance( "SSL" );
+ sc.init( null, trustAllCerts, new java.security.SecureRandom() );
+ HttpsURLConnection.setDefaultSSLSocketFactory( sc.getSocketFactory() );
+
+ // Create all-trusting host name verifier
+ HostnameVerifier allHostsValid = new HostnameVerifier()
+ {
+ public boolean verify( String hostname, SSLSession session )
+ {
+ return true;
+ }
+ };
+ // Install the all-trusting host verifier
+ HttpsURLConnection.setDefaultHostnameVerifier( allHostsValid );
+
+ String urlString = resolveRedirectedURL( remoteUrl + domain + "/tag/?name=" + URLEncoder.encode( searchTag, "UTF-8" ) );
+
+ final URL url = new URL( urlString );
+
+ URLConnection conn = url.openConnection();
+
+ System.out.println( url );
+
+ final InputStream is = conn.getInputStream();
final JsonReader reader = new JsonReader( new InputStreamReader( is, "UTF-8" ) );
reader.beginObject();
@@ -98,25 +354,35 @@ private boolean getDatasetList( final String remoteUrl, final ArrayList< String
reader.beginObject();
- String id = null, description = null, thumbnailUrl = null, datasetUrl = null;
+ String id = null, datasetName = null, tags = null, description = null, thumbnailUrl = null, datasetUrl = null, sharedBy = null;
+ Boolean isPublic = false;
+
while ( reader.hasNext() )
{
final String name = reader.nextName();
- if ( name.equals( "id" ) )
- id = reader.nextString();
+ if ( name.equals( "name" ) )
+ datasetName = reader.nextString();
else if ( name.equals( "description" ) )
description = reader.nextString();
else if ( name.equals( "thumbnailUrl" ) )
thumbnailUrl = reader.nextString();
else if ( name.equals( "datasetUrl" ) )
datasetUrl = reader.nextString();
+ else if ( name.equals( "tags" ) )
+ tags = reader.nextString();
+ else if ( name.equals( "index" ) )
+ id = reader.nextString();
+ else if ( name.equals( "sharedBy" ) )
+ sharedBy = reader.nextString();
+ else if ( name.equals( "isPublic" ) )
+ isPublic = reader.nextBoolean();
else
reader.skipValue();
}
if ( id != null )
{
- nameList.add( id );
+ nameList.add( new DataSet( id, datasetName, description, tags, sharedBy, isPublic ) );
if ( thumbnailUrl != null && StringUtils.isNotEmpty( thumbnailUrl ) )
imageMap.put( id, new ImageIcon( new URL( thumbnailUrl ) ) );
if ( datasetUrl != null )
@@ -133,7 +399,57 @@ else if ( name.equals( "datasetUrl" ) )
return true;
}
- private void createDatasetListUI( final String remoteUrl, final Object[] values )
+ private String resolveRedirectedURL( String url )
+ {
+ try
+ {
+ URL obj = new URL( url );
+
+ HttpURLConnection conn = ( HttpURLConnection ) obj.openConnection();
+ conn.setReadTimeout( 5000 );
+ conn.addRequestProperty( "Accept-Language", "en-US,en;q=0.8" );
+ conn.addRequestProperty( "User-Agent", "Mozilla" );
+
+ boolean redirect = false;
+
+ // normally, 3xx is redirect
+ int status = conn.getResponseCode();
+ if ( status != HttpURLConnection.HTTP_OK )
+ {
+ if ( status == HttpURLConnection.HTTP_MOVED_TEMP
+ || status == HttpURLConnection.HTTP_MOVED_PERM
+ || status == HttpURLConnection.HTTP_SEE_OTHER )
+ redirect = true;
+ }
+
+ if ( redirect )
+ {
+
+ // get redirect url from "location" header field
+ String newUrl = conn.getHeaderField( "Location" );
+
+ // get the cookie if need, for login
+ String cookies = conn.getHeaderField( "Set-Cookie" );
+
+ // open the new connnection again
+ conn = ( HttpURLConnection ) new URL( newUrl ).openConnection();
+ conn.setRequestProperty( "Cookie", cookies );
+ conn.addRequestProperty( "Accept-Language", "en-US,en;q=0.8" );
+ conn.addRequestProperty( "User-Agent", "Mozilla" );
+
+ return newUrl;
+ }
+
+ return url;
+ }
+ catch ( Exception e )
+ {
+ e.printStackTrace();
+ }
+ return url;
+ }
+
+ private void createDatasetListUI( final String tag, final String remoteUrl, final Object[] values )
{
final JList list = new JList( values );
list.setCellRenderer( new ThumbnailListRenderer() );
@@ -146,15 +462,20 @@ public void mouseClicked( final MouseEvent evt )
if ( evt.getClickCount() == 2 )
{
final int index = list.locationToIndex( evt.getPoint() );
- final String key = String.valueOf( list.getModel().getElementAt( index ) );
- System.out.println( key );
- try
- {
- BigDataViewer.view( datasetUrlMap.get( key ), new ProgressWriterIJ() );
- }
- catch ( final SpimDataException e )
+ final Object cell = list.getModel().getElementAt( index );
+
+ if ( cell instanceof DataSet )
{
- e.printStackTrace();
+ DataSet ds = ( DataSet ) cell;
+
+ try
+ {
+ BigDataViewer.view( ds.getName(), datasetUrlMap.get( ds.getIndex() ), new ProgressWriterIJ() );
+ }
+ catch ( final SpimDataException e )
+ {
+ e.printStackTrace();
+ }
}
}
}
@@ -164,7 +485,10 @@ public void mouseClicked( final MouseEvent evt )
scroll.setPreferredSize( new Dimension( 600, 800 ) );
final JFrame frame = new JFrame();
- frame.setTitle( "BigDataServer Browser - " + remoteUrl );
+ if ( tag.equals( "" ) )
+ frame.setTitle( "BigDataServer Browser - " + remoteUrl );
+ else
+ frame.setTitle( "BigDataServer Browser - " + remoteUrl + " searched by " + tag );
frame.add( scroll );
frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
frame.pack();
@@ -176,7 +500,7 @@ public class ThumbnailListRenderer extends DefaultListCellRenderer
{
private static final long serialVersionUID = 1L;
- Font font = new Font( "helvetica", Font.BOLD, 12 );
+ Font font = new Font( "helvetica", Font.PLAIN, 12 );
@Override
public Component getListCellRendererComponent(
@@ -186,9 +510,36 @@ public Component getListCellRendererComponent(
final JLabel label = ( JLabel ) super.getListCellRendererComponent(
list, value, index, isSelected, cellHasFocus );
- label.setIcon( imageMap.get( value ) );
- label.setHorizontalTextPosition( JLabel.RIGHT );
- label.setFont( font );
+
+ if ( value instanceof Category )
+ {
+ Category category = ( Category ) value;
+ label.setText( category.getName() );
+ label.setFont( label.getFont().deriveFont( Font.BOLD, 26 ) );
+ label.setBorder( BorderFactory.createEmptyBorder( 0, 5, 0, 0 ) );
+ }
+ else
+ {
+ DataSet ds = ( DataSet ) value;
+ label.setIcon( imageMap.get( ds.getIndex() ) );
+
+ StringBuilder sb = new StringBuilder( "" + ds.getName() + "
" );
+
+ if ( domain.equals( "/private" ) )
+ {
+ sb.append( "Public: " + ds.isPublic() + "
" );
+ if ( !ds.sharedBy.isEmpty() )
+ sb.append( "Shared by " + ds.getSharedBy() + "
" );
+ }
+
+ sb.append( "Tags: " + ds.getTags() + "
" );
+ sb.append( ds.getDescription() + "
" );
+
+ label.setText( sb.toString() );
+ label.setHorizontalTextPosition( JLabel.RIGHT );
+ label.setFont( font );
+ }
+
return label;
}
}
@@ -196,6 +547,7 @@ public Component getListCellRendererComponent(
public static void main( final String[] args )
{
ImageJ.main( args );
+ //new BigDataBrowserPlugIn().run( "/Users/moon/Desktop/local.bdv" );
new BigDataBrowserPlugIn().run( null );
}
}
diff --git a/src/main/java/bdv/ij/BigDataViewerPlugIn.java b/src/main/java/bdv/ij/BigDataViewerPlugIn.java
index 0e26d3b..6fdfd0b 100644
--- a/src/main/java/bdv/ij/BigDataViewerPlugIn.java
+++ b/src/main/java/bdv/ij/BigDataViewerPlugIn.java
@@ -23,80 +23,83 @@ public class BigDataViewerPlugIn implements PlugIn
@Override
public void run( final String arg )
{
- File file = null;
+ File file = getFile( arg );
- if ( Prefs.useJFileChooser )
+ if( file == null )
{
- final JFileChooser fileChooser = new JFileChooser();
- fileChooser.setSelectedFile( new File( lastDatasetPath ) );
- fileChooser.setFileFilter( new FileFilter()
+ if ( Prefs.useJFileChooser )
{
- @Override
- public String getDescription()
+ final JFileChooser fileChooser = new JFileChooser();
+ fileChooser.setSelectedFile( new File( lastDatasetPath ) );
+ fileChooser.setFileFilter( new FileFilter()
{
- return "xml files";
- }
+ @Override
+ public String getDescription()
+ {
+ return "xml files";
+ }
- @Override
- public boolean accept( final File f )
- {
- if ( f.isDirectory() )
- return true;
- if ( f.isFile() )
+ @Override
+ public boolean accept( final File f )
{
- final String s = f.getName();
- final int i = s.lastIndexOf('.');
- if (i > 0 && i < s.length() - 1) {
- final String ext = s.substring(i+1).toLowerCase();
- return ext.equals( "xml" );
- }
+ if ( f.isDirectory() )
+ return true;
+ if ( f.isFile() )
+ {
+ final String s = f.getName();
+ final int i = s.lastIndexOf('.');
+ if (i > 0 && i < s.length() - 1) {
+ final String ext = s.substring(i+1).toLowerCase();
+ return ext.equals( "xml" );
+ }
+ }
+ return false;
}
- return false;
- }
- } );
+ } );
- final int returnVal = fileChooser.showOpenDialog( null );
- if ( returnVal == JFileChooser.APPROVE_OPTION )
- file = fileChooser.getSelectedFile();
- }
- else // use FileDialog
- {
- final FileDialog fd = new FileDialog( ( Frame ) null, "Open", FileDialog.LOAD );
- fd.setDirectory( new File( lastDatasetPath ).getParent() );
- fd.setFile( new File( lastDatasetPath ).getName() );
- final AtomicBoolean workedWithFilenameFilter = new AtomicBoolean( false );
- fd.setFilenameFilter( new FilenameFilter()
+ final int returnVal = fileChooser.showOpenDialog( null );
+ if ( returnVal == JFileChooser.APPROVE_OPTION )
+ file = fileChooser.getSelectedFile();
+ }
+ else // use FileDialog
{
- private boolean firstTime = true;
-
- @Override
- public boolean accept( final File dir, final String name )
+ final FileDialog fd = new FileDialog( ( Frame ) null, "Open", FileDialog.LOAD );
+ fd.setDirectory( new File( lastDatasetPath ).getParent() );
+ fd.setFile( new File( lastDatasetPath ).getName() );
+ final AtomicBoolean workedWithFilenameFilter = new AtomicBoolean( false );
+ fd.setFilenameFilter( new FilenameFilter()
{
- if ( firstTime )
- {
- workedWithFilenameFilter.set( true );
- firstTime = false;
- }
+ private boolean firstTime = true;
- final int i = name.lastIndexOf( '.' );
- if ( i > 0 && i < name.length() - 1 )
+ @Override
+ public boolean accept( final File dir, final String name )
{
- final String ext = name.substring( i + 1 ).toLowerCase();
- return ext.equals( "xml" );
+ if ( firstTime )
+ {
+ workedWithFilenameFilter.set( true );
+ firstTime = false;
+ }
+
+ final int i = name.lastIndexOf( '.' );
+ if ( i > 0 && i < name.length() - 1 )
+ {
+ final String ext = name.substring( i + 1 ).toLowerCase();
+ return ext.equals( "xml" );
+ }
+ return false;
}
- return false;
- }
- } );
- fd.setVisible( true );
- if ( isMac() && !workedWithFilenameFilter.get() )
- {
- fd.setFilenameFilter( null );
+ } );
fd.setVisible( true );
- }
- final String filename = fd.getFile();
- if ( filename != null )
- {
- file = new File( fd.getDirectory() + filename );
+ if ( isMac() && !workedWithFilenameFilter.get() )
+ {
+ fd.setFilenameFilter( null );
+ fd.setVisible( true );
+ }
+ final String filename = fd.getFile();
+ if ( filename != null )
+ {
+ file = new File( fd.getDirectory() + filename );
+ }
}
}
@@ -114,6 +117,14 @@ public boolean accept( final File dir, final String name )
}
}
+ private File getFile( String arg )
+ {
+ final File file = new File( arg );
+ if( file.exists() )
+ return file;
+ else return null;
+ }
+
private boolean isMac()
{
final String OS = System.getProperty( "os.name", "generic" ).toLowerCase( Locale.ENGLISH );
diff --git a/src/main/java/bdv/ij/util/SpringUtilities.java b/src/main/java/bdv/ij/util/SpringUtilities.java
new file mode 100644
index 0000000..dc3ed9e
--- /dev/null
+++ b/src/main/java/bdv/ij/util/SpringUtilities.java
@@ -0,0 +1,250 @@
+package bdv.ij.util;
+
+/*
+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle or the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.swing.*;
+import javax.swing.SpringLayout;
+
+import java.awt.*;
+
+/**
+ * A 1.4 file that provides utility methods for
+ * creating form- or grid-style layouts with SpringLayout.
+ * These utilities are used by several programs, such as
+ * SpringBox and SpringCompactGrid.
+ */
+public class SpringUtilities
+{
+ /**
+ * A debugging utility that prints to stdout the component's
+ * minimum, preferred, and maximum sizes.
+ */
+ public static void printSizes( Component c )
+ {
+ System.out.println( "minimumSize = " + c.getMinimumSize() );
+ System.out.println( "preferredSize = " + c.getPreferredSize() );
+ System.out.println( "maximumSize = " + c.getMaximumSize() );
+ }
+
+ /**
+ * Aligns the first rows
* cols
+ * components of parent
in
+ * a grid. Each component is as big as the maximum
+ * preferred width and height of the components.
+ * The parent is made just big enough to fit them all.
+ * @param rows number of rows
+ * @param cols number of columns
+ * @param initialX x location to start the grid at
+ * @param initialY y location to start the grid at
+ * @param xPad x padding between cells
+ * @param yPad y padding between cells
+ */
+ public static void makeGrid( Container parent,
+ int rows, int cols,
+ int initialX, int initialY,
+ int xPad, int yPad )
+ {
+ SpringLayout layout;
+ try
+ {
+ layout = ( SpringLayout ) parent.getLayout();
+ }
+ catch ( ClassCastException exc )
+ {
+ System.err.println( "The first argument to makeGrid must use SpringLayout." );
+ return;
+ }
+
+ Spring xPadSpring = Spring.constant( xPad );
+ Spring yPadSpring = Spring.constant( yPad );
+ Spring initialXSpring = Spring.constant( initialX );
+ Spring initialYSpring = Spring.constant( initialY );
+ int max = rows * cols;
+
+ //Calculate Springs that are the max of the width/height so that all
+ //cells have the same size.
+ Spring maxWidthSpring = layout.getConstraints( parent.getComponent( 0 ) ).
+ getWidth();
+ Spring maxHeightSpring = layout.getConstraints( parent.getComponent( 0 ) ).
+ getHeight();
+ for ( int i = 1; i < max; i++ )
+ {
+ SpringLayout.Constraints cons = layout.getConstraints(
+ parent.getComponent( i ) );
+
+ maxWidthSpring = Spring.max( maxWidthSpring, cons.getWidth() );
+ maxHeightSpring = Spring.max( maxHeightSpring, cons.getHeight() );
+ }
+
+ //Apply the new width/height Spring. This forces all the
+ //components to have the same size.
+ for ( int i = 0; i < max; i++ )
+ {
+ SpringLayout.Constraints cons = layout.getConstraints(
+ parent.getComponent( i ) );
+
+ cons.setWidth( maxWidthSpring );
+ cons.setHeight( maxHeightSpring );
+ }
+
+ //Then adjust the x/y constraints of all the cells so that they
+ //are aligned in a grid.
+ SpringLayout.Constraints lastCons = null;
+ SpringLayout.Constraints lastRowCons = null;
+ for ( int i = 0; i < max; i++ )
+ {
+ SpringLayout.Constraints cons = layout.getConstraints(
+ parent.getComponent( i ) );
+ if ( i % cols == 0 )
+ { //start of new row
+ lastRowCons = lastCons;
+ cons.setX( initialXSpring );
+ }
+ else
+ { //x position depends on previous component
+ cons.setX( Spring.sum( lastCons.getConstraint( SpringLayout.EAST ),
+ xPadSpring ) );
+ }
+
+ if ( i / cols == 0 )
+ { //first row
+ cons.setY( initialYSpring );
+ }
+ else
+ { //y position depends on previous row
+ cons.setY( Spring.sum( lastRowCons.getConstraint( SpringLayout.SOUTH ),
+ yPadSpring ) );
+ }
+ lastCons = cons;
+ }
+
+ //Set the parent's size.
+ SpringLayout.Constraints pCons = layout.getConstraints( parent );
+ pCons.setConstraint( SpringLayout.SOUTH,
+ Spring.sum(
+ Spring.constant( yPad ),
+ lastCons.getConstraint( SpringLayout.SOUTH ) ) );
+ pCons.setConstraint( SpringLayout.EAST,
+ Spring.sum(
+ Spring.constant( xPad ),
+ lastCons.getConstraint( SpringLayout.EAST ) ) );
+ }
+
+ /* Used by makeCompactGrid. */
+ private static SpringLayout.Constraints getConstraintsForCell(
+ int row, int col,
+ Container parent,
+ int cols )
+ {
+ SpringLayout layout = ( SpringLayout ) parent.getLayout();
+ Component c = parent.getComponent( row * cols + col );
+ return layout.getConstraints( c );
+ }
+
+ /**
+ * Aligns the first rows
* cols
+ * components of parent
in
+ * a grid. Each component in a column is as wide as the maximum
+ * preferred width of the components in that column;
+ * height is similarly determined for each row.
+ * The parent is made just big enough to fit them all.
+ * @param rows number of rows
+ * @param cols number of columns
+ * @param initialX x location to start the grid at
+ * @param initialY y location to start the grid at
+ * @param xPad x padding between cells
+ * @param yPad y padding between cells
+ */
+ public static void makeCompactGrid( Container parent,
+ int rows, int cols,
+ int initialX, int initialY,
+ int xPad, int yPad )
+ {
+ SpringLayout layout;
+ try
+ {
+ layout = ( SpringLayout ) parent.getLayout();
+ }
+ catch ( ClassCastException exc )
+ {
+ System.err.println( "The first argument to makeCompactGrid must use SpringLayout." );
+ return;
+ }
+
+ //Align all cells in each column and make them the same width.
+ Spring x = Spring.constant( initialX );
+ for ( int c = 0; c < cols; c++ )
+ {
+ Spring width = Spring.constant( 0 );
+ for ( int r = 0; r < rows; r++ )
+ {
+ width = Spring.max( width,
+ getConstraintsForCell( r, c, parent, cols ).
+ getWidth() );
+ }
+ for ( int r = 0; r < rows; r++ )
+ {
+ SpringLayout.Constraints constraints =
+ getConstraintsForCell( r, c, parent, cols );
+ constraints.setX( x );
+ constraints.setWidth( width );
+ }
+ x = Spring.sum( x, Spring.sum( width, Spring.constant( xPad ) ) );
+ }
+
+ //Align all cells in each row and make them the same height.
+ Spring y = Spring.constant( initialY );
+ for ( int r = 0; r < rows; r++ )
+ {
+ Spring height = Spring.constant( 0 );
+ for ( int c = 0; c < cols; c++ )
+ {
+ height = Spring.max( height,
+ getConstraintsForCell( r, c, parent, cols ).
+ getHeight() );
+ }
+ for ( int c = 0; c < cols; c++ )
+ {
+ SpringLayout.Constraints constraints =
+ getConstraintsForCell( r, c, parent, cols );
+ constraints.setY( y );
+ constraints.setHeight( height );
+ }
+ y = Spring.sum( y, Spring.sum( height, Spring.constant( yPad ) ) );
+ }
+
+ //Set the parent's size.
+ SpringLayout.Constraints pCons = layout.getConstraints( parent );
+ pCons.setConstraint( SpringLayout.SOUTH, y );
+ pCons.setConstraint( SpringLayout.EAST, x );
+ }
+}