public void mousePressed(MouseEvent event) { int x = event.getX() / panel.getZoom(); int y = event.getY() / panel.getZoom(); try { if (event.isControlDown() || SwingUtilities.isRightMouseButton(event)) { // treat right-clicks and control-left-clicks as the same (for Mac users) if (event.isShiftDown()) { list.deleteAll(x, y); } else { list.delete(x, y); } } else { if (event.isShiftDown()) { list.lower(x, y); } else { list.raise(x, y); } } // repaint all of the tiles panel.clear(); Graphics g = panel.getGraphics(); list.drawAll(g); } catch (RuntimeException e) { if (CATCH_EXCEPTIONS) { e.printStackTrace(System.err); } else { throw e; } } }
public void keyPressed(KeyEvent event) { int code = event.getKeyCode(); if (code == KeyEvent.VK_N) { Tile newTile = makeRandomTile(); list.addTile(newTile); Graphics g = panel.getGraphics(); list.drawAll(g); } else if (code == KeyEvent.VK_S) { list.shuffle(WIDTH, HEIGHT); Graphics g = panel.getGraphics(); panel.clear(); list.drawAll(g); } }
@Override public void onMapEvent(Event event, MapPosition mapPosition) { if (event == Map.CLEAR_EVENT) { /* sync with TileRenderer */ synchronized (mRenderer) { tileRenderer().clearTiles(); mTileManager.init(); } if (mTileManager.update(mapPosition)) notifyLoaders(); } else if (event == Map.POSITION_EVENT) { if (mTileManager.update(mapPosition)) notifyLoaders(); } }
public static void main(String[] args) { DrawingPanel panel = new DrawingPanel(WIDTH, HEIGHT); Graphics g = panel.getGraphics(); // create several random tiles and put them into a manager TileManager list = new TileManager(); for (int i = 0; i < TILES; i++) { Tile tile = makeRandomTile(); list.addTile(tile); } list.drawAll(g); // listen for key presses RectangleKeyListener listener = new RectangleKeyListener(panel, list); panel.addKeyListener(listener); // listen for mouse clicks RectangleMouseListener listener2 = new RectangleMouseListener(panel, list); panel.addMouseListener(listener2); }
/** * Creates tile managers from the specified collection of tiles. This method usually returns a * single tile manager, but more could be returned if this factory has been unable to put every * tiles in a single mosaic (for example if the ratio between {@linkplain AffineTransform affine * transform} given to {@linkplain Tile#Tile(ImageReaderSpi,Object,int,Rectangle,AffineTransform) * tile constructor} would lead to fractional {@linkplain Tile#getSubsampling subsampling}). * * @param tiles The tiles to give to a tile manager. * @return A tile manager created from the given tiles. * @throws IOException If an I/O operation was required and failed. */ public TileManager[] create(Collection<Tile> tiles) throws IOException { int count = 0; final TileManager[] managers; if (!hasPendingGridToCRS(tiles)) { /* * There is no tile having a "gridToCRS" transform pending RegionCalculator work. So we * can create (at the end of this method) a single TileManager using all those tiles. */ if (!tiles.isEmpty()) { count = 1; } managers = new TileManager[count]; } else { /* * At least one tile have a pending "gridToCRS" transform (actually we should have * more than one - typically all of them - otherwise the RegionCalculator work will * be useless). Computes their region now. Note that we could execute this block * unconditionally. The 'hasPendingGridToCRS' check we just for avoiding the cost * of creating RegionCalculator in the common case where it is not needed. So it is * not a big deal if 'hasPendingGridToCRS' conservatively returned 'true'. */ final Collection<Tile> remainings = new ArrayList<>(Math.min(16, tiles.size())); final RegionCalculator calculator = new RegionCalculator(); for (final Tile tile : tiles) { if (!calculator.add(tile)) { remainings.add(tile); } } if (!remainings.isEmpty()) { count = 1; } final Map<ImageGeometry, Tile[]> split = calculator.tiles(); managers = new TileManager[split.size() + count]; for (final Map.Entry<ImageGeometry, Tile[]> entry : split.entrySet()) { final TileManager manager = createGeneric(entry.getValue()); manager.setGridGeometry(entry.getKey()); managers[count++] = manager; } tiles = remainings; } /* * The collection now contains tiles that has not been processed by RegionCalculator, * because their 'gridToCRS' transform is flagged as already computed. Create a mosaic * for them, and use the affine transform having the finest resolution as the "global" * one. */ if (!tiles.isEmpty()) { final TileManager manager = createGeneric(tiles.toArray(new Tile[tiles.size()])); final Rectangle imageBounds = new Rectangle(-1, -1); AffineTransform gridToCRS = null; Dimension subsampling = null; double scale = Double.POSITIVE_INFINITY; for (final Tile tile : tiles) { imageBounds.add(tile.getAbsoluteRegion()); final AffineTransform candidate = tile.getGridToCRS(); if (candidate != null && !candidate.equals(gridToCRS)) { final double cs = XAffineTransform.getScale(candidate); if (cs < scale) { // Found a new tile at a finer resolution. scale = cs; gridToCRS = candidate; subsampling = tile.getSubsampling(); } else if (cs == scale) { // Inconsistent transform at the finest level. // Abandon the attempt to create a grid geometry. gridToCRS = null; break; } } } if (gridToCRS != null) { if (subsampling.width != 1 || subsampling.height != 1) { gridToCRS = new AffineTransform(gridToCRS); gridToCRS.scale(subsampling.width, subsampling.height); } manager.setGridGeometry(new ImageGeometry(imageBounds, gridToCRS)); } managers[0] = manager; } return managers; }
/** * Invokes {@link TileManager#setSourceFile(Path)} for all managers in the given array. Returns * the given array for convenience. */ private static TileManager[] setSourceFile(final TileManager[] managers, final Path file) { for (final TileManager manager : managers) { manager.setSourceFile(file); } return managers; }