diff --git a/extras/src/main/java/edu/umd/cs/piccolox/swing/PScrollPane.java b/extras/src/main/java/edu/umd/cs/piccolox/swing/PScrollPane.java index cf1c376..109b322 100644 --- a/extras/src/main/java/edu/umd/cs/piccolox/swing/PScrollPane.java +++ b/extras/src/main/java/edu/umd/cs/piccolox/swing/PScrollPane.java @@ -55,407 +55,397 @@ */ public class PScrollPane extends JScrollPane { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - /** A reusable null action. */ - protected PNullAction nullAction = null; + /** A reusable null action. */ + protected PNullAction nullAction = null; - /** Controls whether key actions are disabled on this component. */ - protected boolean disableKeyActions = false; + /** Controls whether key actions are disabled on this component. */ + protected boolean disableKeyActions = false; - private final AdjustmentListener scrollAdjustmentListener = new AdjustmentListener() { - private boolean lastAdjustingState = false; + private final AdjustmentListener scrollAdjustmentListener = new AdjustmentListener() { + private boolean lastAdjustingState = false; - public void adjustmentValueChanged(AdjustmentEvent e) { - if (e.getSource() instanceof JScrollBar) { - JScrollBar scrollBar = (JScrollBar) e.getSource(); - - setAdjusting(scrollBar.getValueIsAdjusting()); - } - } + public void adjustmentValueChanged(final AdjustmentEvent event) { + if (event.getSource() instanceof JScrollBar) { + JScrollBar scrollBar = (JScrollBar) event.getSource(); - /** - * Updates the underlying PCanvas' interacting flag depending on whether - * scroll bar adjustments are still taking place. - * - * @param isAdjusting - * true if the scroll bar is still being interacted with - */ - private void setAdjusting(final boolean isAdjusting) { - if (isAdjusting != lastAdjustingState) { - Component c = getViewport().getView(); - if (c instanceof PCanvas) { - ((PCanvas) c).setInteracting(isAdjusting); - } - lastAdjustingState = isAdjusting; - } - } - }; + setAdjusting(scrollBar.getValueIsAdjusting()); + } + } - /** - * Constructs a scollpane for the provided component with the specified - * scrollbar policies. - * - * @param view - * component being viewed through the scrollpane - * @param vsbPolicy - * vertical scroll bar policy - * @param hsbPolicy - * horizontal scroll bar policy - */ - public PScrollPane(final Component view, final int vsbPolicy, final int hsbPolicy) { - super(view, vsbPolicy, hsbPolicy); + /** + * Updates the underlying PCanvas' interacting flag depending on whether + * scroll bar adjustments are still taking place. + * + * @param isAdjusting true if the scroll bar is still being interacted + * with + */ + private void setAdjusting(final boolean isAdjusting) { + if (isAdjusting != lastAdjustingState) { + Component c = getViewport().getView(); + if (c instanceof PCanvas) { + ((PCanvas) c).setInteracting(isAdjusting); + } + lastAdjustingState = isAdjusting; + } + } + }; - // Set the layout and sync it with the scroll pane - final PScrollPaneLayout layout = new PScrollPaneLayout.UIResource(); - setLayout(layout); - layout.syncWithScrollPane(this); + /** + * Constructs a scollpane for the provided component with the specified + * scrollbar policies. + * + * @param view component being viewed through the scrollpane + * @param vsbPolicy vertical scroll bar policy + * @param hsbPolicy horizontal scroll bar policy + */ + public PScrollPane(final Component view, final int vsbPolicy, final int hsbPolicy) { + super(view, vsbPolicy, hsbPolicy); - horizontalScrollBar.addAdjustmentListener(scrollAdjustmentListener); - verticalScrollBar.addAdjustmentListener(scrollAdjustmentListener); - } + // Set the layout and sync it with the scroll pane + final PScrollPaneLayout layout = new PScrollPaneLayout.UIResource(); + setLayout(layout); + layout.syncWithScrollPane(this); - public void setVerticalScrollBar(javax.swing.JScrollBar newVerticalScrollBar) { - if (verticalScrollBar != null) { - verticalScrollBar.removeAdjustmentListener(scrollAdjustmentListener); - } + horizontalScrollBar.addAdjustmentListener(scrollAdjustmentListener); + verticalScrollBar.addAdjustmentListener(scrollAdjustmentListener); + } - super.setVerticalScrollBar(newVerticalScrollBar); - newVerticalScrollBar.addAdjustmentListener(scrollAdjustmentListener); - } + /** + * Intercepts the vertical scroll bar setter to ensure that the adjustment + * listener is installed appropriately. + * + * @param newVerticalScrollBar the new vertical scroll bar to use with this PScrollPane + */ + public void setVerticalScrollBar(final JScrollBar newVerticalScrollBar) { + if (verticalScrollBar != null) { + verticalScrollBar.removeAdjustmentListener(scrollAdjustmentListener); + } - public void setHorizontalScrollBar(javax.swing.JScrollBar newHorizontalScrollBar) { - if (horizontalScrollBar != null) { - horizontalScrollBar.removeAdjustmentListener(scrollAdjustmentListener); - } - - super.setHorizontalScrollBar(newHorizontalScrollBar); - newHorizontalScrollBar.addAdjustmentListener(scrollAdjustmentListener); - } + super.setVerticalScrollBar(newVerticalScrollBar); + newVerticalScrollBar.addAdjustmentListener(scrollAdjustmentListener); + } - /** - * Constructs a scollpane for the provided component. - * - * @param view - * component being viewed through the scrollpane - */ - public PScrollPane(final Component view) { - this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED); - } + /** + * Intercepts the horizontal scroll bar setter to ensure that the adjustment + * listener is installed appropriately. + * + * @param newHorizontalScrollBar the new horizontal scroll bar to use with this PScrollPane + */ + public void setHorizontalScrollBar(final JScrollBar newHorizontalScrollBar) { + if (horizontalScrollBar != null) { + horizontalScrollBar.removeAdjustmentListener(scrollAdjustmentListener); + } - /** - * Constructs a scollpane not attached to any component with the specified - * scroll bar policies. - * - * @param vsbPolicy - * vertical scroll bar policy - * @param hsbPolicy - * horizontal scroll bar policy - */ - public PScrollPane(final int vsbPolicy, final int hsbPolicy) { - this(null, vsbPolicy, hsbPolicy); - } + super.setHorizontalScrollBar(newHorizontalScrollBar); + newHorizontalScrollBar.addAdjustmentListener(scrollAdjustmentListener); + } - /** - * Constructs a scollpane not attached to any component. - */ - public PScrollPane() { - this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED); - } + /** + * Constructs a scroll pane for the provided component. + * + * @param view component being viewed through the scroll pane + */ + public PScrollPane(final Component view) { + this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED); + } - /** - * Disable or enable key actions on this PScrollPane. - * - * @param disable - * true disables key actions, false enables key actions - */ - public void setKeyActionsDisabled(final boolean disable) { - if (disable && disableKeyActions != disable) { - disableKeyActions = disable; - disableKeyActions(); - } else if (!disable && disableKeyActions != disable) { - disableKeyActions = disable; - installCustomKeyActions(); - } - } + /** + * Constructs a scroll pane not attached to any component with the specified + * scroll bar policies. + * + * @param vsbPolicy vertical scroll bar policy + * @param hsbPolicy horizontal scroll bar policy + */ + public PScrollPane(final int vsbPolicy, final int hsbPolicy) { + this(null, vsbPolicy, hsbPolicy); + } - /** - * Sets the UI. - * - * @param ui - * the scroll pane ui to associate with this PScollPane - */ - public void setUI(final ScrollPaneUI ui) { - super.setUI(ui); + /** + * Constructs a scroll pane not attached to any component. + */ + public PScrollPane() { + this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED); + } - if (!disableKeyActions) { - installCustomKeyActions(); - } else { - disableKeyActions(); - } - } + /** + * Disable or enable key actions on this PScrollPane. + * + * @param disable true disables key actions, false enables key actions + */ + public void setKeyActionsDisabled(final boolean disable) { + if (disable && disableKeyActions != disable) { + disableKeyActions = disable; + disableKeyActions(); + } + else if (!disable && disableKeyActions != disable) { + disableKeyActions = disable; + installCustomKeyActions(); + } + } - /** - * Install custom key actions (in place of the Swing defaults) to correctly - * scroll the view. - */ - protected void installCustomKeyActions() { - final ActionMap map = getActionMap(); + /** + * Sets the UI. + * + * @param ui the scroll pane UI to associate with this PScollPane + */ + public void setUI(final ScrollPaneUI ui) { + super.setUI(ui); - map.put("scrollUp", new PScrollAction("scrollUp", SwingConstants.VERTICAL, -1, true)); - map.put("scrollDown", new PScrollAction("scrollDown", SwingConstants.VERTICAL, 1, - true)); - map.put("scrollLeft", new PScrollAction("scrollLeft", SwingConstants.HORIZONTAL, -1, - true)); + if (!disableKeyActions) { + installCustomKeyActions(); + } + else { + disableKeyActions(); + } + } - map.put("scrollRight", new PScrollAction("ScrollRight", SwingConstants.HORIZONTAL, 1, - true)); - map.put("unitScrollRight", new PScrollAction("UnitScrollRight", - SwingConstants.HORIZONTAL, 1, false)); - map.put("unitScrollLeft", new PScrollAction("UnitScrollLeft", - SwingConstants.HORIZONTAL, -1, false)); - map.put("unitScrollUp", new PScrollAction("UnitScrollUp", SwingConstants.VERTICAL, - -1, false)); - map.put("unitScrollDown", new PScrollAction("UnitScrollDown", - SwingConstants.VERTICAL, 1, false)); + /** + * Install custom key actions (in place of the Swing defaults) to correctly + * scroll the view. + */ + protected void installCustomKeyActions() { + final ActionMap map = getActionMap(); - map.put("scrollEnd", new PScrollEndAction("ScrollEnd")); - map.put("scrollHome", new PScrollHomeAction("ScrollHome")); - } + map.put("scrollUp", new PScrollAction("scrollUp", SwingConstants.VERTICAL, -1, true)); + map.put("scrollDown", new PScrollAction("scrollDown", SwingConstants.VERTICAL, 1, true)); + map.put("scrollLeft", new PScrollAction("scrollLeft", SwingConstants.HORIZONTAL, -1, true)); - /** - * Disables key actions on this PScrollPane. - */ - protected void disableKeyActions() { - final ActionMap map = getActionMap(); + map.put("scrollRight", new PScrollAction("ScrollRight", SwingConstants.HORIZONTAL, 1, true)); + map.put("unitScrollRight", new PScrollAction("UnitScrollRight", SwingConstants.HORIZONTAL, 1, false)); + map.put("unitScrollLeft", new PScrollAction("UnitScrollLeft", SwingConstants.HORIZONTAL, -1, false)); + map.put("unitScrollUp", new PScrollAction("UnitScrollUp", SwingConstants.VERTICAL, -1, false)); + map.put("unitScrollDown", new PScrollAction("UnitScrollDown", SwingConstants.VERTICAL, 1, false)); - if (nullAction == null) { - nullAction = new PNullAction(); - } + map.put("scrollEnd", new PScrollEndAction("ScrollEnd")); + map.put("scrollHome", new PScrollHomeAction("ScrollHome")); + } - map.put("scrollUp", nullAction); - map.put("scrollDown", nullAction); - map.put("scrollLeft", nullAction); - map.put("scrollRight", nullAction); - map.put("unitScrollRight", nullAction); - map.put("unitScrollLeft", nullAction); - map.put("unitScrollUp", nullAction); - map.put("unitScrollDown", nullAction); - map.put("scrollEnd", nullAction); - map.put("scrollHome", nullAction); - } + /** + * Disables key actions on this PScrollPane. + */ + protected void disableKeyActions() { + final ActionMap map = getActionMap(); - /** - * Overridden to create the Piccolo2D viewport. - * - * @return the Piccolo2D version of the viewport - */ - protected JViewport createViewport() { - return new PViewport(); - } + if (nullAction == null) { + nullAction = new PNullAction(); + } - /** - * Action to scroll left/right/up/down. Modified from - * javax.swing.plaf.basic.BasicScrollPaneUI.ScrollAction. - * - * Gets the view parameters (position and size) from the Viewport rather than - * directly from the view - also only performs its actions when the relevant - * scrollbar is visible. - */ - protected static class PScrollAction extends AbstractAction { - private static final int MINIMUM_SCROLL_SIZE = 10; - private static final long serialVersionUID = 1L; - /** Direction to scroll. */ - protected int orientation; - /** 1 indicates scroll down, -1 up. */ - protected int direction; - /** True indicates a block scroll, otherwise a unit scroll. */ - private final boolean block; + map.put("scrollUp", nullAction); + map.put("scrollDown", nullAction); + map.put("scrollLeft", nullAction); + map.put("scrollRight", nullAction); + map.put("unitScrollRight", nullAction); + map.put("unitScrollLeft", nullAction); + map.put("unitScrollUp", nullAction); + map.put("unitScrollDown", nullAction); + map.put("scrollEnd", nullAction); + map.put("scrollHome", nullAction); + } - /** - * Constructs a scroll action with the given name in the given orientiation - * stated and in the direction provided. - * - * @param name - * arbitrary name of action - * @param orientation - * horizontal or vertical - * @param direction - * 1 indicates scroll down, -1 up - * @param block - * true if block scroll as opposed to unit - */ - protected PScrollAction(final String name, final int orientation, - final int direction, final boolean block) { - super(name); - this.orientation = orientation; - this.direction = direction; - this.block = block; - } + /** + * Overridden to create the Piccolo2D viewport. + * + * @return the Piccolo2D version of the viewport + */ + protected JViewport createViewport() { + return new PViewport(); + } - /** - * Performs the scroll action if the action was performed on visible - * scrollbars and if the viewport is valid. - * - * @param event - * the event responsible for this action being performed - */ - public void actionPerformed(final ActionEvent event) { - final JScrollPane scrollpane = (JScrollPane) event.getSource(); - if (!isScrollEventOnVisibleScrollbars(scrollpane)) { - return; - } + /** + * Action to scroll left/right/up/down. Modified from + * javax.swing.plaf.basic.BasicScrollPaneUI.ScrollAction. + * + * Gets the view parameters (position and size) from the Viewport rather + * than directly from the view - also only performs its actions when the + * relevant scrollbar is visible. + */ + protected static class PScrollAction extends AbstractAction { + private static final int MINIMUM_SCROLL_SIZE = 10; + private static final long serialVersionUID = 1L; + /** Direction to scroll. */ + protected int orientation; + /** 1 indicates scroll down, -1 up. */ + protected int direction; + /** True indicates a block scroll, otherwise a unit scroll. */ + private final boolean block; - final JViewport vp = scrollpane.getViewport(); - if (vp == null) { - return; - } + /** + * Constructs a scroll action with the given name in the given + * orientiation stated and in the direction provided. + * + * @param name arbitrary name of action + * @param orientation horizontal or vertical + * @param direction 1 indicates scroll down, -1 up + * @param block true if block scroll as opposed to unit + */ + protected PScrollAction(final String name, final int orientation, final int direction, final boolean block) { + super(name); + this.orientation = orientation; + this.direction = direction; + this.block = block; + } - Component view = vp.getView(); - if (view == null) { - return; - } + /** + * Performs the scroll action if the action was performed on visible + * scrollbars and if the viewport is valid. + * + * @param event the event responsible for this action being performed + */ + public void actionPerformed(final ActionEvent event) { + final JScrollPane scrollpane = (JScrollPane) event.getSource(); + if (!isScrollEventOnVisibleScrollbars(scrollpane)) { + return; + } - final Rectangle visRect = vp.getViewRect(); - // LEG: Modification to query the viewport for the - // view size rather than going directly to the view - final Dimension vSize = vp.getViewSize(); - final int amount; + final JViewport vp = scrollpane.getViewport(); + if (vp == null) { + return; + } - if (view instanceof Scrollable) { - if (block) { - amount = ((Scrollable) view).getScrollableBlockIncrement(visRect, orientation, - direction); - } else { - amount = ((Scrollable) view).getScrollableUnitIncrement(visRect, orientation, - direction); - } - } else { - if (block) { - if (orientation == SwingConstants.VERTICAL) { - amount = visRect.height; - } else { - amount = visRect.width; - } - } else { - amount = MINIMUM_SCROLL_SIZE; - } - } + Component view = vp.getView(); + if (view == null) { + return; + } - if (orientation == SwingConstants.VERTICAL) { - visRect.y += amount * direction; - if (visRect.y + visRect.height > vSize.height) { - visRect.y = Math.max(0, vSize.height - visRect.height); - } else if (visRect.y < 0) { - visRect.y = 0; - } - } else { - visRect.x += amount * direction; - if (visRect.x + visRect.width > vSize.width) { - visRect.x = Math.max(0, vSize.width - visRect.width); - } else if (visRect.x < 0) { - visRect.x = 0; - } - } - vp.setViewPosition(visRect.getLocation()); - } + final Rectangle visRect = vp.getViewRect(); + // LEG: Modification to query the viewport for the + // view size rather than going directly to the view + final Dimension vSize = vp.getViewSize(); + final int amount; - private boolean isScrollEventOnVisibleScrollbars(final JScrollPane scrollpane) { - return orientation == SwingConstants.VERTICAL - && scrollpane.getVerticalScrollBar().isShowing() - || orientation == SwingConstants.HORIZONTAL - && scrollpane.getHorizontalScrollBar().isShowing(); - } - } + if (view instanceof Scrollable) { + if (block) { + amount = ((Scrollable) view).getScrollableBlockIncrement(visRect, orientation, direction); + } + else { + amount = ((Scrollable) view).getScrollableUnitIncrement(visRect, orientation, direction); + } + } + else { + if (block) { + if (orientation == SwingConstants.VERTICAL) { + amount = visRect.height; + } + else { + amount = visRect.width; + } + } + else { + amount = MINIMUM_SCROLL_SIZE; + } + } - /** - * Action to scroll to x,y location of 0,0. Modified from - * javax.swing.plaf.basic.BasicScrollPaneUI.ScrollEndAction. - * - * Only performs the event if a scrollbar is visible. - */ - private static class PScrollHomeAction extends AbstractAction { - private static final long serialVersionUID = 1L; + if (orientation == SwingConstants.VERTICAL) { + visRect.y += amount * direction; + if (visRect.y + visRect.height > vSize.height) { + visRect.y = Math.max(0, vSize.height - visRect.height); + } + else if (visRect.y < 0) { + visRect.y = 0; + } + } + else { + visRect.x += amount * direction; + if (visRect.x + visRect.width > vSize.width) { + visRect.x = Math.max(0, vSize.width - visRect.width); + } + else if (visRect.x < 0) { + visRect.x = 0; + } + } + vp.setViewPosition(visRect.getLocation()); + } - protected PScrollHomeAction(final String name) { - super(name); - } + private boolean isScrollEventOnVisibleScrollbars(final JScrollPane scrollpane) { + return orientation == SwingConstants.VERTICAL && scrollpane.getVerticalScrollBar().isShowing() + || orientation == SwingConstants.HORIZONTAL && scrollpane.getHorizontalScrollBar().isShowing(); + } + } - public void actionPerformed(final ActionEvent e) { - final JScrollPane scrollpane = (JScrollPane) e.getSource(); - // LEG: Modification to only perform these actions if one of the - // scrollbars is actually showing - if (scrollpane.getVerticalScrollBar().isShowing() - || scrollpane.getHorizontalScrollBar().isShowing()) { - final JViewport vp = scrollpane.getViewport(); - if (vp != null && vp.getView() != null) { - vp.setViewPosition(new Point(0, 0)); - } - } - } - } + /** + * Action to scroll to x,y location of 0,0. Modified from + * javax.swing.plaf.basic.BasicScrollPaneUI.ScrollEndAction. + * + * Only performs the event if a scrollbar is visible. + */ + private static class PScrollHomeAction extends AbstractAction { + private static final long serialVersionUID = 1L; - /** - * Action to scroll to last visible location. Modified from - * javax.swing.plaf.basic.BasicScrollPaneUI.ScrollEndAction. - * - * Gets the view size from the viewport rather than directly from the view - - * also only performs the event if a scrollbar is visible. - */ - protected static class PScrollEndAction extends AbstractAction { - private static final long serialVersionUID = 1L; + protected PScrollHomeAction(final String name) { + super(name); + } - /** - * Constructs a scroll to end action with the given name. - * - * @param name - * name to assign to this action - */ - protected PScrollEndAction(final String name) { - super(name); - } + public void actionPerformed(final ActionEvent e) { + final JScrollPane scrollpane = (JScrollPane) e.getSource(); + // LEG: Modification to only perform these actions if one of the + // scrollbars is actually showing + if (scrollpane.getVerticalScrollBar().isShowing() || scrollpane.getHorizontalScrollBar().isShowing()) { + final JViewport vp = scrollpane.getViewport(); + if (vp != null && vp.getView() != null) { + vp.setViewPosition(new Point(0, 0)); + } + } + } + } - /** - * Scrolls to the end of the viewport if there are visible scrollbars. - * - * @param event - * event responsible for the scroll event - */ - public void actionPerformed(final ActionEvent event) { - final JScrollPane scrollpane = (JScrollPane) event.getSource(); - // LEG: Modification to only perform these actions if one of the - // scrollbars is actually showing - if (scrollpane.getVerticalScrollBar().isShowing() - || scrollpane.getHorizontalScrollBar().isShowing()) { + /** + * Action to scroll to last visible location. Modified from + * javax.swing.plaf.basic.BasicScrollPaneUI.ScrollEndAction. + * + * Gets the view size from the viewport rather than directly from the view - + * also only performs the event if a scrollbar is visible. + */ + protected static class PScrollEndAction extends AbstractAction { + private static final long serialVersionUID = 1L; - final JViewport vp = scrollpane.getViewport(); - if (vp != null && vp.getView() != null) { + /** + * Constructs a scroll to end action with the given name. + * + * @param name name to assign to this action + */ + protected PScrollEndAction(final String name) { + super(name); + } - final Rectangle visRect = vp.getViewRect(); - // LEG: Modification to query the viewport for the - // view size rather than going directly to the view - final Dimension size = vp.getViewSize(); - vp.setViewPosition(new Point(size.width - visRect.width, size.height - - visRect.height)); - } - } - } - } + /** + * Scrolls to the end of the viewport if there are visible scrollbars. + * + * @param event event responsible for the scroll event + */ + public void actionPerformed(final ActionEvent event) { + final JScrollPane scrollpane = (JScrollPane) event.getSource(); + // LEG: Modification to only perform these actions if one of the + // scrollbars is actually showing + if (scrollpane.getVerticalScrollBar().isShowing() || scrollpane.getHorizontalScrollBar().isShowing()) { - /** - * An action to do nothing - put into an action map to keep it from looking to - * its parent. - */ - protected static class PNullAction extends AbstractAction { - private static final long serialVersionUID = 1L; + final JViewport vp = scrollpane.getViewport(); + if (vp != null && vp.getView() != null) { - /** - * Does nothing. - * - * @param e - * Event responsible for this action - */ - public void actionPerformed(final ActionEvent e) { - } - } + final Rectangle visRect = vp.getViewRect(); + // LEG: Modification to query the viewport for the + // view size rather than going directly to the view + final Dimension size = vp.getViewSize(); + vp.setViewPosition(new Point(size.width - visRect.width, size.height - visRect.height)); + } + } + } + } + + /** + * An action to do nothing - put into an action map to keep it from looking + * to its parent. + */ + protected static class PNullAction extends AbstractAction { + private static final long serialVersionUID = 1L; + + /** + * Does nothing. + * + * @param e Event responsible for this action + */ + public void actionPerformed(final ActionEvent e) { + } + } }