Java tutorial
/* Copyright (c) 2010-2012 Jesper qvist <jesper@llbit.se> * * This file is part of Chunky. * * Chunky is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Chunky 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 General Public License for more details. * You should have received a copy of the GNU General Public License * along with Chunky. If not, see <http://www.gnu.org/licenses/>. */ package se.llbit.chunky.ui; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JPanel; import org.apache.commons.math3.util.FastMath; import se.llbit.chunky.main.Chunky; import se.llbit.chunky.map.MapBuffer; import se.llbit.chunky.map.WorldRenderer; import se.llbit.chunky.world.Chunk; import se.llbit.chunky.world.ChunkPosition; import se.llbit.chunky.world.ChunkSelectionTracker; import se.llbit.chunky.world.ChunkView; import se.llbit.chunky.world.World; import se.llbit.chunky.world.listeners.ChunkUpdateListener; /** * @author Jesper qvist (jesper@llbit.se) */ @SuppressWarnings("serial") public class Minimap extends JPanel implements ChunkUpdateListener { /** * Default width of the minimap */ public static final int DEFAULT_WIDTH = 300; /** * Default height of the minimap */ public static final int DEFAULT_HEIGHT = 150; private static final Font font = new Font("Sans serif", Font.BOLD, 11); private final MapBuffer mapBuffer; private final Chunky chunky; private volatile ChunkView view; /** * @param parent */ public Minimap(Chunky parent) { this.chunky = parent; setBackground(Color.white); setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT)); setMinimumSize(new Dimension(100, 100)); setIgnoreRepaint(false); view = chunky.getMinimapView(); mapBuffer = new MapBuffer(view); addMouseListener(new MouseListener() { @Override public void mouseReleased(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { chunky.moveView(e.getX() - getWidth() / 2, e.getY() - getHeight() / 2); } @Override public void mouseExited(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseClicked(MouseEvent e) { } }); addComponentListener(new ComponentListener() { @Override public void componentShown(ComponentEvent e) { } @Override public void componentResized(ComponentEvent e) { chunky.minimapResized(getWidth(), getHeight()); } @Override public void componentMoved(ComponentEvent e) { } @Override public void componentHidden(ComponentEvent e) { } }); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); // NB lock the lock ordering here is critical! // we access ChunkMap via Chunky but here we also need to lock Chunky synchronized (chunky) { synchronized (this) { ChunkView mapView = chunky.getMapView(); WorldRenderer renderer = chunky.getWorldRenderer(); World world = chunky.getWorld(); ChunkSelectionTracker selection = chunky.getChunkSelection(); renderer.render(world, mapBuffer, Chunk.biomeRenderer, selection); mapBuffer.renderBuffered(g); renderer.renderPlayer(world, g, view, true); renderer.renderSpawn(world, g, view, true); // draw view rectangle g.setColor(Color.orange); g.drawRect((int) FastMath.round(mapView.x0 - view.x0), (int) FastMath.round(mapView.z0 - view.z0), FastMath.round(mapView.width / (float) mapView.scale), FastMath.round(mapView.height / (float) mapView.scale)); // draw North indicator g.setFont(font); g.setColor(Color.red); g.drawString("N", view.width / 2 - 4, 12); g.setColor(Color.black); g.drawString(world.levelName(), 10, view.height - 10); } } } /** * Redraw all visible chunks. */ public void redraw() { mapBuffer.flushCache(); repaint(); } @Override public void chunkUpdated(ChunkPosition chunk) { mapBuffer.chunkUpdated(chunk); repaint(); } @Override public void regionUpdated(ChunkPosition region) { mapBuffer.regionUpdated(region); repaint(); } /** * Called when the minimap view has changed. * @param newView */ public synchronized void viewUpdated(ChunkView newView) { view = newView; mapBuffer.updateView(view, Chunk.biomeRenderer, 0); repaint(); } }