/** * Get the ImageDatums rendered in this AbstractImageBrowser: the ones that are the most recently * modified among all ImageDatums in their ImageGroup. */ ArrayList<ImageDatum> getAllImageData() { List<ImageDatum> allDatums = list.getAllImageData(); Set<ImageDatum> recentDatums = new LinkedHashSet<ImageDatum>(); for (ImageDatum datum : allDatums) { ImageGroup group = datum.getGroup(); List<ImageDatum> members = group.getImageDatums(); long lastTime = 0; ImageDatum lastMember = null; for (ImageDatum member : members) { File file = member.getFile(); long modTime = file.lastModified(); if (modTime > lastTime) { lastMember = member; lastTime = modTime; } } recentDatums.add(lastMember); } return new ArrayList<ImageDatum>(recentDatums); }
void updateSelectionDatumRemoved(ImageDatum datum, int index) { List<ImageDatum> selected = selection.getSelected(); if (selected.contains(datum)) { if (selected.size() == 1) { ArrayList<ImageDatum> visible = getAllImageData(); ArrayList<ImageDatum> all = list.getAllImageData(); ImageDatum next = null; if (index == 0) { // If the first image was deleted, select the new first if (visible.size() > 0) { next = visible.get(0); } } else { // If the deleted one was NOT a version, walk FORWARDS // starting at the SAME position until we find a visible // image. if (!datum.getType().hasLznData()) { int max = all.size() - 1; while ((index < max) && (!visible.contains(next))) { next = all.get(index++); } } // Otherwise, walk BACKWARDS starting with the PREVIOUS // position until we find a visible image else { while ((index > 0) && (!visible.contains(next))) { next = all.get(--index); } } } if (next != null) { int i = visible.indexOf(next); selection.setLeadSelected(next); if (i >= 0) { Rectangle bounds = getBounds(i); scrollRectToVisible(bounds); } } } else { selection.removeSelected(datum); } } }
protected void paintComponent(Graphics graphics) { if (justShown) { if (!paintTimer.isRunning()) paintTimer.start(); return; } if (!isWidthInitialized) { // Only paint if the component size has been initialized. Layout // jumps are typical the first time this component is displayed, // because the preferred height depends on the component width. return; } Graphics2D g = (Graphics2D) graphics; Rectangle clip = g.getClipBounds(); // Figure out which ImageDatums fall within the clip bounds. List<ImageDatum> datums = getAllImageData(); int[] indices = getIndices(datums.size(), clip); // Iterate backwards through indices, so repaints get enqueued // in a visually pleasing order. for (int i = indices.length - 1; i >= 0; i--) { int index = indices[i]; if (index < 0) { continue; } ImageDatum datum = datums.get(index); if (datum == null) { // A race; the image disappeared during painting. continue; } RenderedImage image = datum.getImage(this); // This queue prevents GC of recently painted images: recentImages.add(image); Rectangle rect = getBounds(index); g.setClip(clip.intersection(rect)); File file = datum.getFile(); String label = file.getName(); ImageDatumType type = datum.getType(); String tag = type.toString(); ImageMetadata meta = datum.getMetadata(true); int rating = meta.getRating(); boolean selected = selection.isSelected(datum); renderer.paint(g, image, label, tag, rating, rect, selected); ImageGroup group = datum.getGroup(); if (group.isNonTrivial()) { ImageGroupCountRenderer.paint(g, rect, datum); } } g.setClip(clip); // The control is drawn as an overlay. if (controller.isEnabled()) { Rectangle ctrlRect = controller.getRect(); if (ctrlRect != null) { if (ctrlRect.intersects(clip)) { controller.paint(g); } } } }