Portal WebMap search

Download Sample Viewer

Description

The sample shows how to search for web maps online using the Portal API classes.

Code snippet


  protected void openMap(PortalItem item) { 
    try { 
      closeExistingMap(); 
      JMap newMap = new JMap(); 
      showMapPanel(item.getItemId()); 
      WebMap webMap = WebMap.newInstance(item); 
      newMap.loadWebMap(webMap); 
      mapPanel.add(newMap); 
    } catch (Exception e) { 
      JOptionPane.showMessageDialog(_mainPanel, "An error occured: " + e.getLocalizedMessage(),  
          "Warning", JOptionPane.WARNING_MESSAGE); 
    } 
  }
  

Sample Code

/* Copyright 2014 Esri

All rights reserved under the copyright laws of the United States
and applicable international laws, treaties, and conventions.

You may freely redistribute and use this sample code, with or
without modification, provided you include the original copyright
notice and use restrictions.

See the use restrictions.*/
package com.esri.client.samples.webmap;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.basic.BasicProgressBarUI;

import com.esri.core.portal.Portal;
import com.esri.core.portal.PortalItem;
import com.esri.core.portal.PortalItemType;
import com.esri.core.portal.PortalQueryParams;
import com.esri.core.portal.PortalQueryResultSet;
import com.esri.core.portal.WebMap;
import com.esri.map.JMap;

/**
 * This sample shows how to search for web maps online using the Portal API classes.
 */
public class WebMapSearchApp {

  // the portal for this sample - standard public ArcGIS Online portal
  private static final String PORTAL_URL = "http://www.arcgis.com";
  private Portal _portal;

  // Swing components
  private JTextField textSearchField;
  private JPanel browseMapsPanel;
  private JPanel mapPanel;
  private JPanel _mainPanel;
  private JButton btnBack;
  private JLabel searchStatusLabel;
  private JLabel webMapStatusLabel;
  private JProgressBar progressBar;
  private JScrollPane scrollPaneSearch;

  private static final String RESULTS_PANEL = "RESULTS_PANEL";
  private static final String MAP_PANEL = "MAP_PANEL";
  private static final String PROGRESS_PANEL = "PROGRESS_PANEL";
  protected static final int NUM_RESULTS_PER_PAGE = 10;

  public WebMapSearchApp() {
    _portal = new Portal(PORTAL_URL, null);
  }

  /**
   * Starting point of this application: creates the window, creates an 
   * instance of this application and calls method to create the UI.
   * 
   * @param args any arguments
   */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          // instance of this application
          WebMapSearchApp application = new WebMapSearchApp();

          // create the UI, including the map, for the application
          JFrame appWindow = application.createWindow();
          appWindow.getContentPane().add(application.createUI());
          appWindow.setVisible(true);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
  }

  private JFrame createWindow() {
    JFrame window = new JFrame("Web Map Search application");
    window.setSize(1000, 600);
    window.setLocationRelativeTo(null);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setLayout(new BorderLayout());
    // dispose map just before application window is closed
    window.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent windowEvent) {
        super.windowClosing(windowEvent);
        closeExistingMap();
      }
    });
    return window;
  }

  /**
   * Created the user interface, along with running an initial default web map search.
   */
  public JComponent createUI() {

    JPanel contentPane = new JPanel();
    contentPane.setLayout(new BorderLayout());
    JToolBar toolBar = new JToolBar();
    contentPane.add(toolBar, BorderLayout.NORTH);
    
    JLabel searchInstructions = new JLabel("Search for web maps:  ");
    toolBar.add(searchInstructions);

    // Add search text box to toolbar and set it to handle the
    // enter key by performing a search.
    textSearchField = new JTextField();
    toolBar.add(textSearchField);
    textSearchField.setColumns(10);
    textSearchField.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent e) {
        performQuery(textSearchField.getText());
      }
    });

    // Add a search button to the toolbar.
    JButton btnSearch = new JButton("Search");
    btnSearch.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent e) {
        performQuery(textSearchField.getText());
      }
    });
    toolBar.add(btnSearch);

    // back button to the toolbar to return the user to the search results
    btnBack = new JButton("Back to Results");
    btnBack.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent e) {
        showResultsPanel(null);
      }
    });
    toolBar.add(btnBack);

    // Add a panel to contain the current web map and a panel for the search results to a card layout. 
    // The search results panel is inside a scroll pane. Both panels have their own status label.

    // map panel
    mapPanel = new JPanel();
    mapPanel.setLayout(new BorderLayout(0, 0));

    JPanel webMapStatus = new JPanel();
    webMapStatus.setLayout(new BoxLayout(webMapStatus, BoxLayout.LINE_AXIS));
    webMapStatus.setBorder(new EmptyBorder(5, 10, 5, 10));
    webMapStatus.setBackground(Color.DARK_GRAY);
    webMapStatusLabel = new JLabel(" ");
    webMapStatusLabel.setOpaque(true);
    webMapStatusLabel.setForeground(Color.WHITE);
    webMapStatusLabel.setBackground(Color.DARK_GRAY);
    webMapStatusLabel.setFont(PortalUI.TOP_STATUS_FONT);
    webMapStatus.add(webMapStatusLabel);

    JPanel statusAndWebMapPanel = new JPanel();
    statusAndWebMapPanel.setLayout(new BorderLayout(0, 1));
    statusAndWebMapPanel.add(mapPanel, BorderLayout.CENTER);
    statusAndWebMapPanel.add(webMapStatus, BorderLayout.NORTH);

    // search panel
    JPanel searchStatus = new JPanel();
    searchStatus.setBackground(Color.DARK_GRAY);
    searchStatus.setLayout(new BoxLayout(searchStatus, BoxLayout.LINE_AXIS));
    searchStatus.setBorder(new EmptyBorder(5, 10, 5, 10));
    searchStatusLabel = new JLabel(" ");
    searchStatusLabel.setOpaque(true);
    searchStatusLabel.setForeground(Color.WHITE);
    searchStatusLabel.setBackground(Color.DARK_GRAY);
    searchStatusLabel.setFont(PortalUI.TOP_STATUS_FONT);
    searchStatus.add(searchStatusLabel);

    browseMapsPanel = new JPanel();
    browseMapsPanel.setBackground(Color.WHITE);
    browseMapsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 8, 8) {
      private static final long serialVersionUID = 1L;
      int bottomPadding = 20;

      @Override
      public Dimension preferredLayoutSize(Container target) {
        synchronized (target.getTreeLock())
        {
          int hgap = getHgap();
          int vgap = getVgap();
          int width = target.getWidth();

          Insets insets = target.getInsets();
          if (insets == null)
            insets = new Insets(0, 0, 0, 0);
          int reqdWidth = 0;

          int maxwidth = width - (insets.left + insets.right + hgap * 2);
          int n = target.getComponentCount();
          int x = 0;
          int y = insets.top;
          int rowHeight = 0;

          for (int i = 0; i < n; i++) {
            Component c = target.getComponent(i);
            if (c.isVisible()) {
              Dimension dim = c.getPreferredSize();
              if ((x == 0) || ((x + dim.width) <= maxwidth)) {
                if (x > 0) {
                  x += hgap;
                }
                x += dim.width;
                rowHeight = Math.max(rowHeight, dim.height);
              } else {
                x = dim.width;
                y += vgap + rowHeight;
                rowHeight = dim.height;
              }
              reqdWidth = Math.max(reqdWidth, x);
            }
          }
          y += rowHeight;
          return new Dimension(reqdWidth+insets.left+insets.right, y + bottomPadding);
        }
      }
    });
    scrollPaneSearch = new JScrollPane(browseMapsPanel);
    scrollPaneSearch.setBorder(null);

    JPanel statusAndSearchPanel = new JPanel();
    statusAndSearchPanel.setLayout(new BorderLayout(0, 1));
    statusAndSearchPanel.add(scrollPaneSearch, BorderLayout.CENTER);
    statusAndSearchPanel.add(searchStatus, BorderLayout.NORTH);

    // to show a progress bar when a search is being performed
    JLayeredPane progressContainer = new JLayeredPane();
    progressContainer.setLayout(new BorderLayout());
    JPanel dummyPanel = new JPanel();
    Dimension preferredSize = new Dimension(1000, 700);
    dummyPanel.setBackground(Color.WHITE);
    dummyPanel.setPreferredSize(preferredSize);

    progressBar = createProgressBar(dummyPanel);
    progressContainer.add(progressBar);
    progressContainer.add(dummyPanel);

    JPanel progressPanel = new JPanel();
    progressPanel.setLayout(new BorderLayout(0, 1));
    progressPanel.add(progressContainer, BorderLayout.CENTER);

    // put panels in card layout panel
    _mainPanel = new JPanel();
    _mainPanel.setLayout(new CardLayout(0, 0));
    _mainPanel.add(statusAndSearchPanel, RESULTS_PANEL);
    _mainPanel.add(statusAndWebMapPanel, MAP_PANEL);
    _mainPanel.add(progressPanel, PROGRESS_PANEL);

    contentPane.add(_mainPanel, BorderLayout.CENTER);

    // Run an initial query
    performQuery("world");

    return contentPane;
  }

  /**
   * Opens the currently selected webmap.
   * 
   * @param item portal item to display as a webmap
   */
  protected void openMap(PortalItem item) {
    try {
      closeExistingMap();
      JMap newMap = new JMap();
      showMapPanel(item.getItemId());
      WebMap webMap = WebMap.newInstance(item);
      newMap.loadWebMap(webMap);
      mapPanel.add(newMap);
    } catch (Exception e) {
      JOptionPane.showMessageDialog(
          _mainPanel, 
          wrap("An error occured: "+ e.getLocalizedMessage()), 
          "Warning", JOptionPane.WARNING_MESSAGE);
    }
  }

  private void showProgressPanel(String progress) {
    CardLayout layout = (CardLayout) _mainPanel.getLayout();
    updateProgressBarUI(progress, true);
    layout.show(_mainPanel, PROGRESS_PANEL);
  }

  /**
   * Displays the map and enables the back button.
   */
  private void showMapPanel(String id) {
    CardLayout layout = (CardLayout) _mainPanel.getLayout();
    layout.show(_mainPanel, MAP_PANEL);
    webMapStatusLabel.setText("Currently viewing webmap with ID "+ id+" on portal "+ PORTAL_URL);
    btnBack.setEnabled(true);
  }

  /**
   * Displays the search results and disables the back button.
   */
  private void showResultsPanel(String statusText) {
    CardLayout layout = (CardLayout) _mainPanel.getLayout();
    layout.show(_mainPanel, RESULTS_PANEL);
    if (statusText != null) {
      searchStatusLabel.setText(statusText);
    }
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        scrollPaneSearch.getVerticalScrollBar().setValue(0);
      }
    });
    btnBack.setEnabled(false);
  }

  /**
   * Disposes the current map.
   */
  private void closeExistingMap() {
    if (mapPanel.getComponentCount() == 1){
      JMap oldMap = (JMap) mapPanel.getComponents()[0];
      mapPanel.remove(oldMap);
      oldMap.dispose();
    }
  }

  /**
   * Searches for items on the portal that match the given query string. This is
   * run as a background task inside a ProgressDialog which will be displayed
   * until the query completes.
   * 
   * @param queryString
   */
  private void performQuery(final String queryString) {

    String progressMessage = "Performing web map search with query string '"+ queryString +"'...";
    if (queryString == null || queryString.isEmpty()) {
      progressMessage = "Performing default web map search...";
    }
    showProgressPanel(progressMessage);

    browseMapsPanel.removeAll();
    browseMapsPanel.repaint();
    browseMapsPanel.revalidate();

    SwingWorker<MyPortalResult, Void> worker = 
        new SwingWorker<MyPortalResult, Void>() {
      private MyPortalResult results;

      @Override
      public MyPortalResult doInBackground() {
        PortalQueryParams queryParams = new PortalQueryParams();
        // query for web maps
        queryParams.setQuery(PortalItemType.WEBMAP, null, queryString);
        // max number of results to return
        queryParams.setLimit(NUM_RESULTS_PER_PAGE); // default is 10

        MyPortalResult myResult = new MyPortalResult();
        try {
          PortalQueryResultSet<PortalItem> portalItems = _portal.findItems(queryParams);
          ArrayList<MyItem> myItems = new ArrayList<>();
          for (PortalItem item : portalItems.getResults()) {
            myItems.add(new MyItem(item));
          }
          myResult.setItems(myItems);
          myResult.setNumResults(portalItems.getTotalResults());
        } catch (Exception e) {
          JOptionPane.showMessageDialog(
              _mainPanel, 
              wrap("An error occured: "+ e.getLocalizedMessage()), 
              "Warning", JOptionPane.WARNING_MESSAGE);
          e.printStackTrace();
        }
        return myResult;
      }

      @Override
      public void done() {
        try {
          results = get();
        } catch (InterruptedException e1) {
          e1.printStackTrace();
        } catch (ExecutionException e1) {
          e1.printStackTrace();
        }
        if (results == null) {
          showResultsPanel("No results for your search terms, please try another search.");
        } else {
          for (MyItem curItem: results.getItems()){
            final PortalItemPanel portalItemPanel = new PortalItemPanel(curItem);
            MouseAdapter mouseAdapter = new MouseAdapter() {
              @Override
              public void mouseClicked(MouseEvent e) {
                openMap(portalItemPanel.getItem());
              }
              @Override
              public void mouseEntered(MouseEvent e) {
                portalItemPanel.setBorder(PortalUI.SELECTED_BORDER);
                portalItemPanel.setCursor(PortalUI.SELECTED_CURSOR);
              }
              @Override
              public void mouseExited(MouseEvent e) {
                portalItemPanel.setBorder(PortalUI.UNSELECTED_BORDER);
                portalItemPanel.setCursor(Cursor.getDefaultCursor());
              }
            };
            portalItemPanel.addMouseListener(mouseAdapter);
            portalItemPanel.getTxtSnippetArea().addMouseListener(mouseAdapter);
            browseMapsPanel.add(portalItemPanel);
          }
          showResultsPanel("Showing top "+ (results.getNumResults() > NUM_RESULTS_PER_PAGE ? NUM_RESULTS_PER_PAGE : results.getNumResults()) + " of " + 
              results.getNumResults() + " results for query string '"+queryString+"'.");
        }
      }
    };
    worker.execute();
  }
  
  private class MyPortalResult {
    private ArrayList<MyItem> myItems;
    private int numResults;
    
    public int getNumResults() {
      return numResults;
    }
    public void setNumResults(int numResults) {
      this.numResults = numResults;
    }
    public ArrayList<MyItem> getItems() {
      return myItems;
    }
    public void setItems(ArrayList<MyItem> myItems) {
      this.myItems = myItems;
    }
    
  }

  /**
   * Creates a progress bar.
   * @param parent progress bar's parent. The horizontal axis of the progress bar will be
   * center-aligned to the parent.
   * @return a progress bar.
   */
  private static JProgressBar createProgressBar(final JComponent parent) {
    final JProgressBar progressBar = new JProgressBar();
    progressBar.setSize(400, 25);
    progressBar.setBackground(Color.DARK_GRAY);
    progressBar.setBorderPainted(false);
    progressBar.setForeground(Color.WHITE);
    progressBar.setUI(new BasicProgressBarUI() {
      @Override
      protected Color getSelectionBackground() { return Color.WHITE; }
      @Override
      protected Color getSelectionForeground() { return Color.DARK_GRAY; }
    });
    parent.addComponentListener(new ComponentAdapter() {
      @Override
      public void componentResized(ComponentEvent e) {
        progressBar.setLocation(
            parent.getWidth()/2 - progressBar.getWidth()/2,
            parent.getHeight()/2 - progressBar.getHeight()/2 - 20);
      }
    });
    progressBar.setStringPainted(true);
    progressBar.setIndeterminate(true);
    progressBar.setVisible(false);
    return progressBar;
  }

  /**
   * Updates progress bar UI from Swing's Event Dispatch Thread.
   * @param str string to be set.
   * @param visible flag to indicate visibility of the progress bar.
   */
  private void updateProgressBarUI(final String str, final boolean visible) {
    System.out.println(str);
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        if (str != null) {
          progressBar.setString(str);
        }
        progressBar.setVisible(visible);
      }
    }); 
  }
  
  private String wrap(String str) {
    // create a HTML string that wraps text when longer
    return "<html><p style='width:200px;'>" + str + "</html>";
  }
}
/* Copyright 2014 Esri

All rights reserved under the copyright laws of the United States
and applicable international laws, treaties, and conventions.

You may freely redistribute and use this sample code, with or
without modification, provided you include the original copyright
notice and use restrictions.

See the use restrictions.*/
package com.esri.client.samples.webmap;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;

import javax.swing.border.LineBorder;

public class PortalUI {

  public static final Color FOREGROUND_COLOR = Color.DARK_GRAY;
  public static final Color FOREGROUND_LIGHTER_COLOR = new Color(100, 100, 100);
  public static final Color BG_COLOR = Color.WHITE;
  public static final Font TITLE_FONT = new Font("Dialog", Font.BOLD, 14);
  public static final Cursor SELECTED_CURSOR = new Cursor(Cursor.HAND_CURSOR);
  public static final Cursor DEFAULT_CURSOR = Cursor.getDefaultCursor();
  public static final Font DESCRIPTION_FONT = new Font("Dialog", Font.PLAIN, 12);
  public static final Font OWNER_FONT = new Font("Dialog", Font.ITALIC, 12);
  public static final Font TOP_STATUS_FONT = new Font("Dialog", Font.ITALIC, 13);
  public static final LineBorder UNSELECTED_BORDER = new LineBorder(new Color(0, 0, 0, 0), 3);
  public static final LineBorder SELECTED_BORDER = new LineBorder(new Color(180, 180, 180), 3);
  public static final int DESC_WIDTH = 350;
  public static final int TH_WIDTH = 200 + 2;
  public static final int TH_HEIGHT = 133 + 2;
  public static final int TITLE_HEIGHT = 30;
  public static final int OWNER_HEIGHT = 20;

  public PortalUI() {
    super();
  }

}
/* Copyright 2014 Esri

All rights reserved under the copyright laws of the United States
and applicable international laws, treaties, and conventions.

You may freely redistribute and use this sample code, with or
without modification, provided you include the original copyright
notice and use restrictions.

See the use restrictions.*/
package com.esri.client.samples.webmap;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

import com.esri.core.portal.PortalItem;

/**
 * Create a panel that will display a thumbnail along with its description.
 *
 */
public class PortalItemPanel extends JPanel {

  private MyItem _item;
  private JTextArea txtSnippetArea;

  private static final long serialVersionUID = 1L;

  /**
   * Creates a portal item panel based on a portal item, using title, description, 
   * and thumbnail.
   * 
   * @param item
   */
  public PortalItemPanel (MyItem item) {
    _item = item;

    setLayout(new java.awt.BorderLayout(2, 2));
    setBackground(PortalUI.BG_COLOR);
    setForeground(PortalUI.FOREGROUND_COLOR);
    setBorder(PortalUI.UNSELECTED_BORDER);

    String title = item.getItem().getTitle();
    String description = "";
    if (item.getItem().getSnippet() == null) { 
      description = "<Missing description>";
    } else if (item.getItem().getSnippet().isEmpty() || item.getItem().getSnippet().length() < 6) {
      description = "<Missing description>";
    } else {
      description = item.getItem().getSnippet().trim();
    }

    // title
    String titleForLabel = title;
    if (title.length() > 45) {
      titleForLabel = title.substring(0, 42) + "...";
    }
    final JLabel labelTitle = new JLabel(titleForLabel);
    labelTitle.setForeground(PortalUI.FOREGROUND_COLOR);
    labelTitle.setFont(PortalUI.TITLE_FONT);
    labelTitle.setAlignmentX(Component.LEFT_ALIGNMENT);
    labelTitle.setOpaque(false);
    JPanel titlePanel = new JPanel();
    titlePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    titlePanel.setBackground(PortalUI.BG_COLOR);
    titlePanel.setAlignmentX(Component.LEFT_ALIGNMENT);
    Dimension titleDim = new Dimension(PortalUI.DESC_WIDTH, PortalUI.TITLE_HEIGHT);
    titlePanel.setPreferredSize(titleDim);
    titlePanel.setMaximumSize(titleDim);
    titlePanel.add(labelTitle);

    // thumbnail
    JLabel thumbnail;
    if (item.getIcon() == null) {
      thumbnail = new JLabel("<Missing Thumbnail>");
    } else {
      thumbnail = new JLabel(item.getIcon());
    }
    thumbnail.setForeground(Color.DARK_GRAY);
    thumbnail.setBackground(Color.WHITE);
    thumbnail.setAlignmentY(Component.TOP_ALIGNMENT);
    thumbnail.setAlignmentX(Component.LEFT_ALIGNMENT);
    thumbnail.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));

    final JPanel thumbnailPanel = new JPanel();
    thumbnailPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
    thumbnailPanel.setBackground(PortalUI.BG_COLOR);
    thumbnailPanel.setForeground(PortalUI.FOREGROUND_COLOR);
    Dimension dim = new Dimension(PortalUI.TH_WIDTH, PortalUI.TH_HEIGHT);
    thumbnailPanel.setMaximumSize(dim);
    thumbnailPanel.setMinimumSize(dim);
    thumbnailPanel.setPreferredSize(dim);
    thumbnailPanel.add(thumbnail);
    thumbnailPanel.revalidate();
    
    // description plain text
    txtSnippetArea = new JTextArea(description);
    txtSnippetArea.setFont(PortalUI.DESCRIPTION_FONT);
    txtSnippetArea.setForeground(PortalUI.FOREGROUND_COLOR);
    txtSnippetArea.setBackground(PortalUI.BG_COLOR);
    txtSnippetArea.setWrapStyleWord(true);
    txtSnippetArea.setLineWrap(true);
    txtSnippetArea.setEnabled(false);
    txtSnippetArea.setFocusable(false);
    txtSnippetArea.setDisabledTextColor(PortalUI.FOREGROUND_COLOR);
    txtSnippetArea.setAlignmentY(Component.TOP_ALIGNMENT);
    txtSnippetArea.setAlignmentX(Component.LEFT_ALIGNMENT);
    txtSnippetArea.setBorder(new EmptyBorder(0, 5, 0, 0));
    Dimension descDim = new Dimension(PortalUI.DESC_WIDTH, PortalUI.TH_HEIGHT - PortalUI.TITLE_HEIGHT - PortalUI.OWNER_HEIGHT);
    txtSnippetArea.setPreferredSize(descDim);
    txtSnippetArea.setMaximumSize(descDim);

    String ownerString = item.getItem().getOwner();
    String ownerLabelText = null;
    if (ownerString == null || ownerString.isEmpty()) {
      ownerLabelText = "";
    } else {
      ownerLabelText = "Web map by " + ownerString;
    }
    JLabel owner = new JLabel(ownerLabelText);
    owner.setBorder(new EmptyBorder(0, 5, 0, 0));
    owner.setForeground(PortalUI.FOREGROUND_LIGHTER_COLOR);
    owner.setFont(PortalUI.OWNER_FONT);
    
    JPanel titleAndDescription = new JPanel();
    titleAndDescription.setBackground(PortalUI.BG_COLOR);
    titleAndDescription.setLayout(new BoxLayout(titleAndDescription, BoxLayout.Y_AXIS));
    titleAndDescription.add(titlePanel);
    titleAndDescription.add(txtSnippetArea);
    titleAndDescription.add(owner);

    add(thumbnailPanel, BorderLayout.WEST);
    add(titleAndDescription, BorderLayout.CENTER);

    revalidate();
  }
  
  /**
   * Get access to the PortalItem this instance represents so we can display
   * it in a click handler later.
   * 
   * @return PortalItem used to create this instance
   */
  public PortalItem getItem(){
    return _item.getItem();
  }
  
  public JTextArea getTxtSnippetArea() {
    return txtSnippetArea;
  }
}
/* Copyright 2014 Esri

All rights reserved under the copyright laws of the United States
and applicable international laws, treaties, and conventions.

You may freely redistribute and use this sample code, with or
without modification, provided you include the original copyright
notice and use restrictions.

See the use restrictions.*/
package com.esri.client.samples.webmap;

import javax.swing.ImageIcon;

import com.esri.core.portal.PortalItem;

public class MyItem {
  PortalItem item = null;
  private boolean hasIcon = true;
  private ImageIcon icon = null;

  public ImageIcon getIcon() {
    return icon;
  }

  public void setIcon(ImageIcon icon) {
    this.icon = icon;
  }

  public MyItem(PortalItem item) {
    this.item = item;
    try {
      icon = new ImageIcon(item.fetchThumbnail());
    } catch (Exception e1) {
      System.out.println("exception on thumbnail fetch");
      System.out.println(item.getThumbnailFileName());
    }
    if (icon == null) {
      hasIcon = false;
    }
  }

  @Override
  public String toString() {
    return item.getTitle();
  }

  public PortalItem getItem() {
    return item;
  }

  public boolean isHasIcon() {
    return hasIcon;
  }
}
Feedback on this topic?