Java tutorial
/** * Squidy Interaction Library is free software: you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * Squidy Interaction Library is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squidy Interaction Library. If not, see * <http://www.gnu.org/licenses/>. * * 2009 Human-Computer Interaction Group, University of Konstanz. * <http://hci.uni-konstanz.de> * * Please contact info@squidy-lib.de or visit our website * <http://www.squidy-lib.de> for further information. */ package org.squidy.designer.zoom; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import javax.swing.JOptionPane; import javax.swing.JTextField; import javax.xml.bind.Unmarshaller; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.squidy.designer.Designer; import org.squidy.designer.constant.Constants; import org.squidy.designer.piccolo.JComponentWrapper; import org.squidy.designer.shape.VisualShape; import org.squidy.designer.util.AffineTransformUtils; import org.squidy.designer.util.FontUtils; import org.squidy.designer.util.ShapeUtils; import edu.umd.cs.piccolo.PNode; import edu.umd.cs.piccolo.event.PBasicInputEventHandler; import edu.umd.cs.piccolo.event.PInputEvent; import edu.umd.cs.piccolo.util.PAffineTransform; import edu.umd.cs.piccolo.util.PBounds; import edu.umd.cs.piccolo.util.PPaintContext; /** * <code>ZoomNavigationObject</code>. * * <pre> * Date: Feb 19, 2009 * Time: 4:40:32 PM * </pre> * * @author <pre> * Roman R&aumldle * <a href="mailto:Roman.Raedle@uni-konstanz.de">Roman.Raedle@uni-konstanz.de</a> * Human-Computer Interaction Group * University of Konstanz * </pre> * * @version $Id: NavigationShape.java 772 2011-09-16 15:39:44Z raedle $ * @since 1.0.0 */ public abstract class NavigationShape<T extends VisualShape<?>> extends TitledShape<T> { /** * Generated serial version UID. */ private static final long serialVersionUID = -5787025974725394517L; // Logger to log info, error, debug,... messages. private static final Log LOG = LogFactory.getLog(NavigationShape.class); // ############################################################################# // BEGIN JAXB // ############################################################################# private JComponentWrapper titleInputWrapper; /** * Default constructor required for JAXB. */ public NavigationShape() { super(); addInputEventListener(new PBasicInputEventHandler() { private JTextField titleInput = new JTextField(getTitle()); { titleInputWrapper = new JComponentWrapper(titleInput); titleInput.setFont(fontBreadcrumb); addChild(titleInputWrapper); // titleInputWrapper.setScale(2); ShapeUtils.setApparent(titleInputWrapper, false); titleInput.addKeyListener(new KeyAdapter() { /** * @param e */ public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { if (ShapeUtils.isApparent(titleInputWrapper)) { prepareTitleIfNecessary(); } } } }); } /** * Prepare title if user did new input and title is different than * current title. */ void prepareTitleIfNecessary() { String oldTitle = getTitle(); String newTitle = titleInput.getText(); if (!oldTitle.equals(newTitle)) { if (changeTitle(oldTitle, newTitle)) { setTitle(titleInput.getText()); ShapeUtils.setApparent(titleInputWrapper, false); invalidateTitle(); invalidateBreadcrumb(); invalidatePaint(); } } else { ShapeUtils.setApparent(titleInputWrapper, false); } } /* * (non-Javadoc) * * @see * edu.umd.cs.piccolo.event.PBasicInputEventHandler#mouseClicked * (edu.umd.cs.piccolo.event.PInputEvent) */ @Override public void mouseClicked(PInputEvent event) { if (!event.isHandled()) { switch (event.getClickCount()) { case 1: if (!event.getPickedNode().equals(titleInputWrapper) && ShapeUtils.isApparent(titleInputWrapper)) { prepareTitleIfNecessary(); event.setHandled(true); } break; case 2: Point2D p = event.getPositionRelativeTo(NavigationShape.this); if (titleBounds != null && titleBounds.contains(p)) { if (!ShapeUtils.isApparent(titleInputWrapper)) { titleInputWrapper.setOffset(titleBounds.getX(), titleBounds.getY()); titleInput.setText(getTitle()); // titleInput.requestFocus(); ShapeUtils.setApparent(titleInputWrapper, true); } event.setHandled(true); } break; } } } }); } /* * (non-Javadoc) * * @see * org.squidy.designer.zoom.TitledZoomShape#afterUnmarshal(javax. * xml.bind.Unmarshaller, java.lang.Object) */ public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) { super.afterUnmarshal(unmarshaller, parent); } // ############################################################################# // END JAXB // ############################################################################# private double titleGap = 0; /** * @return the titleGap */ public final double getTitleGap() { return titleGap; } /** * @param titleGap * the titleGap to set */ public final void setTitleGap(double titleGap) { this.titleGap = titleGap; } private boolean showNavigation = true; /** * @return the showNavigation */ public final boolean isShowNavigation() { return showNavigation; } /** * @param showNavigation * the showNavigation to set */ public final void setShowNavigation(boolean showNavigation) { this.showNavigation = showNavigation; } /** * @param title * @return */ protected boolean changeTitle(String oldTitle, String newTitle) { if ("".equals(newTitle.trim())) { JOptionPane.showMessageDialog(Designer.getInstance(), "Blank title is not allowed.", "Blank title", JOptionPane.ERROR_MESSAGE); return false; } return true; } private String breadcrumb; /** * @return */ protected String getBreadcrumb() { if (breadcrumb == null) { PNode parent = getParent(); while (parent != null && !(parent instanceof NavigationShape)) { parent = parent.getParent(); } if (parent == null) { return getTitle(); } breadcrumb = ((NavigationShape<?>) parent).getBreadcrumb(); if (!"".equals(breadcrumb)) { breadcrumb += " / "; } breadcrumb += getTitle(); } return breadcrumb; } /** * */ protected void invalidateBreadcrumb() { breadcrumb = null; croppedBreadcrumb = null; for (Object o : getChildrenReference()) { if (o instanceof NavigationShape<?>) { ((NavigationShape<?>) o).invalidateBreadcrumb(); } } } private Rectangle2D titleBounds; private PAffineTransform SCALE_TRANSFORM = AffineTransformUtils.getScaleInstance(0.1, 0.1); private static Font fontBreadcrumb = internalFont.deriveFont(18f); private String croppedBreadcrumb; /* * (non-Javadoc) * * @see * org.squidy.designer.zoom.ZoomShape#paintShapeZoomedIn(edu.umd. * cs.piccolo.util.PPaintContext) */ @Override protected void paintShapeZoomedIn(PPaintContext paintContext) { super.paintShapeZoomedIn(paintContext); Graphics2D g = (Graphics2D) paintContext.getGraphics(); if (showNavigation) {// && !isHierarchicalZoomInProgress()) { PBounds bounds = getBoundsReference(); int x = (int) bounds.getX(); int y = (int) bounds.getY(); int width = (int) bounds.getWidth(); int height = (int) bounds.getHeight(); g.setColor(Constants.Color.COLOR_SHAPE_BACKGROUND); if (isRenderPrimitiveRect()) g.fillRect(x, y, width, 60); else { g.clearRect(x, y, width, 60); g.fillRoundRect(x, y, width, 60, 25, 25); } g.setColor(Constants.Color.COLOR_SHAPE_BORDER); if (isRenderPrimitiveRect()) g.drawRect(x, y, width, 60); else g.drawRoundRect(x, y, width, 60, 25, 25); g.setFont(fontBreadcrumb); if (titleBounds == null) { FontMetrics fm = g.getFontMetrics(); titleBounds = new Rectangle2D.Double(bounds.getX() + 455 + titleGap, bounds.getY() + 25 - fm.getHeight(), FontUtils.getWidthOfText(fm, getTitle()) + 10, fm.getHeight() + 5); } // Font font = internalFont.deriveFont(3.2f); for (int i = 0; i < 3; i++) { if (isRenderPrimitiveRect()) g.fillRect((int) (bounds.getX() + 430), (int) bounds.getY() + i * 15 + 10, 5, 10); else g.fillOval((int) (bounds.getX() + 430), (int) bounds.getY() + i * 15 + 10, 5, 10); } if (!ShapeUtils.isApparent(titleInputWrapper)) { g.drawString(getTitle(), (int) (bounds.getX() + 460 + titleGap), (int) (bounds.getY() + 25)); } if (croppedBreadcrumb == null) { croppedBreadcrumb = FontUtils.createCroppedLabelIfNecessary(g.getFontMetrics(), getBreadcrumb(), (int) bounds.getWidth() * 10 - 450); } g.drawString(croppedBreadcrumb, (int) (bounds.getX() + 460), (int) (bounds.getY() + 50)); } } }