/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package photoSpreadObjects.photoSpreadComponents;
import inputOutput.CsvWriter;
import inputOutput.InputOutput;
import java.awt.Component;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.File;
import java.rmi.NotBoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import photoSpread.PhotoSpread;
import photoSpread.PhotoSpreadException.BadUUIDStringError;
import photoSpread.PhotoSpreadException.CannotLoadImage;
import photoSpread.PhotoSpreadException.FormulaError;
import photoSpread.PhotoSpreadException.IllegalArgumentException;
import photoSpreadLoaders.CSVFileFilter;
import photoSpreadLoaders.ImageFileFilter;
import photoSpreadLoaders.PhotoSpreadFileImporter;
import photoSpreadObjects.PhotoSpreadObject;
import photoSpreadObjects.PhotoSpreadTableObject;
import photoSpreadTable.DnDSupport;
import photoSpreadTable.PhotoSpreadCell;
import photoSpreadTable.PhotoSpreadCell.CSVRecord;
import photoSpreadTable.PhotoSpreadCell.CSVSpreadsheet;
import photoSpreadUtilities.ComputableDimension;
import photoSpreadUtilities.Const;
import photoSpreadUtilities.Misc;
import photoSpreadUtilities.PhotoSpreadContextMenu;
import photoSpreadUtilities.ReconyxGroupingInteractor;
import photoSpreadUtilities.TreeSetRandomSubsetIterable;
import photoSpreadUtilities.PhotoSpreadContextMenu.PhotoSpreadRadioButtonSubMenu;
import photoSpreadUtilities.PhotoSpreadContextMenu.PhotoSpreadSubMenu;
/**
*
* @author skandel
*
* UI aspects of cells.
*/
public class ObjectsPanel extends JPanel{
private static final long serialVersionUID = 1L;
protected PhotoSpreadCell _displayedCell;
PhotoSpreadContextMenu _contextMenu = null;
PhotoSpreadSubMenu _sortSubmenu = null;
PhotoSpreadRadioButtonSubMenu _showSortKeySubmenu = null;
public ComputableDimension _maxDisplayedItemDim;
protected int _page = 0;
protected LinkedHashMap<PhotoSpreadObject, PhotoSpreadAddable> _drawnLabels;
public static final int NORMAL_LEFT_CLICK = MouseEvent.BUTTON1_DOWN_MASK & (~MouseEvent.SHIFT_DOWN_MASK | ~MouseEvent.CTRL_DOWN_MASK);
public static final int SHIFT_LEFT_CLICK = MouseEvent.SHIFT_DOWN_MASK;
public static final int CTRL_LEFT_CLICK = MouseEvent.CTRL_DOWN_MASK;
public static final int ALT_LEFT_CLICK = MouseEvent.ALT_DOWN_MASK;
private DraggableLabel _lastLabelClicked;
protected int _objWidth;
protected int _objHeight; // Currently always kept equal to _objWidth
/*************************************************
* Constructors
*************************************************/
public ObjectsPanel (boolean addContexMenu) {
this(null, addContexMenu);
}
public ObjectsPanel (PhotoSpreadCell thisPanelsCell) {
this(thisPanelsCell, Const.ADD_CELL_CONTEXT_MENU);
}
public ObjectsPanel(PhotoSpreadCell thisPanelsCell, boolean addContexMenu) {
if (thisPanelsCell != null)
_displayedCell = thisPanelsCell;
if (addContexMenu)
addContextMenu();
_page = 0;
_drawnLabels = new LinkedHashMap<PhotoSpreadObject,PhotoSpreadAddable>();
setLastLabelClicked(null);
set_objWidth(PhotoSpread.photoSpreadPrefs.getInt(PhotoSpread.sheetCellObjsWidthKey));
// All sheet cells are square, initially:
set_objHeight(PhotoSpread.photoSpreadPrefs.getInt(PhotoSpread.sheetCellObjsWidthKey));
setBorder(Const.cellBorder);
}
/*************************************************
* Internal Classes
*************************************************/
class ObjectsPanelKeyListener extends KeyAdapter {
public void keyTyped(KeyEvent e) {
if(e.getID() == KeyEvent.KEY_TYPED) {
// switch (KeyEvent.KEY_TYPED) {
switch (e.getKeyChar()) {
case KeyEvent.VK_C:
if(e.getModifiersEx() == KeyEvent.VK_CONTROL) {
selectAll();
break;
} // end case cnt-a pressed
default:
break;
}
}
}
} // end class ObjectPanelKeyListener
/*************************************************
* Methods
*************************************************/
/**
Redraw one sheet cell panel
* @throws NotBoundException
* @throws NumberFormatException
*/
public void redraw() throws NumberFormatException, NotBoundException{
redrawPanel();
}
public void setDisplayedCell(PhotoSpreadCell cell) {
_displayedCell = cell;
// _page = 0;
redrawPanel();
}
protected int getNumFittableObjsInCell() {
int theObjsPerPage = 0;
theObjsPerPage = PhotoSpread.photoSpreadPrefs.getInt(PhotoSpread.sheetObjsInCellKey);
return theObjsPerPage;
}
/**
* Redraws the panel
*/
public void redrawPanel(){
set_objWidth(PhotoSpread.photoSpreadPrefs.getInt(PhotoSpread.sheetCellObjsWidthKey));
// All sheet cells are square, initially:
set_objHeight(PhotoSpread.photoSpreadPrefs.getInt(PhotoSpread.sheetCellObjsWidthKey));
populatePanel(Math.max(1, (this.getWidth() / get_objWidth())), getNumFittableObjsInCell());
invalidate();
repaint();
// this.repaint(this.getBounds());
// this.paintBorder(getGraphics());
}
/**
* Populates one sheet cell
* with objects that are stored in the cell that is
* associated with this Objects panel.
*
* Caller is responsible for setting the _objWidth and
* _objHeight instance variables to the sizes that new
* instantiations of, for instance, photos, are to be
* dimensioned.
*
* @param numCols Number of columns to lay out
* @param numObjsFittableIntoThisCell Total number of objects to be shown in this panel
*/
public void populatePanel(int numCols, int numObjsFittableIntoThisCell){
if(_displayedCell == null) return;
PhotoSpreadObject oneObject = null;
TreeSetRandomSubsetIterable<PhotoSpreadObject> currCellObjs =
_displayedCell.getObjects();
int numCurrCellObjs = currCellObjs.size();
// The following used to be a slight
// optimization. But with the cell draw
// optimization, this quick return caused
// objects in a cell still to be visible
// even if they this cell was cleared of
// all objects in the model;
// if (numCurrCellObjs == 0)
// return;
// Remove all objects from this cell's panel:
this.removeAll();
setLastLabelClicked(null);
// Remember which labels are currently materialized in
// memory. This way we don't unnecessarily to to disk.
// TODO: We could save more of the images than just one
// pane. Right now it's just one pane's worth:
HashMap<PhotoSpreadObject, PhotoSpreadAddable> previousDrawnLabels =
new HashMap<PhotoSpreadObject,PhotoSpreadAddable>(_drawnLabels);
_drawnLabels.clear();
if (_displayedCell.isFormulaCell()) {
this.setToolTipText("" + numCurrCellObjs + " objects: " + _displayedCell.getFormula());
}
else {
this.setToolTipText("" + numCurrCellObjs + " objects");
}
if (numCurrCellObjs > 0) {
// Add cell's objects to this newly
// cleared cell panel:
Iterator<PhotoSpreadObject> cellObjIterator = null;
try {
// For now: always just show the first 10 or so objs in a cell:
cellObjIterator = currCellObjs.iterator(0, Math.min(numObjsFittableIntoThisCell, numCurrCellObjs));
} catch (IllegalArgumentException e) {
Misc.showErrorMsgAndStackTrace(e, "");
//System.err.println(e.getMessage());
//e.printStackTrace();
}
while (cellObjIterator.hasNext()) {
try {
oneObject = cellObjIterator.next();
} catch (java.util.NoSuchElementException e) {
System.err.println(e.getMessage());
}
if(oneObject != null){
// Try to get the cached image:
PhotoSpreadAddable addable = previousDrawnLabels.get(oneObject);
if (addable == null)
try {
addable = (PhotoSpreadAddable) getObjectComponent(oneObject, get_objHeight(), get_objWidth());
} catch (CannotLoadImage e) {
Misc.showErrorMsg(e.getMessage());
continue;
}
addable.setCell(_displayedCell);
JComponent thisComponent = addable.getComponent();
// thisComponent.setPreferredSize(new ComputableDimension(get_objHeight(), get_objWidth()));
DnDSupport.initComponentAsDragSource(thisComponent);
this.add(thisComponent);
_drawnLabels.put(oneObject, addable);
// If this just-drawn object is noted as 'selected'
// in the cell that we're drawing, then highlight
// this label:
if (_displayedCell.isObjectSelected(oneObject)) {
addable.highlight();
}
}
}
} // end if (numCurrObjs != 0) ... of adding cell's objects to this ObjectPanel
if(numCurrCellObjs == 0 && _displayedCell.isFormulaCell()){
this.add(new JLabel("(Empty Set)"));
}
}
/**
* Removes all images (DraggableLabesl) that are on the currently visible
* Workspace page from the layout.
*/
public void removeAllFromLayout() {
for (PhotoSpreadAddable draggableLabel : _drawnLabels.values())
this.getLayout().removeLayoutComponent(draggableLabel.getComponent());
}
protected Component getObjectComponent(PhotoSpreadObject object, int height, int width) throws CannotLoadImage {
if(object!= null){
return object.getObjectComponent(height, width);
}
return null;
}
void selectAll(){
Iterator<PhotoSpreadAddable> it = _drawnLabels.values().iterator();
while(it.hasNext()){
it.next().highlight();
}
this._displayedCell.selectAllObjects();
}
public void clearSelected(){
if (_drawnLabels.size() == 0) return;
Iterator<PhotoSpreadAddable> it = _drawnLabels.values().iterator();
while(it.hasNext()){
it.next().unhighlight();
}
this._displayedCell.deselectAll();
}
/**
* triggers that a label in the panel has been clicked
* @param label the label that was clicked
* @param clickType the type of click (NORMAL, SHIFT, CTRL)
*/
public boolean clickLabel(DraggableLabel label, int clickType){
// All but alt-left-click are handled here.
// So set the result optimistically to true,
// unless proven otherwise below:
boolean clickHandled = true;
PhotoSpreadCell cell = label.getCell();
// The PhotoSpreadObject that this label represents:
PhotoSpreadObject parentObject = label.getParentObject();
// If user was selecting/deselecting using the
// shift-arrow keys, then that activity is terminated
// with any mouse click:
WorkspaceSelector.endSelectionXaction();
switch(clickType){
case(ObjectsPanel.NORMAL_LEFT_CLICK):
if(cell.isObjectSelected(parentObject)){
cell.deselectObject(parentObject);
label.unhighlight();
}
else {
Iterator<PhotoSpreadAddable> it = _drawnLabels.values().iterator();
while(it.hasNext()){
it.next().unhighlight();
}
cell.deselectAll();
cell.selectObject(parentObject);
label.highlight();
}
break;
case(ObjectsPanel.CTRL_LEFT_CLICK):
if(cell.isObjectSelected(parentObject)){
cell.deselectObject(parentObject);
label.unhighlight();
}
else{
cell.selectObject(parentObject);
label.highlight();
}
break;
case(ObjectsPanel.SHIFT_LEFT_CLICK):
if(getLastLabelClicked() != null){
// I hate turning the values (i.e. Label objects) of the
// _drawnLabels LinkedHashMap into an array here. But that's
// what _drawnLabels used to be. I don't have time/patience to adjust
// the code in the remainder of this case branch to something
// nicer:
ArrayList<PhotoSpreadAddable> drawnLabelArray = new ArrayList<PhotoSpreadAddable>(_drawnLabels.values());
int lastClickIndex = drawnLabelArray.indexOf(getLastLabelClicked());
if (lastClickIndex < 0) {
Misc.showErrorMsg("Both items of a shift-click must be in one visible area.");
break;
}
int currentClickIndex = drawnLabelArray.indexOf(label);
if(lastClickIndex < currentClickIndex){
for(int i = lastClickIndex; i <= currentClickIndex; i++){
PhotoSpreadAddable l = drawnLabelArray.get(i);
l.highlight();
cell.selectObject(l.getParentObject());
}
}
else{
for(int i = currentClickIndex; i <= lastClickIndex; i++){
PhotoSpreadAddable l = drawnLabelArray.get(i);
l.highlight();
cell.selectObject(l.getParentObject());
}
}
}
break;
default:
clickHandled = false;
break;
}
setLastLabelClicked(label);
return clickHandled;
}
public Insets insets () {
return Const.tableCellInsets;
}
private void addContextMenu(){
_contextMenu = new PhotoSpreadContextMenu(_displayedCell);
_contextMenu.addMenuItem("Load Object Files Into this Cell",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
loadFiles(_displayedCell);
}
}
);
_contextMenu.addMenuItem("Import Objs and their Metadata Into this Cell from CSV",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
importFromCSV();
} catch (BadUUIDStringError e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
);
_contextMenu.addMenuItem("Export Metadata of this Cell's Objects to CSV",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
exportToCSV();
}
}
);
/* _contextMenu.addMenuItem("Refresh display",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
PhotoSpreadTableModel tModel = _displayedCell.getTableModel();
tModel.fireTableCellUpdated(_displayedCell.getRow(), _displayedCell.getColumn());
}
}
);
*/
// Specifying sort order:
addMetadataSortMenuItem();
_contextMenu.addMenuItem("Select All",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
selectAll();
}
}
);
_contextMenu.addMenuItem("Clear cell",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
clearCell();
}
}
);
/* _contextMenu.addMenuItem("Insert Table",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
loadTable();
}
}
);
*/
_contextMenu.addMenuItem("Copy",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
copy();
}
}
);
_contextMenu.addMenuItem("Paste",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
paste();
}
}
);
_contextMenu.addMenuItemSeparator();
_contextMenu.addMenuItem("Reconyx Group",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
ReconyxGroupingInteractor.performReconyxGrouping(_displayedCell);
}
}
);
this.addMouseListener(_contextMenu.getPopupListener());
}
private void copy(){
this._displayedCell.getTableModel().copyToClipboard();
}
private void paste(){
PhotoSpreadCell destCell = this._displayedCell;
PhotoSpreadCell sourceCell = null;
// Cannot paste into a cell with a formula:
if (destCell.isFormulaCell()) {
Misc.showErrorMsg("Cannot paste into a formula cell");
return;
}
destCell.setFormula(
Const.OBJECTS_COLLECTION_INTERNAL_TOKEN,
Const.DONT_EVAL, Const.DONT_REDRAW);
try {
sourceCell = (PhotoSpreadCell) destCell.getTableModel().getClipboard();
} catch (RuntimeException e) {
Misc.showErrorMsg(
"Items from cell " +
sourceCell.getCellAddress() +
" cannot be copy/pasted into " +
destCell.getCellAddress() +
".");
return;
}
// The following commented-out line properly creates an in-memory
// duplicate of these objects. This is a possible semantic for
// Copy/paste. But it seems too confusing to do this. Instead
// we have copy/paste just reference the original objects:
// destCell.assimilateObjects(sourceCell.getSelectedObjects());
destCell.addObjects(sourceCell.getSelectedObjects());
try {
destCell.evaluate(Const.DO_REDRAW);
} catch (FormulaError e) {
Misc.showErrorMsg(
"Objects from cell " +
sourceCell.getCellAddress() +
" cause the formula of cell " +
destCell.getCellAddress() +
" to become invalid.");
}
}
@SuppressWarnings("unused")
private void saveTable(){
InputOutput.saveTable(this, _displayedCell.getTableModel());
}
@SuppressWarnings("unused")
private void loadTableFromXML(){
InputOutput.loadTable(this, this._displayedCell.getTableModel());
}
/**
* Ask for a csv file name and import the
* PhotoSpreadObjects and their metadata from
* that csv file into the cell that contains
* this ObjectsPanel.
* @throws BadUUIDStringError
*/
private void importFromCSV() throws BadUUIDStringError{
// TODO: handle Excel format
File importFile = Misc.getCSVFileNameFromUser();
if (importFile == null)
// User cancelled out of the file chooser box:
return;
int numObjsInCellBeforeImport = _displayedCell.getObjects().size();
int numImportedCSVRecords =
PhotoSpreadFileImporter.importCSV(importFile, _displayedCell);
int numObjsInCellAfterImport = _displayedCell.getObjects().size();
if (numObjsInCellAfterImport > 0)
this._displayedCell.setFormula(Const.OBJECTS_COLLECTION_INTERNAL_TOKEN, Const.DO_EVAL, Const.DO_REDRAW);
// fireTableCellUpdated(); (Done in setFormula();
if (importFile != null)
JOptionPane.showMessageDialog(
this.getParent(),
"Done loading " +
importFile.getName() +
"' (" +
numImportedCSVRecords +
" CSV records, adding " +
(numObjsInCellAfterImport - numObjsInCellBeforeImport) +
" new objects to " +
_displayedCell.getCellAddress() +
").");
}
/**
* Ask for a target .csv file path and export all
* objects from this ObjectsPanel with their
* metadata to that .csv file.
*/
private void exportToCSV(){
String priorWriteDir = PhotoSpread.photoSpreadPrefs.getProperty(PhotoSpread.lastDirWrittenKey);
final JFileChooser fc = new JFileChooser(priorWriteDir);
CSVFileFilter filter = new CSVFileFilter();
fc.setFileFilter(filter);
fc.setMultiSelectionEnabled(false);
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
int returnVal = fc.showSaveDialog(this);
//In response to a button click:
//int returnVal = fc.showOpenDialog(this);
if(returnVal == JFileChooser.APPROVE_OPTION){
File exportFile = fc.getSelectedFile();
PhotoSpread.photoSpreadPrefs.setProperty(PhotoSpread.lastDirWrittenKey, exportFile.getParent());
// Make sure file gets a .csv extension:
try {
exportFile = new File (Misc.ensureFileExtension(exportFile.getPath(), "csv"));
} catch (java.text.ParseException e1) {
// Exception when a directory is passed into ensureFileExtension
// GUI file chooser prevents that.
e1.printStackTrace();
}
exportFile.setWritable(true);
try{
CsvWriter out = new CsvWriter(exportFile.getPath());
out.setConformToExcel(true);
CSVSpreadsheet csvObjectRecords = _displayedCell.toCSV();
Iterator<CSVRecord> row = csvObjectRecords.iterator();
while (row.hasNext()) {
out.writeRecord(row.next());
}
out.close();
}catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
JOptionPane.showMessageDialog(this.getParent(), "Done writing to '" + exportFile.getName() + "'.");
}
}
@SuppressWarnings("unused")
private void loadTable(){
PhotoSpreadTableObject t = new PhotoSpreadTableObject(_displayedCell);
this._displayedCell.addObject(t);
fireTableCellUpdated();
}
public static void loadFiles(PhotoSpreadCell cell){
final JFileChooser fc = new JFileChooser(PhotoSpread.photoSpreadPrefs.getProperty(PhotoSpread.lastDirReadKey));
ImageFileFilter filter = new ImageFileFilter();
fc.setFileFilter(filter);
fc.setMultiSelectionEnabled(true);
fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
//In response to a button click:
int returnVal = fc.showOpenDialog(null);
if (returnVal != JFileChooser.APPROVE_OPTION)
return;
loadFiles(cell, fc.getSelectedFiles());
}
public static boolean loadFiles (PhotoSpreadCell cell, ArrayList<File> fileObjList) {
return doFileLoading(cell, Misc.flattenFiles(fileObjList));
}
public static boolean loadFiles (PhotoSpreadCell cell, File[] fileObjArray) {
return doFileLoading(cell, Misc.flattenFiles(fileObjArray));
}
private static boolean doFileLoading (PhotoSpreadCell cell, ArrayList<File> files) {
try {
if (files.size() > 0)
PhotoSpread.photoSpreadPrefs.setProperty(PhotoSpread.lastDirReadKey, files.get(0).getParent());
for(int i = 0; i < files.size(); i++){
cell.addObject(files.get(i));
}
cell.setFormula(Const.OBJECTS_COLLECTION_INTERNAL_TOKEN, Const.DO_EVAL, Const.DO_REDRAW);
// fireTableCellUpdated(); (Done in setFormula();
} catch (Exception e) {
return false;
}
return true;
}
private void clearCell() {
if (JOptionPane.showConfirmDialog(
this, // Show dialog within the sheet window, not in center of screen (which null would do)
"Clear this cell? (Though no files will be affected)",
"Confirm", // Title
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
this._displayedCell.clear();
}
// fireTableCellUpdated(); (Called in the above clear() method.
}
protected void addMetadataSortMenuItem (){
_sortSubmenu = new PhotoSpreadSubMenu("Specify sort order");
_showSortKeySubmenu = new PhotoSpreadRadioButtonSubMenu ("See-&-Pick sort key (slow if many items)", _displayedCell);
_sortSubmenu.addMenuItem("Specify sort key",new java.awt.event.ActionListener() {
public void actionPerformed(ActionEvent e) {
requestSortKeyFromUserAndSort();
}
}
);
// Add the sort key collection menu to the sort submenu:
_sortSubmenu.addMenuItemSubMenu(_showSortKeySubmenu, null);
// Add the sort submenu to the main context menu:
_contextMenu.add(_sortSubmenu);
}
protected void requestSortKeyFromUserAndSort () {
if (_displayedCell.getObjects().isEmpty()) {
Misc.showInfoMsg(
"No objects to sort in cell " +
_displayedCell.getCellAddress() +
".",
this // Frame to show msg in.
);
return;
}
String sortField = (String) JOptionPane.showInputDialog (
_displayedCell.getTable(), // Window to center dialog box in
"Enter metadata field name to sort on:",
"Sort field entry", // Text in the title bar
JOptionPane.QUESTION_MESSAGE, // Type of msg (e.g. for the icon)
null, // icon
null, // array of selection values
PhotoSpreadContextMenu.getCurrentMetadataSortKey () // initial value in text box
);
if (sortField == null)
return;
if (sortField.isEmpty())
return;
PhotoSpreadContextMenu.setCurrentMetadataSortKey (sortField);
_displayedCell.sortObjects(sortField);
}
protected void set_objWidth(int _objWidth) {
this._objWidth = _objWidth;
}
protected int get_objWidth() {
return _objWidth;
}
protected void set_objHeight(int _objHeight) {
this._objHeight = _objHeight;
}
protected int get_objHeight() {
return _objHeight;
}
public void setLastLabelClicked(DraggableLabel lastLabelClicked) {
this._lastLabelClicked = lastLabelClicked;
}
public DraggableLabel getLastLabelClicked() {
return _lastLabelClicked;
}
public void fireTableCellUpdated() {
this._displayedCell.getTableModel().fireTableCellUpdated(_displayedCell.getRow(), _displayedCell.getColumn());
}
protected void setDrawnLabels(LinkedHashMap<PhotoSpreadObject,PhotoSpreadAddable> _drawnLabels) {
this._drawnLabels = _drawnLabels;
}
protected LinkedHashMap<PhotoSpreadObject,PhotoSpreadAddable> getDrawnLabels() {
return _drawnLabels;
}
public PhotoSpreadCell getDisplayedCell() {
return _displayedCell;
}
/**
* We consider all of the associated cell's
* objects to be the component count of this
* panel. Note that this number is different from
* the currently *displayed* number of components.
*
* @see java.awt.Container#getComponentCount()
*/
public int getUserComponentCount() {
// During startup some vars won't yet
// be initialized, causing null pt exceptions.
// In that case, return 0:
try {
return _displayedCell.getObjects().size();
} catch (Exception e) {
return 0;
}
}
/* public int getComponentCount () {
int orig = 0;
int mine = 0;
// During startup some vars won't yet
// be initialized, causing null pt exceptions.
// In that case, return 0:
try {
//********
orig = super.getComponentCount();
mine = _displayedCell.getObjects().size();
if (orig != mine) {
throw new InvalidParameterException();
}
//********
// return _displayedCell.getObjects().size();
return super.getComponentCount();
} catch (Exception e) {
if (orig != mine) {
System.out.println("Comps: orig:" + orig + ". Mine: " + mine);
try {
Thread.sleep(10);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
return 0;
}
}
*/
}