se.llbit.chunky.ui.Minimap.java Source code

Java tutorial

Introduction

Here is the source code for se.llbit.chunky.ui.Minimap.java

Source

/* 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();
    }

}