Java tutorial
/* * Copyright 2008 Eckhart Arnold (eckhart_arnold@hotmail.com). * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package de.eckhartarnold.client; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.dom.client.MouseOutEvent; import com.google.gwt.event.dom.client.MouseOutHandler; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.event.dom.client.MouseOverHandler; //import com.google.gwt.user.client.DOM; import com.google.gwt.dom.client.Element; import com.google.gwt.user.client.ui.HasHorizontalAlignment; import com.google.gwt.user.client.ui.HasVerticalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.safehtml.shared.SafeHtml; /** * presents the user with a table of * thumbnail images that can be clicked by the user. * * <p>The thumbnail * images contain the caption of the image as a tool-tip. The number * of rows and columns of the image table is determined dynamically * based on the size of the widget (or browser window resp.) and * changes whenever it is resized. * * Class <code>GalleryWidget</code> does not add slide show button and * thus only fires <code>onPickImage</code> events. * * @author eckhart * */ public class GalleryWidget extends GalleryBase { /** The default with of the thumbnail images of the gallery */ public static final int DEFAULT_THUMBNAIL_WIDTH = 160; /** The default height of the thumnail images of the gallery */ public static final int DEFAULT_THUMBNAIL_HEIGHT = 160; /** The default horizontal padding between the thumbnail images of the gallery */ public static final int DEFAULT_GALLERY_HPADDING = 50; /** The default vertical padding between the thumbnail images of the gallery */ public static final int DEFAULT_GALLERY_VPADDING = 30; // padding does not work really well, because horizontal and vertical padding are somwhow correlated. /** The key in the "info.json" file for the thumnbail width */ public static final String KEY_THUMBNAIL_WIDTH = "thumbnail width"; /** The key in the "info.json" file for the thumnbail height */ public static final String KEY_THUMBNAIL_HEIGHT = "thumbnail height"; /** The key in the "info.json" file for horizontal padding */ public static final String KEY_GALLERY_HPADDING = "gallery horizontal padding"; /** The key in the "info.json" file for horizontal padding */ public static final String KEY_GALLERY_VPADDING = "gallery vertical padding"; private static int readKey(ImageCollectionInfo collection, String keyName, int defaultValue) { if (collection.getInfo().containsKey(keyName)) { return Integer.valueOf(collection.getInfo().get(keyName)); } else { return defaultValue; } } /** * The "main" panel of the gallery widget. Basically, the gallery widget * consists of a vertical panel that contains a number of horizontal * panels which represent the rows of the image table. The horizontal * panels are disposed and recreated when ever the size changes. */ protected VerticalPanel panel; private SafeHtml[] captions; private int edgeWidth, edgeHeight; // private HTML filler; private Thumbnails thumbnails; private HorizontalPanel[] imageRows; private int paddingH, paddingV; /** * Constructor of class <code>GalleryWidget</code> * * @param collection the image collection info from which to construct the * gallery. */ public GalleryWidget(ImageCollectionInfo collection) { this(collection, readKey(collection, KEY_THUMBNAIL_WIDTH, DEFAULT_THUMBNAIL_WIDTH), readKey(collection, KEY_THUMBNAIL_HEIGHT, DEFAULT_THUMBNAIL_HEIGHT), readKey(collection, KEY_GALLERY_HPADDING, DEFAULT_GALLERY_HPADDING), readKey(collection, KEY_GALLERY_VPADDING, DEFAULT_GALLERY_VPADDING)); } /** * An alternative constructor of class <code>GalleryWidget</code> which * allows setting the with, height and spacing of the thumbnail images * according to user preferences. It is advisable to make sure that * these values correspond more of less to the extensions of the images * in the thumbnail image directory (i.e. the image directory with the * smalles sized images). Aspect ratios are taken care of by the * <code>GalleryWidget</code> class. * * @param collection the image collection info record * @param edgeWidth the with of the thumbnail images * @param edgeHeight the height of the thumbnail images * @param hpadding the horizontal padding between the thumbnail images * @param vpadding the vertical padding between the thumbnail images */ public GalleryWidget(ImageCollectionInfo collection, int edgeWidth, int edgeHeight, int hpadding, int vpadding) { this(new Thumbnails(collection), collection.getCaptions(), edgeWidth, edgeHeight, hpadding, vpadding); } /** * This is the most verbose constructor of class <code>GalleryWidget</code>. * It allows using this class without an image collection info object. * This requires not only to pass the thumbnail image's width and height * explicitly, but also their captions displayed as tooltips. * * @param thumbnails the collection of thumbnail images * @param captions the captions of the thumbnail images * @param edgeWidth the width of the thumbnail images * @param edgeHeight the height of the thumbnail images * @param hpadding the horizontal padding between the thumbnail images * @param vpadding the vertical padding between the thumbnail images */ public GalleryWidget(Thumbnails thumbnails, SafeHtml[] captions, int edgeWidth, int edgeHeight, int hpadding, int vpadding) { this.captions = captions; this.edgeWidth = edgeWidth; this.edgeHeight = edgeHeight; this.paddingH = hpadding; this.paddingV = vpadding; thumbnails.adjustToRectangle(edgeWidth, edgeHeight); this.thumbnails = thumbnails; initRawGallery(); } /* (non-Javadoc) * @see de.eckhartarnold.client.SourcesGalleryEvents#onResized() */ @Override public void onResized() { Widget parent = getParent(); if (parent == null) return; int width = parent.getOffsetWidth(); HorizontalPanel row = null; int columns = (width - paddingH) / (edgeWidth + paddingH); if (columns <= 0) columns = 1; int rows = thumbnails.size() / columns; if (thumbnails.size() % columns != 0) rows++; if (imageRows != null) { if (rows == imageRows.length && imageRows[0].getWidgetCount() == columns) { return; // layout did not change! } for (HorizontalPanel p : imageRows) { panel.remove(p); } } imageRows = new HorizontalPanel[rows]; for (int i = 0; i < thumbnails.size(); i++) { if (i % columns == 0) { row = new HorizontalPanel(); row.setStyleName("galleryRow"); //row.setSpacing(paddingV); row.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); row.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); imageRows[i / columns] = row; } Image img = thumbnails.get(i); if (captions[i].asString().length() > 0) { Tooltip.addToWidget(new Tooltip(captions[i]), img); // sometimes wrong tooltip position!? } row.add(img); //int delta = 0; //if (paddingH > paddingV) delta = 2*(paddingH-paddingV); row.setCellWidth(img, edgeWidth + 2 * paddingH + "px"); row.setCellHeight(img, edgeHeight + 2 * paddingV + "px"); } for (HorizontalPanel r : imageRows) { panel.add(r); } } /* (non-Javadoc) * @see com.google.gwt.user.client.ui.Composite#onAttach() */ @Override protected void onAttach() { prepareResized(); // if (filler != null) { // panel.remove(filler); // filler = null; // } onResized(); super.onAttach(); } /* (non-Javadoc) * @see de.eckhartarnold.client.ResizeListener#prepareResized() */ public void prepareResized() { } private void initRawGallery() { assert panel == null; panel = new VerticalPanel(); panel.addStyleName("gallery"); panel.getElement().setAttribute("align", "center"); panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); // add a filler so that the vertical panel is not empty (and its // horizontal size not zero) when the thumbnail pictures are added. // filler = new HTML(" "); // panel.add(filler); ClickHandler imageClickHandler = new ClickHandler() { public void onClick(ClickEvent event) { Widget sender = (Widget) event.getSource(); // String id = DOM.getElementAttribute(sender.getElement(), "id"); String id = sender.getElement().getAttribute("id"); firePickImage(Integer.parseInt(id)); sender.removeStyleName("galleryTouched"); sender.removeStyleName("galleryPressed"); } }; MouseDownHandler imageMouseDownHandler = new MouseDownHandler() { public void onMouseDown(MouseDownEvent event) { Widget sender = (Widget) event.getSource(); sender.addStyleName("galleryPressed"); } }; MouseOverHandler imageMouseOverHandler = new MouseOverHandler() { public void onMouseOver(MouseOverEvent event) { Widget sender = (Widget) event.getSource(); sender.addStyleName("galleryTouched"); } }; MouseOutHandler imageMouseOutHandler = new MouseOutHandler() { public void onMouseOut(MouseOutEvent event) { Widget sender = (Widget) event.getSource(); sender.removeStyleName("galleryTouched"); sender.removeStyleName("galleryPressed"); } }; for (int i = 0; i < thumbnails.size(); i++) { Image img = thumbnails.get(i); img.setStyleName("galleryImage"); Element imgElement = img.getElement(); // DOM.setElementAttribute(imgElement, "id", String.valueOf(i)); imgElement.setAttribute("id", String.valueOf(i)); img.addClickHandler(imageClickHandler); img.addMouseDownHandler(imageMouseDownHandler); img.addMouseOverHandler(imageMouseOverHandler); img.addMouseOutHandler(imageMouseOutHandler); } initWidget(panel); } }