/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package photoSpreadObjects.photoSpreadComponents;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
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.MouseWheelEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.rmi.NotBoundException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import photoSpread.PhotoSpread;
import photoSpreadObjects.PhotoSpreadObject;
import photoSpreadTable.PhotoSpreadCell;
import photoSpreadTable.PhotoSpreadDragDropManager;
import photoSpreadTable.PredictableEquiSizedGridLayout;
import photoSpreadUtilities.ComputableDimension;
import photoSpreadUtilities.Const;
import photoSpreadUtilities.Misc;
import photoSpreadUtilities.SuperPositioner;
import photoSpreadUtilities.Zoomer;
import photoSpreadUtilities.Const.Direction;
import photoSpreadUtilities.Misc.ShowHelpAction;
/**
*
* @author skandel
*/
/**
* Modification History Jul-4-2008 Initialized min/max values of workspace image
* slider (_colNumSetSlider) to 1 and 100, respectively. The default zero causes
* div-by-zero later on.
*
*/
public class Workspace extends JFrame {
private static final long serialVersionUID = 1L;
private WorkspaceObjectsPanel _workspacePanel;
JFrame _theSheetWindow;
private JSlider _colNumSetSlider;
private JSlider _objHeightSetSlider;
JButton _nextSet;
JButton _prevSet;
JButton _homeSet;
JButton _endSet;
JLabel _pageViewer;
JButton _testButton;
JButton _zoomButton;
JPanel _navPanel = new JPanel();
private boolean _disabledColNumSliderService = false;
private boolean _disabledObjHeightSliderService = false;
SuperPositioner _resizeOverlay;
protected int _userPrefWindowHeight = Const.INVALID;
/*************************************************
* Constructors
*************************************************/
public Workspace(JFrame theSheetWindow) {
_theSheetWindow = theSheetWindow;
// Set up the main window:
this.setBackground(Color.BLACK);
this.setForeground(Color.WHITE);
// Setup the photos/row slider:
setColNumSetSlider(new JSlider(JSlider.HORIZONTAL, 0, 30, 1)); // Min/Max/initial
// values:
// 0/30/1
getColNumSetSlider().setMajorTickSpacing(2);
getColNumSetSlider().setMinorTickSpacing(1);
getColNumSetSlider().setPaintTicks(true);
getColNumSetSlider().setPaintLabels(true);
getColNumSetSlider().setToolTipText(
"Modifies number of Workspace objects per row.");
// Set up the object height adjuster:
// Min/Max values: 10/110%. Initial: 100%
setObjHeightSetSlider(new JSlider(JSlider.VERTICAL, 10, 110, 100)); // Min/Max/initial
// values:
// 10/110/100
getObjHeightSetSlider().setMajorTickSpacing(10);
// _objHeightSetSlider.setMinorTickSpacing(1);
getObjHeightSetSlider().setPaintTicks(true);
getObjHeightSetSlider().setPaintLabels(true);
getObjHeightSetSlider().setToolTipText(
"Modifies size of Workspace objects");
this.setTitle("PhotoSpread Workspace");
// We'll catch close-window operations in
// the window listener methods below:
this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
this.setLayout(new BorderLayout());
_workspacePanel = new WorkspaceObjectsPanel(this);
_workspacePanel.setPreferredSize(new ComputableDimension(
PhotoSpread.photoSpreadPrefs
.getInt(PhotoSpread.workspaceObjWidthKey),
PhotoSpread.photoSpreadPrefs
.getInt(PhotoSpread.workspaceObjHeightKey)));
// Enable arrow shift-arrow-keys on the Workspace panel:
WorkspaceSelector.init(this);
this.add(_workspacePanel, BorderLayout.CENTER);
this.add(getColNumSetSlider(), BorderLayout.NORTH);
this.add(getObjHeightSetSlider(), BorderLayout.WEST);
initializeButtons();
_pageViewer = new JLabel("1/1");
_navPanel.add(_zoomButton);
// _navPanel.add(_testButton);
/*
* Dimension zoomButtonSpaceOnRightDim = new Dimension
* (Const.WorkspaceNavBarButtonGroupSpace, 0); Box.Filler filler = new
* Box.Filler( zoomButtonSpaceOnRightDim, zoomButtonSpaceOnRightDim,
* zoomButtonSpaceOnRightDim);
*
* _navPanel.add(filler);
*/
_navPanel.add(Box.createHorizontalStrut(5));
JSeparator sep = new JSeparator(SwingConstants.VERTICAL);
sep.setPreferredSize(new Dimension(2, 0));
_navPanel.add(sep);
_navPanel.add(Box.createHorizontalStrut(5));
_navPanel.add(_homeSet);
_navPanel.add(_prevSet);
_navPanel.add(_nextSet);
_navPanel.add(_endSet);
_navPanel.add(_pageViewer);
_homeSet.setEnabled(false);
// _navPanel.setBackground(Const.inactiveCellBackgroundColor);u
_navPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,
Const.inactiveCellBackgroundColor, Color.BLACK));
getColNumSetSlider().addChangeListener(
CursorController.createChangeListener(getColNumSetSlider(),
new WSColNumSliderListener(this)));
getObjHeightSetSlider().addMouseListener(
new WSObjHeightSliderMouseListener(this));
getObjHeightSetSlider().addChangeListener(
new WSObjHeightSliderChangeListener(_workspacePanel));
this.add(_navPanel, BorderLayout.SOUTH);
this.addWindowListener(new WSWindowListener(this));
this.addComponentListener(new WSJFrameComponentListener(this));
// Prevent the two sliders from stealing the input
// focus. In particular, they like to grab the left/right
// arrow keys:
getColNumSetSlider().setFocusable(false);
getObjHeightSetSlider().setFocusable(false);
// Mouse wheel listener: a Java bug will cause an infinite
// loop in event processing if a mouse wheel listener is added
// to a top level, i.e. heavyweight component, like a JFrame.
// One must attach the listener to a lightweight component,
// like a JPanel! Wrong: this.addMouseWheelListener(new ...
_workspacePanel.addMouseWheelListener(new scrollMouseWheelListener());
// Zoom commands:
Misc.bindKey(_workspacePanel, "control PLUS", ZoomSpawner);
Misc.bindKey(_workspacePanel, "control EQUALS", ZoomSpawner);
Misc.bindKey(_workspacePanel, "control shift EQUALS", ZoomSpawner);
Misc.bindKey(_workspacePanel, "control MINUS", ZoomSpawner);
Misc.bindKey(_workspacePanel, "control shift MINUS", ZoomSpawner);
// Keyboard shortcuts:
Misc.bindKey(_workspacePanel, "control A", new SelectAllVisibleAction(
this));
Misc.bindKey(_workspacePanel, "control shift A", new SelectAllAction(
this));
Misc.bindKey(_workspacePanel, "control W",
new Misc.AppExitWithConfirmAction("Really exit PhotoSpread?",
this));
Misc.bindKey(this, "F1", new ShowHelpAction(
"To do in Workspace Window", "HelpFiles/workspaceHelp.html",
this));
}
/*************************************************
* Internal Classes
*************************************************/
class WSWindowListener extends WindowAdapter {
Workspace _workspace;
public WSWindowListener(Workspace workspace) {
_workspace = workspace;
}
public void windowClosing(WindowEvent e) {
Misc.exitIfUserWants(
"Closing Workspace Window Exits PhotoSpread. Do it?",
_workspace);
}
public void windowDeiconified(WindowEvent e) {
_theSheetWindow.setState(NORMAL);
_theSheetWindow.setVisible(true);
}
/*
* public void windowActivated(WindowEvent e) {
* _workspacePanel.requestFocusInWindow(); }
*/
}
class WSJFrameComponentListener extends ComponentAdapter {
Workspace _workspace;
boolean numColsSliderLocked = false;
public WSJFrameComponentListener(Workspace workspace) {
_workspace = workspace;
}
/**
*
* Workspace window has been resized. We check whether the workspace
* needs to be laid out again, i.e. whether rows can be added or
* removed. We also save the new window dimensions for this cell.
*
* @param Details
* of the resize event.
*/
public void componentResized(ComponentEvent e) {
// Should we wait here so that we don't lose
// a resize event?
if (numColsSliderLocked)
return;
numColsSliderLocked = true;
try {
// ComputableDimension newWorkspaceSize;
// newWorkspaceSize = new ComputableDimension(getSize());
// We refuse to let users make the window wider
// by hand. They are to use the slider for that.
// But if they make the Workspace window large enough
// to accommodate more rows, we'll do it.
Dimension prefDim = null;
// Get a hold of the layout:
PredictableEquiSizedGridLayout panelLayout = (PredictableEquiSizedGridLayout) getWorkspacePanel()
.getLayout();
int numPossibleRows = panelLayout
.getNumRowsAllSameHeightComponents(_workspace
.getWorkspacePanel(), getWorkspacePanel()
.getObjHeight());
// if (numPossibleRows == getWorkspacePanel().getRows()) {
if (panelLayout.isValid()) {
// Just tighten the Workspace window to its prior size
// again:
pack();
return;
}
if (numPossibleRows > 0) {
// The new page number (given the new number of rows)
// will differ from the current one. Find the new one:
int numObjsShownWithOldPageNum = (getPage()
* panelLayout.getRows() * panelLayout.getColumns())
+ getDrawnLabels().size();
// int numObjsShownWithOldPageNum = (getPage() + 1) *
// panelLayout.getRows() * panelLayout.getColumns();
int newPage = ((int) Math
.ceil(((float) numObjsShownWithOldPageNum / ((float) numPossibleRows * (float) panelLayout
.getColumns())))) - 1;
_workspacePanel.setPage(newPage, Const.DONT_REDRAW);
} else
// If user sized higher enough to lose one
// or more rows, then numPossibleRows will
// be 0. Set that to our minimum:
numPossibleRows = 1;
// Fill the internal representation of the panel with
// the additional (or fewer) objects:
int currNumCols = getWorkspacePanel().getColumns();
int fittableItems = numPossibleRows * currNumCols;
getWorkspacePanel().populatePanel(panelLayout.getColumns(),
fittableItems);
getWorkspacePanel().padWorkspacePanel(fittableItems,
getWorkspacePanel()._maxDisplayedItemDim);
// Recalculate the layout
panelLayout.validateNumRows(_workspace.getDisplayedCell()
.getObjects().size());
// Have the Workspace panel express the wish to occupy the new
// size
prefDim = panelLayout.preferredLayoutSize(getWorkspacePanel());
getWorkspacePanel().setPreferredSize(prefDim);
setEnabledButtons(getPage());
_userPrefWindowHeight = prefDim.height;
// Tighten the Workspace window around the new ensemble:
pack();
getWorkspacePanel().saveWorkspaceWindowSizeState();
getWorkspacePanel().saveNumRowsState();
} finally {
numColsSliderLocked = false;
}
}
}
class WSColNumSliderListener implements ChangeListener {
JFrame _workspaceWindow;
public WSColNumSliderListener(JFrame workspaceWindow) {
_workspaceWindow = workspaceWindow;
setFocusable(false);
}
// We assume that by the time we get here,
// it's already clear that user stopped
// sliding:
public void stateChanged(ChangeEvent e) {
if (_disabledColNumSliderService)
return;
int sliderVal = ((JSlider) e.getSource()).getValue();
if (sliderVal == 0) {
// Setting objs/row to 0 resizes the workspace
// to normal (and thereby sets the slider to 1):
getWorkspacePanel().resetCellWorkspaceToDefault();
return;
}
if (sliderVal == getWorkspacePanel().getColumns())
return;
try {
_disabledColNumSliderService = true;
System.out.println(sliderVal);
getWorkspacePanel().setObjectsPerRow(sliderVal);
_workspacePanel.redrawPanel();
} finally {
_disabledColNumSliderService = false;
}
setEnabledButtons(getPage());
}
}
class WSColNumSliderMouseListener extends MouseAdapter {
WorkspaceObjectsPanel _workspacePanel;
public WSColNumSliderMouseListener(WorkspaceObjectsPanel workspacePanel) {
_workspacePanel = workspacePanel;
}
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
_workspacePanel.resetCellWorkspaceToDefault();
}
}
}
class WSObjHeightSliderChangeListener implements ChangeListener {
JPanel _panel;
boolean resizeSliderLocked = false;
public WSObjHeightSliderChangeListener(JPanel workspacePanel) {
_panel = workspacePanel;
}
// We assume that by the time we get here,
// it's already clear that user stopped
// sliding:
public void stateChanged(ChangeEvent e) {
WorkspaceObjectsPanel wsPanel = getWorkspacePanel();
if (_disabledObjHeightSliderService || resizeSliderLocked)
return;
try {
resizeSliderLocked = true;
int sliderVal = ((JSlider) e.getSource()).getValue();
// If user simply clicked somewhere on the slider
// scale, then we don't have a resize overlay showing
// the resize of a sample image. In that
// case we go and adjust the Workspace's object width
// a percentage of its current value:
if (_resizeOverlay == null) {
setObjSizeToPercentage(sliderVal);
wsPanel.setCurrentImageSizePercentage(sliderVal);
wsPanel.invalidate();
return;
}
// Else user is sliding the object resize slider:
_resizeOverlay.resizeItem(sliderVal);
wsPanel.invalidate();
} finally {
resizeSliderLocked = false;
}
}
} // end. class WSObjHeightSliderChangeListener
class WSObjHeightSliderMouseListener extends MouseAdapter {
JFrame _workspaceWindow;
public WSObjHeightSliderMouseListener(JFrame workspaceWindow) {
_workspaceWindow = workspaceWindow;
}
public void mousePressed(MouseEvent e) {
PhotoSpreadAddable biggestDrawnItem = getWorkspacePanel()
.getBiggestDisplayedObject();
if (biggestDrawnItem == null) {
// We'll let the superposition use a rectangle as size sample:
_resizeOverlay = new SuperPositioner(getWorkspacePanel(),
"Size sample");
// Have overlay create a sample the size of a default-sized
// Workspace object:
_resizeOverlay
.setInitialItemSize(getDefaultInitialWorkspaceObjSize());
} else {
// We'll use a currently displayed pictures as size sample:
_resizeOverlay = new SuperPositioner(getWorkspacePanel(),
biggestDrawnItem.getComponent(), "Size sample");
// Have overlay create a sample the size of a default-sized
// Workspace object:
_resizeOverlay
.setInitialItemSize(getDefaultInitialWorkspaceObjSize());
}
_resizeOverlay.setVisible(true);
pack();
}
public void mouseReleased(MouseEvent e) {
if (_resizeOverlay == null)
return;
int sliderVal = ((JSlider) e.getSource()).getValue();
setObjSizeToPercentage(sliderVal);
getWorkspacePanel().setCurrentImageSizePercentage(sliderVal);
// ComputableDimension newObjSize = _resizeOverlay.getItemSize();
// _workspacePanel.setObjWidth(newObjSize.width);
_resizeOverlay.dispose();
_resizeOverlay = null;
((Workspace) _workspaceWindow).redraw();
repaint();
}
}
/**
* @author paepcke
*
* Handle the mouse wheel for scrolling in the workspace. The
* 'getScrollAmount() provides the platform dependent number of
* units (in our case Workspace screens) to advance per wheel notch.
* This quantity can be set in the platform dependend mouse control
* panel.
*
* We do not implement block scroll (as in page up/down).
*
*/
private class scrollMouseWheelListener extends MouseAdapter {
public void mouseWheelMoved(MouseWheelEvent e) {
// We only implement scrolling in units (as with arrow keys).
// We do not implement WHEEL_BLOCK_SCROLL, the page up/down
// alternative:
if (e.getScrollType() != MouseWheelEvent.WHEEL_UNIT_SCROLL)
return;
int notches = e.getWheelRotation();
if (notches < 0)
nextPage(e.getScrollAmount());
else
prevPage(e.getScrollAmount());
e.consume();
}
}
/*************************************************
* Action Listeners
*************************************************/
static Action ZoomSpawner = new AbstractAction() {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
((WorkspaceObjectsPanel) e.getSource()).getWorkspace()
.spawnZoomerWindow(Const.ALL);
}
};
/**
* Action listener associated with the 'Test' button in the Workspace
* window. This button is normally disabled (in the initializer above), but
* one can enable it and run some test by changing the code here. You can
* make any changes in this listener.
*
* @param comp
* @return
*/
private ActionListener testButtonListener(Component comp) {
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
// spawnZoomerWindow(Const.ALL);
return;
}
};
return listener;
}
private ActionListener zoomButtonListener(Component comp) {
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
spawnZoomerWindow(Const.ALL);
return;
}
};
return listener;
}
private ActionListener nextPageListener(Component comp) {
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
int page = _workspacePanel.getPage() + 1;
_workspacePanel.setPage(page);
setEnabledButtons(page);
WorkspaceSelector.userChangedPage(Direction.FORWARD);
}
};
// Now wrap the wait cursor code around this
// listener and return the wrapped result:
return CursorController.createActionListener(comp, listener);
}
private ActionListener prevPageListener(Component comp) {
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
int page = _workspacePanel.getPage() - 1;
_workspacePanel.setPage(page);
setEnabledButtons(page);
WorkspaceSelector.userChangedPage(Direction.BACKWARD);
}
};
// Now wrap the wait cursor code around this
// listener and return the wrapped result:
return CursorController.createActionListener(comp, listener);
}
private ActionListener homePageListener(Component comp) {
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
int currPage = getPage();
_workspacePanel.setPage(0);
setEnabledButtons(0);
if (currPage != 0)
WorkspaceSelector.userChangedPage(Direction.BACKWARD);
}
};
// Now wrap the wait cursor code around this
// listener and return the wrapped result:
return CursorController.createActionListener(comp, listener);
}
private ActionListener endPageListener(Component comp) {
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
int currPage = getPage();
int page = _workspacePanel.getLastPage();
_workspacePanel.setPage(page);
setEnabledButtons(page);
if (currPage != page)
WorkspaceSelector.userChangedPage(Direction.FORWARD);
}
};
// Now wrap the wait cursor code around this
// listener and return the wrapped result:
return CursorController.createActionListener(comp, listener);
}
/****************************************************
* Keyboard Commands
*****************************************************/
private class SelectAllAction extends AbstractAction {
private static final long serialVersionUID = 1L;
Workspace _workspace;
public SelectAllAction(Workspace workspace) {
_workspace = workspace;
}
public void actionPerformed(ActionEvent e) {
_workspace.selectAll();
}
}
private class SelectAllVisibleAction extends AbstractAction {
private static final long serialVersionUID = 1L;
Workspace _workspace;
public SelectAllVisibleAction(Workspace workspace) {
_workspace = workspace;
}
public void actionPerformed(ActionEvent e) {
_workspace.selectAllVisible();
}
}
@SuppressWarnings("unused")
private class ProgrammaticDnDAction extends AbstractAction {
private static final long serialVersionUID = 1L;
PhotoSpreadCell _destCell = null;
PhotoSpreadCell _srcCell = null;
public ProgrammaticDnDAction(PhotoSpreadCell destCell) {
_destCell = destCell;
_srcCell = _workspacePanel.getDisplayedCell();
}
public ProgrammaticDnDAction(PhotoSpreadCell srcCell,
PhotoSpreadCell destCell) {
_destCell = destCell;
_srcCell = srcCell;
}
public void actionPerformed(ActionEvent e) {
PhotoSpreadDragDropManager.setSourceCell(_srcCell);
PhotoSpreadDragDropManager.setDestCell(_destCell);
PhotoSpreadDragDropManager.executeDragDrop();
}
}
/*************************************************
* Methods
*************************************************/
public void reset() {
_workspacePanel.resetCellWorkspaceToDefault();
_userPrefWindowHeight = Const.INVALID;
}
public void reset(boolean redraw) {
reset();
if (redraw == Const.DO_REDRAW)
repaint();
}
private void initializeButtons() {
_zoomButton = new JButton("Zoom");
_zoomButton.setEnabled(true);
_zoomButton.addActionListener(zoomButtonListener(_zoomButton));
_testButton = new JButton("Test");
_testButton.setEnabled(true);
_testButton.addActionListener(testButtonListener(_testButton));
_nextSet = new JButton("Next");
_nextSet.setEnabled(false);
// _nextSet.setMnemonic('n');
// _zoomButton.setDisplayedMnemonicIndex(0);
_nextSet.addActionListener(nextPageListener(_nextSet));
_prevSet = new JButton("Prev");
_prevSet.setEnabled(false);
// _nextSet.setMnemonic('p');
_prevSet.addActionListener(prevPageListener(_prevSet));
_homeSet = new JButton("Home");
_homeSet.setEnabled(false);
// _nextSet.setMnemonic('h');
_homeSet.addActionListener(homePageListener(_homeSet));
_endSet = new JButton("End");
_endSet.setEnabled(false);
// _nextSet.setMnemonic('e');
_endSet.addActionListener(endPageListener(_endSet));
}
protected void spawnZoomerWindow(int max) {
ComputableDimension windowOffset = Const.ZoomWindowsOffset;
int nthLabel = 0;
Zoomer zoomer;
ComputableDimension zoomerPosition;
ComputableDimension newZoomerPosition;
DraggableLabel latestLabel = getLastLabelClicked();
String filePath = "";
ArrayList<PhotoSpreadAddable> selObjs = new ArrayList<PhotoSpreadAddable>();
// If no item in the Workspace is selected
// then we check whether exactly one (unselected)
// item is visible in the Workspace. If only one
// is visible, we select it and zoom. Otherwise
// we throw up an error message:
if (latestLabel == null)
if (getDrawnLabels().size() == 1) {
LinkedHashMap<PhotoSpreadObject, PhotoSpreadAddable> drawnLabels = getDrawnLabels();
// selectObject(getDrawnLabels().get(0));
selectObject(drawnLabels.get(drawnLabels.keySet().iterator()
.next()));
} else {
Misc.showErrorMsg("Cannot zoom: nothing selected.", this); // Show
// msg
// inside
// Workspace
// window
return;
}
switch (max) {
case Const.LAST_CLICKED:
selObjs.add(latestLabel);
max = 1;
break;
case Const.ALL:
for (PhotoSpreadAddable shownLabel : getDrawnLabels().values()) {
if (isObjectSelected(shownLabel))
selObjs.add(shownLabel);
}
max = selObjs.size();
break;
default:
break;
}
for (PhotoSpreadAddable selObj : selObjs) {
if (--max < 0)
break;
filePath = (String) selObj.getParentObject().toString();
try {
zoomer = new Zoomer(filePath);
if (nthLabel++ == 0)
continue;
zoomerPosition = new ComputableDimension(zoomer.getLocation());
newZoomerPosition = zoomerPosition.plus(windowOffset
.times(nthLabel++));
zoomer.setLocation(newZoomerPosition.toPoint());
} catch (IOException e) {
boolean wantContinue = Misc.showConfirmMsg(
"Cannot zoom: bad file path: '" + filePath
+ "'. Continue creating zoom windows?", this); // Show
// msg
// within
// Workspace
// window
if ((wantContinue && (selObj != selObjs.get(selObjs.size() - 1)))
&& max > 0)
continue;
else
return;
}
}
}
protected void spawnZoomerWindow() {
spawnZoomerWindow(Const.LAST_CLICKED);
}
/**
* Flip Workspace to next page if possible.
*
* @return True if there was a page to flip to. False if we were already on
* the last page.
*/
public boolean nextPage() {
return nextPage(1);
}
/**
* Advance a given number of pages.
*
* @param pages
* Number of pages to add to current page number.
* @return True if page flip succeeded. If flip would have gone past last
* page, do nothing and return false.
*/
public boolean nextPage(int pages) {
int newPageNum = _workspacePanel.getPage() + pages;
int lastPageNum = _workspacePanel.getLastPage();
if (newPageNum > lastPageNum)
return false;
_workspacePanel.setPage(newPageNum);
setEnabledButtons(newPageNum);
return true;
}
/**
* Flip Workspace to previous page if possible.
*
* @return True if there was a page to flip to. False if we were already on
* the first page.
*/
public boolean prevPage() {
return prevPage(1);
}
/**
* Go back a given number of pages.
*
* @param pages
* Number of pages to add to current page number.
* @return True if page flip succeeded. If flip would have gone past first
* page, do nothing and return false.
*/
public boolean prevPage(int pages) {
int newPageNum = _workspacePanel.getPage() - pages;
if (newPageNum < 0)
return false;
_workspacePanel.setPage(newPageNum);
setEnabledButtons(newPageNum);
return true;
}
public PhotoSpreadCell getDisplayedCell() {
return _workspacePanel.getDisplayedCell();
}
public boolean isObjectSelected(PhotoSpreadAddable label) {
return _workspacePanel.getDisplayedCell().isObjectSelected(
label.getParentObject());
}
public void flipObjectSelection(PhotoSpreadAddable label,
boolean updateMostRecentlyClicked) {
if (_workspacePanel.getDisplayedCell().isObjectSelected(
label.getParentObject()))
deSelectObject(label, updateMostRecentlyClicked);
else
selectObject(label, updateMostRecentlyClicked);
}
/**
* Select a PhotoSpreadAddable in the Workspace. Ex: DraggableLabel.
*
* @param label
* The Addable to select
* @param updateMostRecentlyClicked
* Whether the "most recently clicked" label should also be
* updated.
*/
public void selectObject(PhotoSpreadAddable label,
boolean updateMostRecentlyClicked) {
label.highlight();
_workspacePanel.getDisplayedCell()
.selectObject(label.getParentObject());
if (updateMostRecentlyClicked)
_workspacePanel.setLastLabelClicked((DraggableLabel) label);
}
/**
* Select a PhotoSpreadAddable in the Workspace. Ex: DraggableLabel.
*
* @param label
* The label to select.
*/
public void selectObject(PhotoSpreadAddable label) {
selectObject(label, false);
}
public void deSelectObject(PhotoSpreadAddable label,
boolean updateMostRecentlyClicked) {
label.unhighlight();
_workspacePanel.getDisplayedCell().deselectObject(
label.getParentObject());
if (updateMostRecentlyClicked)
_workspacePanel.setLastLabelClicked((DraggableLabel) label);
}
public void deSelectObject(PhotoSpreadAddable label) {
deSelectObject(label, false);
}
public void selectAll() {
_workspacePanel.getDisplayedCell().selectAllObjects();
selectAllVisible();
}
public void deSelectAll() {
_workspacePanel.clearSelected();
}
public void deSelectAllVisible() {
Iterator<PhotoSpreadAddable> visibleLablesIt = _workspacePanel
.getDrawnLabels().values().iterator();
while (visibleLablesIt.hasNext()) {
deSelectObject(visibleLablesIt.next());
}
}
public void selectAllVisible() {
Iterator<PhotoSpreadAddable> visibleLablesIt = _workspacePanel
.getDrawnLabels().values().iterator();
while (visibleLablesIt.hasNext()) {
selectObject(visibleLablesIt.next());
}
}
public void setColNumSliderValue(int newVal) {
if (getColNumSetSlider().getValue() == newVal)
return;
try {
_disabledColNumSliderService = true;
getColNumSetSlider().setValue(newVal);
getColNumSetSlider().validate();
getColNumSetSlider().repaint();
} finally {
_disabledColNumSliderService = false;
}
}
public void setObjHeightSliderValue(int newVal) {
if (getObjHeightSetSlider().getValue() == newVal)
return;
try {
_disabledObjHeightSliderService = true;
getObjHeightSetSlider().setValue(newVal);
_workspacePanel.setCurrentImageSizePercentage(newVal);
getObjHeightSetSlider().revalidate();
getObjHeightSetSlider().repaint();
} finally {
_disabledObjHeightSliderService = false;
}
}
/**
* Obtain dimensions Workspace objects as initially sized by default.
*
* @return Dimension width/height of initial object sizes in Workspace.
*/
public ComputableDimension getDefaultInitialWorkspaceObjSize() {
ComputableDimension res = null;
res = new ComputableDimension(PhotoSpread.photoSpreadPrefs
.getInt(PhotoSpread.workspaceObjWidthKey),
PhotoSpread.photoSpreadPrefs
.getInt(PhotoSpread.workspaceObjHeightKey));
return res;
}
/**
* enables/disables navigation based on page being viewed
*
* @param page
* The page that the workspace is currently displaying (base 0)
*/
public void setEnabledButtons(int page) {
if (page <= 0) {
_prevSet.setEnabled(false);
_homeSet.setEnabled(false);
} else {
_prevSet.setEnabled(true);
_homeSet.setEnabled(true);
}
int lastPage = _workspacePanel.getLastPage();
if (page >= lastPage) {
_nextSet.setEnabled(false);
_endSet.setEnabled(false);
} else {
_nextSet.setEnabled(true);
_endSet.setEnabled(true);
}
// For human consumption: be 1-based:
this._pageViewer.setText("" + (page + 1) + "/" + (lastPage + 1));
}
public int getPage() {
return _workspacePanel.getPage();
}
public int getLastPage() {
return _workspacePanel.getLastPage();
}
public void setDisplayedCell(PhotoSpreadCell cell)
throws NumberFormatException, NotBoundException {
_workspacePanel.removeAll();
// The following will repaint:
_workspacePanel.setDisplayedCell(cell);
}
public void setColNumSetSlider(JSlider _colNumSetSlider) {
this._colNumSetSlider = _colNumSetSlider;
}
public JSlider getColNumSetSlider() {
return _colNumSetSlider;
}
public void setObjHeightSetSlider(JSlider _objHeightSetSlider) {
this._objHeightSetSlider = _objHeightSetSlider;
}
public JSlider getObjHeightSetSlider() {
return _objHeightSetSlider;
}
public JPanel getNavPanel() {
return _navPanel;
}
private void setObjSizeToPercentage(int percentage) {
_workspacePanel.setObjWidth(PhotoSpread.photoSpreadPrefs
.getInt(PhotoSpread.workspaceObjWidthKey)
* percentage / 100);
}
protected LinkedHashMap<PhotoSpreadObject, PhotoSpreadAddable> getDrawnLabels() {
return _workspacePanel.getDrawnLabels();
}
protected DraggableLabel getLastLabelClicked() {
return _workspacePanel.getLastLabelClicked();
}
protected void setLastLabelClicked(DraggableLabel newLabel) {
_workspacePanel.setLastLabelClicked(newLabel);
}
void setWorkspacePanel(WorkspaceObjectsPanel _workspacePanel) {
this._workspacePanel = _workspacePanel;
}
public WorkspaceObjectsPanel getWorkspacePanel() {
return _workspacePanel;
}
/**
* Bind a key to an action. The binding will be active while the Workspace
* window is selected.
*
* @param keyDescription
* A string describing the key as per
* KeyStroke.getKeyStroke(String). Ex: "alt A" or "ctrl UP" (for
* up-arrow). Key names are the <keyName> part in VK_<keyName>
* @param action
* Action object to invoke when key is pressed.
*/
/*
* public void bindKey (String keyDescription, Action action) {
*
* InputMap keyMap =
* _workspacePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); ActionMap
* actionMap = _workspacePanel.getActionMap();
*
* keyMap.put(KeyStroke.getKeyStroke(keyDescription), keyDescription);
* actionMap.put(keyDescription, action); }
*/
public void resize() {
if (_workspacePanel == null)
return;
ComputableDimension layoutManagerPrefSize = (ComputableDimension) _workspacePanel
.getLayout().preferredLayoutSize(this);
setSize(getInsets().left + layoutManagerPrefSize.width
+ getObjHeightSetSlider().getWidth() + getInsets().top,
layoutManagerPrefSize.height + _navPanel.getHeight()
+ getInsets().bottom);
}
public Insets getInsets() {
return Const.workspaceInsets;
}
/**
* Redraws workspace
*/
public void redraw() {
// To prevent circular call chains
// _workspace -> _workspacePanel constructor -> _workspace.redraw()
// during startup:
if (_workspacePanel == null)
return;
try {
_workspacePanel.redraw();
} catch (NumberFormatException e) {
Misc.showErrorMsgAndStackTrace(e, "");
// e.printStackTrace();
} catch (NotBoundException e) {
Misc.showErrorMsgAndStackTrace(e, "");
// e.printStackTrace();
}
}
public void pack() {
if (_userPrefWindowHeight != Const.INVALID) {
Dimension currDim = _workspacePanel.getPreferredSize();
_workspacePanel.setPreferredSize(new Dimension(currDim.width,
_userPrefWindowHeight));
}
super.pack();
}
}