Java tutorial
/* * Copyright 2015 Torridity. * * 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.tor.tribes.ui.panels; import de.tor.tribes.control.GenericManagerListener; import de.tor.tribes.io.DataHolder; import de.tor.tribes.types.Marker; import de.tor.tribes.types.UserProfile; import de.tor.tribes.types.ext.*; import de.tor.tribes.ui.ImageManager; import de.tor.tribes.ui.MinimapListener; import de.tor.tribes.ui.renderer.map.MapRenderer; import de.tor.tribes.ui.windows.DSWorkbenchMainFrame; import de.tor.tribes.ui.windows.MinimapZoomFrame; import de.tor.tribes.util.Constants; import de.tor.tribes.util.GlobalOptions; import de.tor.tribes.util.ImageUtils; import de.tor.tribes.util.JOptionPaneHelper; import de.tor.tribes.util.ServerSettings; import de.tor.tribes.util.interfaces.ToolChangeListener; import de.tor.tribes.util.mark.MarkerManager; import de.tor.tribes.util.tag.TagManager; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Point; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import java.text.NumberFormat; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import javax.imageio.ImageIO; import javax.swing.*; import javax.swing.filechooser.FileFilter; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.labels.StandardPieSectionLabelGenerator; import org.jfree.chart.plot.PiePlot; import org.jfree.data.general.DefaultPieDataset; /** * @author Torridity */ public class MinimapPanel extends javax.swing.JPanel implements GenericManagerListener { @Override public void dataChangedEvent() { dataChangedEvent(null); } @Override public void dataChangedEvent(String pGroup) { redraw(); } private static Logger logger = LogManager.getLogger("MinimapCanvas"); private Image mBuffer = null; private int iX = 0; private int iY = 0; private int iWidth = 0; private int iHeight = 0; private int iCurrentCursor = ImageManager.CURSOR_DEFAULT; private static MinimapPanel SINGLETON = null; private ScreenshotPanel mScreenshotPanel = null; private List<MinimapListener> mMinimapListeners = null; private List<ToolChangeListener> mToolChangeListeners = null; private boolean doRedraw = false; private int iXDown = 0; private int iYDown = 0; //x,y start point //width, height end point private Rectangle2D rDrag = null; private Rectangle rVisiblePart = null; boolean zoomed = false; boolean showControls = false; private static final int ID_MINIMAP = 0; private static final int ID_ALLY_CHART = 1; private static final int ID_TRIBE_CHART = 2; private HashMap<Integer, Rectangle> minimapButtons = new HashMap<>(); private HashMap<Integer, BufferedImage> minimapIcons = new HashMap<>(); private int iCurrentView = ID_MINIMAP; private BufferedImage mChartImage; private int lastHash = 0; public static synchronized MinimapPanel getSingleton() { if (SINGLETON == null) { SINGLETON = new MinimapPanel(); } return SINGLETON; } /** * Creates new form MinimapPanel */ MinimapPanel() { initComponents(); setSize(300, 300); mMinimapListeners = new LinkedList<>(); mToolChangeListeners = new LinkedList<>(); setCursor(ImageManager.getCursor(iCurrentCursor)); mScreenshotPanel = new ScreenshotPanel(); minimapButtons.put(ID_MINIMAP, new Rectangle(2, 2, 26, 26)); minimapButtons.put(ID_ALLY_CHART, new Rectangle(30, 2, 26, 26)); minimapButtons.put(ID_TRIBE_CHART, new Rectangle(60, 2, 26, 26)); try { minimapIcons.put(ID_MINIMAP, ImageIO.read(new File("./graphics/icons/minimap.png"))); minimapIcons.put(ID_ALLY_CHART, ImageIO.read(new File("./graphics/icons/ally_chart.png"))); minimapIcons.put(ID_TRIBE_CHART, ImageIO.read(new File("./graphics/icons/tribe_chart.png"))); } catch (Exception ignored) { } jPanel1.add(mScreenshotPanel); rVisiblePart = new Rectangle(ServerSettings.getSingleton().getMapDimension()); zoomed = false; MarkerManager.getSingleton().addManagerListener(this); TagManager.getSingleton().addManagerListener(this); MinimapRepaintThread.getSingleton().setVisiblePart(rVisiblePart); if (!GlobalOptions.isMinimal()) { MinimapRepaintThread.getSingleton().start(); } addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent e) { if (!showControls && e.getButton() != MouseEvent.BUTTON1) { //show controls Point p = e.getPoint(); p.translate(-5, -5); showControls(p); return; } if (!showControls && iCurrentView == ID_MINIMAP) { Point p = mousePosToMapPosition(e.getX(), e.getY()); DSWorkbenchMainFrame.getSingleton().centerPosition(p.getX(), p.getY()); MapPanel.getSingleton().getMapRenderer().initiateRedraw(MapRenderer.ALL_LAYERS); if (MinimapZoomFrame.getSingleton().isVisible()) { MinimapZoomFrame.getSingleton().toFront(); } } else { if (minimapButtons.get(ID_MINIMAP).contains(e.getPoint())) { iCurrentView = ID_MINIMAP; mBuffer = null; showControls = false; MinimapRepaintThread.getSingleton().update(); } else if (minimapButtons.get(ID_ALLY_CHART).contains(e.getPoint())) { iCurrentView = ID_ALLY_CHART; lastHash = 0; showControls = false; updateComplete(); } else if (minimapButtons.get(ID_TRIBE_CHART).contains(e.getPoint())) { iCurrentView = ID_TRIBE_CHART; lastHash = 0; showControls = false; updateComplete(); } } } @Override public void mousePressed(MouseEvent e) { if (iCurrentView != ID_MINIMAP) { return; } if (iCurrentCursor == ImageManager.CURSOR_SHOT || iCurrentCursor == ImageManager.CURSOR_ZOOM) { iXDown = e.getX(); iYDown = e.getY(); } } @Override public void mouseReleased(MouseEvent e) { if (iCurrentView != ID_MINIMAP) { return; } if (rDrag == null) { return; } if (iCurrentCursor == ImageManager.CURSOR_SHOT) { try { BufferedImage i = MinimapRepaintThread.getSingleton().getImage(); double widthFactor = ((double) ServerSettings.getSingleton().getMapDimension().width) / getWidth(); double heightFactor = ((double) ServerSettings.getSingleton().getMapDimension().height) / getHeight(); int x = (int) Math.rint(widthFactor * rDrag.getX()); int y = (int) Math.rint(heightFactor * rDrag.getY()); int w = (int) Math.rint(widthFactor * (rDrag.getWidth() - rDrag.getX())); int h = (int) Math.rint(heightFactor * (rDrag.getHeight() - rDrag.getY())); BufferedImage sub = i.getSubimage(x, y, w, h); mScreenshotPanel.setBuffer(sub); jPanel1.setSize(mScreenshotPanel.getSize()); jPanel1.setPreferredSize(mScreenshotPanel.getSize()); jPanel1.setMinimumSize(mScreenshotPanel.getSize()); jPanel1.setMaximumSize(mScreenshotPanel.getSize()); jScreenshotPreview.pack(); jScreenshotControl.pack(); jScreenshotPreview.setVisible(true); jScreenshotControl.setVisible(true); } catch (Exception ie) { logger.error("Failed to initialize mapshot", ie); } } else if (iCurrentCursor == ImageManager.CURSOR_ZOOM) { if (!zoomed) { Rectangle mapDim = ServerSettings.getSingleton().getMapDimension(); double widthFactor = ((double) mapDim.width) / getWidth(); double heightFactor = ((double) mapDim.height) / getHeight(); int x = (int) Math.rint(widthFactor * rDrag.getX() + mapDim.getMinX()); int y = (int) Math.rint(heightFactor * rDrag.getY() + mapDim.getMinY()); int w = (int) Math.rint(widthFactor * (rDrag.getWidth() - rDrag.getX())); if (w >= 10) { rVisiblePart = new Rectangle(x, y, w, w); MinimapRepaintThread.getSingleton().setVisiblePart(rVisiblePart); redraw(); zoomed = true; } } else { rVisiblePart = new Rectangle(ServerSettings.getSingleton().getMapDimension()); MinimapRepaintThread.getSingleton().setVisiblePart(rVisiblePart); redraw(); zoomed = false; } MinimapZoomFrame.getSingleton().setVisible(false); } iXDown = 0; iYDown = 0; rDrag = null; } @Override public void mouseEntered(MouseEvent e) { if (iCurrentView != ID_MINIMAP) { return; } switch (iCurrentCursor) { case ImageManager.CURSOR_ZOOM: { MinimapZoomFrame.getSingleton().setVisible(true); } } } @Override public void mouseExited(MouseEvent e) { if (MinimapZoomFrame.getSingleton().isVisible()) { MinimapZoomFrame.getSingleton().setVisible(false); } iXDown = 0; iYDown = 0; rDrag = null; } }); addMouseMotionListener(new MouseMotionListener() { @Override public void mouseDragged(MouseEvent e) { if (iCurrentView != ID_MINIMAP) { return; } switch (iCurrentCursor) { case ImageManager.CURSOR_MOVE: { Point p = mousePosToMapPosition(e.getX(), e.getY()); DSWorkbenchMainFrame.getSingleton().centerPosition(p.x, p.y); rDrag = null; break; } case ImageManager.CURSOR_SHOT: { rDrag = new Rectangle2D.Double(iXDown, iYDown, e.getX(), e.getY()); break; } case ImageManager.CURSOR_ZOOM: { rDrag = new Rectangle2D.Double(iXDown, iYDown, e.getX(), e.getY()); break; } } } @Override public void mouseMoved(MouseEvent e) { if (iCurrentView == ID_MINIMAP) { switch (iCurrentCursor) { case ImageManager.CURSOR_ZOOM: { if (!MinimapZoomFrame.getSingleton().isVisible()) { MinimapZoomFrame.getSingleton().setVisible(true); } int mapWidth = (int) ServerSettings.getSingleton().getMapDimension().getWidth(); int mapHeight = (int) ServerSettings.getSingleton().getMapDimension().getHeight(); int x = (int) Math.rint((double) mapWidth / (double) getWidth() * (double) e.getX()); int y = (int) Math.rint((double) mapHeight / (double) getHeight() * (double) e.getY()); MinimapZoomFrame.getSingleton().updatePosition(x, y); break; } default: { if (MinimapZoomFrame.getSingleton().isVisible()) { MinimapZoomFrame.getSingleton().setVisible(false); } } } } Point location = minimapButtons.get(ID_MINIMAP).getLocation(); location.translate(-2, -2); if (!new Rectangle(location.x, location.y, 88, 30).contains(e.getPoint())) { //hide controls showControls = false; repaint(); } } }); addMouseWheelListener(new MouseWheelListener() { @Override public void mouseWheelMoved(MouseWheelEvent e) { if (iCurrentView != ID_MINIMAP) { return; } iCurrentCursor += e.getWheelRotation(); if (iCurrentCursor == ImageManager.CURSOR_DEFAULT + e.getWheelRotation()) { if (e.getWheelRotation() < 0) { iCurrentCursor = ImageManager.CURSOR_SHOT; } else { iCurrentCursor = ImageManager.CURSOR_MOVE; } } else if (iCurrentCursor < ImageManager.CURSOR_MOVE) { iCurrentCursor = ImageManager.CURSOR_DEFAULT; } else if (iCurrentCursor > ImageManager.CURSOR_SHOT) { iCurrentCursor = ImageManager.CURSOR_DEFAULT; } if (iCurrentCursor != ImageManager.CURSOR_ZOOM) { if (MinimapZoomFrame.getSingleton().isVisible()) { MinimapZoomFrame.getSingleton().setVisible(false); } } else { MinimapZoomFrame.getSingleton().setVisible(true); } setCurrentCursor(iCurrentCursor); } }); } private void showControls(Point p) { minimapButtons.get(ID_MINIMAP).setLocation(p.x + 2, p.y + 2); minimapButtons.get(ID_ALLY_CHART).setLocation(p.x + 30, p.y + 2); minimapButtons.get(ID_TRIBE_CHART).setLocation(p.x + 60, p.y + 2); showControls = true; repaint(); } public synchronized void addMinimapListener(MinimapListener pListener) { mMinimapListeners.add(pListener); } public synchronized void removeMinimapListener(MinimapListener pListener) { mMinimapListeners.remove(pListener); } public synchronized void addToolChangeListener(ToolChangeListener pListener) { mToolChangeListeners.add(pListener); } public synchronized void removeToolChangeListener(ToolChangeListener pListener) { mToolChangeListeners.remove(pListener); } public Point mousePosToMapPosition(double pX, double pY) { int x = rVisiblePart.x; int y = rVisiblePart.y; //calc dots per village double dpvx = (double) getWidth() / (double) rVisiblePart.width; double dpvy = (double) getHeight() / (double) rVisiblePart.height; x += (int) Math.round(pX / dpvx); y += (int) Math.round(pY / dpvy); return new Point(x, y); } public void setCurrentCursor(int pCurrentCursor) { iCurrentCursor = pCurrentCursor; setCursor(ImageManager.getCursor(iCurrentCursor)); fireToolChangedEvents(iCurrentCursor); } public void setSelection(int pX, int pY, int pWidth, int pHeight) { iX = pX; iY = pY; iWidth = pWidth; iHeight = pHeight; } @Override public void paintComponent(Graphics g) { super.paintComponent(g); try { Graphics2D g2d = (Graphics2D) g; g2d.clearRect(0, 0, getWidth(), getHeight()); g2d.drawImage(mBuffer, 0, 0, null); if (iCurrentView == ID_MINIMAP) { g2d.setColor(Color.YELLOW); int mapWidth = rVisiblePart.width; int mapHeight = rVisiblePart.height; int w = (int) Math.rint(((double) getWidth() / mapWidth) * (double) iWidth); int h = (int) Math.rint(((double) getHeight() / mapHeight) * (double) iHeight); double posX = ((double) getWidth() / mapWidth * (double) (iX - rVisiblePart.x)) - w / 2; double posY = ((double) getHeight() / mapHeight * (double) (iY - rVisiblePart.y)) - h / 2; g2d.drawRect((int) Math.rint(posX), (int) Math.rint(posY), w, h); if (iCurrentCursor == ImageManager.CURSOR_SHOT) { if (rDrag != null) { g2d.setColor(Color.ORANGE); g2d.drawRect((int) rDrag.getMinX(), (int) rDrag.getMinY(), (int) (rDrag.getWidth() - rDrag.getX()), (int) (rDrag.getHeight() - rDrag.getY())); } } else if (iCurrentCursor == ImageManager.CURSOR_ZOOM) { if (rDrag != null) { g2d.setColor(Color.CYAN); g2d.drawRect((int) rDrag.getX(), (int) rDrag.getY(), (int) (rDrag.getWidth() - rDrag.getX()), (int) ((rDrag.getWidth() - rDrag.getX()) * ((double) getHeight()) / getWidth())); } } } if (showControls) { //g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .2f)); Rectangle r = minimapButtons.get(ID_MINIMAP); g2d.setColor(Color.WHITE); Point menuPos = r.getLocation(); menuPos.translate(-2, -2); //draw border g2d.fillRect(menuPos.x, menuPos.y, 88, 30); g2d.setColor(Color.BLACK); //check if mouse is inside minimap button if (getMousePosition() != null && r.contains(getMousePosition())) { g2d.setColor(Color.YELLOW); g2d.fillRect(r.x, r.y, r.width, r.height); g2d.setColor(Color.BLACK); } g2d.drawImage(minimapIcons.get(ID_MINIMAP), r.x, r.y, null); g2d.drawRect(r.x, r.y, r.width, r.height); r = minimapButtons.get(ID_ALLY_CHART); //check if mouse is inside ally chart button if (getMousePosition() != null && r.contains(getMousePosition())) { g2d.setColor(Color.YELLOW); g2d.fillRect(r.x, r.y, r.width, r.height); g2d.setColor(Color.BLACK); } g2d.drawImage(minimapIcons.get(ID_ALLY_CHART), r.x, r.y, null); g2d.drawRect(r.x, r.y, r.width, r.height); r = minimapButtons.get(ID_TRIBE_CHART); //check if mouse is inside tribe chart button if (getMousePosition() != null && r.contains(getMousePosition())) { g2d.setColor(Color.YELLOW); g2d.fillRect(r.x, r.y, r.width, r.height); g2d.setColor(Color.BLACK); } g2d.drawImage(minimapIcons.get(ID_TRIBE_CHART), r.x, r.y, null); g2d.drawRect(r.x, r.y, r.width, r.height); } g2d.dispose(); } catch (Exception e) { logger.error("Failed painting Minimap", e); } } public void makeScreenshot() { jScreenshotPreview.setVisible(true); } public void resetBuffer() { mBuffer = null; redraw(); } protected void updateComplete() { try { if (iCurrentView == ID_MINIMAP) { BufferedImage scaled = MinimapRepaintThread.getSingleton().getScaledImage(getWidth(), getHeight()); if ((mBuffer == null || doRedraw || (mBuffer.getWidth(null) != getWidth()) || (mBuffer.getHeight(null) != getHeight())) && MinimapRepaintThread.getSingleton().drawn()) { if (scaled == null) { MinimapRepaintThread.getSingleton().update(); return; } mBuffer = scaled; } } else { // long s = System.currentTimeMillis(); int hash = MapPanel.getSingleton().getMapRenderer().getAllyCount().hashCode(); if (lastHash != hash) { renderChartInfo(); mBuffer = mChartImage; lastHash = hash; } // System.out.println("dur " + (System.currentTimeMillis() - s)); } repaint(); if (MinimapRepaintThread.getSingleton().drawn()) { //wait with redrawing for repaint Thread to finish doRedraw = false; } } catch (Exception e) { logger.error("Exception while updating Minimap", e); //ignore } } private void renderChartInfo() { HashMap<Object, Marker> marks = new HashMap<>(); DefaultPieDataset dataset = buildDataset(marks); JFreeChart chart = ChartFactory.createPieChart(null, // chart title dataset, // data true, // include legend true, false); chart.setBackgroundPaint(null); //chart.setBorderStroke(null); chart.setBorderVisible(false); final PiePlot plot = (PiePlot) chart.getPlot(); // plot.setBackgroundPaint(null); // plot.setShadowPaint(null); for (Object o : marks.keySet()) { if (iCurrentView == ID_ALLY_CHART) { Ally a = (Ally) o; plot.setSectionPaint(a.getTag(), marks.get(a).getMarkerColor()); } else { Tribe t = (Tribe) o; plot.setSectionPaint(t.getName(), marks.get(t).getMarkerColor()); } } //plot.setCircular(true); // plot.setMaximumLabelWidth(30.0); /* * plot.setLabelGenerator(new StandardPieSectionLabelGenerator( "{0} = {2}", NumberFormat.getNumberInstance(), * NumberFormat.getPercentInstance())); */ // chart.getLegend().setVerticalAlignment(VerticalAlignment.CENTER); // chart.getLegend().setPosition(RectangleEdge.RIGHT); // plot.setMaximumLabelWidth(20.0); plot.setLabelGenerator(null); plot.setBackgroundPaint(Constants.DS_BACK); /* * plot.setInteriorGap(0.0); plot.setLabelGap(0.0); */ plot.setLegendLabelGenerator(new StandardPieSectionLabelGenerator("{0} = {2}", NumberFormat.getNumberInstance(), NumberFormat.getPercentInstance())); /* * plot.getL plot.setLabelFont(g2d.getFont().deriveFont(10.0f)); */ //plot.setLabelGenerator(null); //plot.setMaximumLabelWidth(30.0); //plot.getLabelDistributor().distributeLabels(10.0, 20.0); //chart.draw(g2d, new Rectangle2D.Float(20, 20, 100, 100)); // g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); plot.setOutlineVisible(false); mChartImage = chart.createBufferedImage(getWidth(), getHeight()); //chart.draw(g2d, new Rectangle2D.Float(50, 50, 400, 400)); //g2d.drawImage(bi, 30, 30, null); // g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); //bi = chart.createBufferedImage(240, 240); // g2d.drawImage(bi, 30, 30, null); } private DefaultPieDataset buildDataset(HashMap<Object, Marker> marks) { DefaultPieDataset dataset = new DefaultPieDataset(); if (iCurrentView == ID_ALLY_CHART) { HashMap<Ally, Integer> allyCount = MapPanel.getSingleton().getMapRenderer().getAllyCount(); int overallVillages = 0; //count all villages for (Integer count : allyCount.values()) { overallVillages += count; } double rest = 0; for (Ally a : allyCount.keySet()) { Integer v = allyCount.get(a); Double perc = (double) v / (double) overallVillages * 100; if (perc > 5.0) { dataset.setValue(a.getTag(), perc); Marker m = MarkerManager.getSingleton().getMarker(a); if (m != null) { marks.put(a, m); } dataset.setValue(a.getTag(), new Double((double) v / (double) overallVillages * 100)); } else { rest += perc; } } dataset.setValue("Sonstige", rest); } else { HashMap<Tribe, Integer> tribeCount = MapPanel.getSingleton().getMapRenderer().getTribeCount(); int overallVillages = 0; //count all villages for (Integer trbCnt : tribeCount.values()) { overallVillages += trbCnt; } double rest = 0; for (Tribe t : tribeCount.keySet()) { Integer v = tribeCount.get(t); Double perc = (double) v / (double) overallVillages * 100; if (perc > 5.0) { dataset.setValue(t.getName(), perc); Marker m = MarkerManager.getSingleton().getMarker(t); if (m != null) { marks.put(t, m); } dataset.setValue(t.getName(), new Double((double) v / (double) overallVillages * 100)); } else { rest += perc; } } dataset.setValue("Sonstige", rest); } return dataset; } public void redraw() { doRedraw = true; try { MinimapRepaintThread.getSingleton().update(); } catch (Exception ignored) { } } public void redraw(boolean pResize) { rVisiblePart = new Rectangle(ServerSettings.getSingleton().getMapDimension()); MinimapRepaintThread.getSingleton().setVisiblePart(rVisiblePart); redraw(); } public synchronized void fireToolChangedEvents(int pTool) { for (ToolChangeListener l : mToolChangeListeners) { l.fireToolChangedEvent(pTool); } } /** * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The content of this * method is always regenerated by the Form Editor. */ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { jScreenshotControl = new javax.swing.JFrame(); jScalingSlider = new javax.swing.JSlider(); jLabel1 = new javax.swing.JLabel(); jLabel2 = new javax.swing.JLabel(); jFileTypeChooser = new javax.swing.JComboBox(); jButton1 = new javax.swing.JButton(); jButton2 = new javax.swing.JButton(); jLabel3 = new javax.swing.JLabel(); jTransparancySlider = new javax.swing.JSlider(); jScreenshotPreview = new javax.swing.JDialog(); jPanel1 = new javax.swing.JPanel(); jScreenshotControl.setTitle("Einstellungen"); jScreenshotControl.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { fireScreenshotControlClosingEvent(evt); } }); jScalingSlider.setMajorTickSpacing(1); jScalingSlider.setMaximum(10); jScalingSlider.setMinimum(1); jScalingSlider.setPaintLabels(true); jScalingSlider.setPaintTicks(true); jScalingSlider.setSnapToTicks(true); jScalingSlider.setValue(1); jScalingSlider.setOpaque(false); jScalingSlider.addChangeListener(new javax.swing.event.ChangeListener() { public void stateChanged(javax.swing.event.ChangeEvent evt) { fireChangeScreenshotScalingEvent(evt); } }); jLabel1.setText("Zoom"); jLabel2.setText("Dateityp"); jFileTypeChooser.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "png", "gif", "jpeg" })); jButton1.setText("Schlieen"); jButton1.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { fireCloseScreenshotEvent(evt); } }); jButton2.setText("Speichern"); jButton2.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { fireSaveScreenshotEvent(evt); } }); jLabel3.setText("Legendentransparenz"); jTransparancySlider.setMajorTickSpacing(1); jTransparancySlider.setMaximum(10); jTransparancySlider.setPaintLabels(true); jTransparancySlider.setPaintTicks(true); jTransparancySlider.setSnapToTicks(true); jTransparancySlider.setToolTipText("Transparenz der Legende (10 = keine Legende)"); jTransparancySlider.setValue(0); jTransparancySlider.setOpaque(false); javax.swing.GroupLayout jScreenshotControlLayout = new javax.swing.GroupLayout( jScreenshotControl.getContentPane()); jScreenshotControl.getContentPane().setLayout(jScreenshotControlLayout); jScreenshotControlLayout.setHorizontalGroup(jScreenshotControlLayout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jScreenshotControlLayout.createSequentialGroup().addContainerGap() .addGroup(jScreenshotControlLayout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jScreenshotControlLayout.createSequentialGroup() .addGap(0, 0, Short.MAX_VALUE).addComponent(jButton1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jButton2)) .addGroup(jScreenshotControlLayout.createSequentialGroup() .addGroup(jScreenshotControlLayout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel1).addComponent(jLabel3).addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jScreenshotControlLayout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jTransparancySlider, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 236, Short.MAX_VALUE) .addComponent(jScalingSlider, javax.swing.GroupLayout.DEFAULT_SIZE, 236, Short.MAX_VALUE) .addComponent(jFileTypeChooser, 0, 236, Short.MAX_VALUE)))) .addContainerGap())); jScreenshotControlLayout.setVerticalGroup(jScreenshotControlLayout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jScreenshotControlLayout.createSequentialGroup().addContainerGap() .addGroup(jScreenshotControlLayout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jScalingSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jScreenshotControlLayout .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jTransparancySlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jScreenshotControlLayout .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jFileTypeChooser, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel2)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 36, Short.MAX_VALUE) .addGroup(jScreenshotControlLayout .createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jButton2).addComponent(jButton1)) .addContainerGap())); jScreenshotPreview.setTitle("Vorschau"); jScreenshotPreview.addWindowListener(new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent evt) { fireMapPreviewClosingEvent(evt); } }); jPanel1.setBackground(new java.awt.Color(102, 255, 102)); jPanel1.setOpaque(false); jPanel1.setPreferredSize(new java.awt.Dimension(0, 0)); jPanel1.setLayout(new java.awt.BorderLayout()); javax.swing.GroupLayout jScreenshotPreviewLayout = new javax.swing.GroupLayout( jScreenshotPreview.getContentPane()); jScreenshotPreview.getContentPane().setLayout(jScreenshotPreviewLayout); jScreenshotPreviewLayout.setHorizontalGroup( jScreenshotPreviewLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jScreenshotPreviewLayout.createSequentialGroup().addContainerGap() .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 321, Short.MAX_VALUE) .addContainerGap())); jScreenshotPreviewLayout.setVerticalGroup( jScreenshotPreviewLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jScreenshotPreviewLayout.createSequentialGroup().addContainerGap() .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE) .addContainerGap())); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 304, Short.MAX_VALUE)); layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGap(0, 142, Short.MAX_VALUE)); }// </editor-fold>//GEN-END:initComponents private void fireChangeScreenshotScalingEvent(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_fireChangeScreenshotScalingEvent mScreenshotPanel.setScaling(jScalingSlider.getValue()); jPanel1.setSize(mScreenshotPanel.getSize()); jPanel1.setPreferredSize(mScreenshotPanel.getSize()); jPanel1.setMinimumSize(mScreenshotPanel.getSize()); jPanel1.setMaximumSize(mScreenshotPanel.getSize()); jScreenshotPreview.pack(); }//GEN-LAST:event_fireChangeScreenshotScalingEvent private void fireCloseScreenshotEvent(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_fireCloseScreenshotEvent jScreenshotPreview.setVisible(false); jScreenshotControl.setVisible(false); }//GEN-LAST:event_fireCloseScreenshotEvent private void fireSaveScreenshotEvent(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_fireSaveScreenshotEvent String dir = GlobalOptions.getProperty("screen.dir"); JFileChooser chooser = null; try { chooser = new JFileChooser(dir); } catch (Exception e) { JOptionPaneHelper.showErrorBox(this, "Konnte Dateiauswahldialog nicht ffnen.\nMglicherweise verwendest du Windows Vista. Ist dies der Fall, beende DS Workbench, klicke mit der rechten Maustaste auf DSWorkbench.exe,\n" + "whle 'Eigenschaften' und deaktiviere dort unter 'Kompatibilitt' den Windows XP Kompatibilittsmodus.", "Fehler"); return; } chooser.setDialogTitle("Speichern unter..."); chooser.setSelectedFile(new File("map")); final String type = (String) jFileTypeChooser.getSelectedItem(); chooser.setFileFilter(new FileFilter() { @Override public boolean accept(File f) { return (f != null) && (f.isDirectory() || f.getName().endsWith(type)); } @Override public String getDescription() { return "*." + type; } }); int ret = chooser.showSaveDialog(jScreenshotControl); if (ret == JFileChooser.APPROVE_OPTION) { try { File f = chooser.getSelectedFile(); String file = f.getCanonicalPath(); if (!file.endsWith(type)) { file += "." + type; } File target = new File(file); if (target.exists()) { //ask if overwrite if (JOptionPaneHelper.showQuestionConfirmBox(jScreenshotControl, "Existierende Datei berschreiben?", "berschreiben", "Nein", "Ja") != JOptionPane.YES_OPTION) { return; } } ImageIO.write(mScreenshotPanel.getResult(jTransparancySlider.getValue()), type, target); GlobalOptions.addProperty("screen.dir", target.getParent()); } catch (Exception e) { logger.error("Failed to write map shot", e); } } }//GEN-LAST:event_fireSaveScreenshotEvent private void fireMapPreviewClosingEvent(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_fireMapPreviewClosingEvent jScreenshotControl.setVisible(false); }//GEN-LAST:event_fireMapPreviewClosingEvent private void fireScreenshotControlClosingEvent(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_fireScreenshotControlClosingEvent jScreenshotPreview.setVisible(false); }//GEN-LAST:event_fireScreenshotControlClosingEvent // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton jButton1; private javax.swing.JButton jButton2; private javax.swing.JComboBox jFileTypeChooser; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JPanel jPanel1; private javax.swing.JSlider jScalingSlider; private javax.swing.JFrame jScreenshotControl; private javax.swing.JDialog jScreenshotPreview; private javax.swing.JSlider jTransparancySlider; // End of variables declaration//GEN-END:variables } class MinimapRepaintThread extends Thread { private static Logger logger = LogManager.getLogger("MinimapRenderer"); private BufferedImage mBuffer = null; private boolean drawn = false; private Rectangle mapDim = null; private static MinimapRepaintThread SINGLETON = null; private Rectangle visiblePart = null; public static synchronized MinimapRepaintThread getSingleton() { if (SINGLETON == null) { try { SINGLETON = new MinimapRepaintThread(); } catch (Exception e) { SINGLETON = null; } } return SINGLETON; } MinimapRepaintThread() { setName("MinimapUpdater"); setDaemon(true); } public void setVisiblePart(Rectangle pVisible) { visiblePart = (Rectangle) pVisible.clone(); } public void update() { Rectangle currentDim = ServerSettings.getSingleton().getMapDimension(); if (currentDim == null) { return; } if ((mapDim == null) || (!mapDim.equals(currentDim))) { mapDim = new Rectangle(currentDim); mBuffer = ImageUtils.createCompatibleBufferedImage(mapDim.width, mapDim.height, BufferedImage.TYPE_INT_ARGB_PRE); } drawn = false; } protected BufferedImage getImage() { BufferedImage tempImg = ImageUtils.createCompatibleBufferedImage(mapDim.width, mapDim.height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = (Graphics2D) tempImg.getGraphics(); g2d.setColor(new Color(35, 125, 0)); g2d.fillRect(0, 0, tempImg.getWidth(null), tempImg.getHeight(null)); g2d.drawImage(mBuffer, 0, 0, null); g2d.dispose(); return tempImg; } protected BufferedImage getScaledImage(int width, int height) { BufferedImage tempImg = ImageUtils.createCompatibleBufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = (Graphics2D) tempImg.getGraphics(); g2d.setColor(new Color(35, 125, 0)); g2d.fillRect(0, 0, tempImg.getWidth(null), tempImg.getHeight(null)); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); g2d.drawImage(mBuffer, 0, 0, width, height, 0, 0, mBuffer.getWidth(), mBuffer.getHeight(), null); g2d.dispose(); return tempImg; } public boolean drawn() { return drawn; } @Override public void run() { while (true) { try { if (!drawn) { drawn = redraw(); MinimapZoomFrame.getSingleton().setMinimap(getImage()); } MinimapPanel.getSingleton().updateComplete(); try { Thread.sleep(100); } catch (Exception ignored) { } } catch (Exception oe) { if (mBuffer == null) { update(); } else { logger.error("Failed to re-render minimap", oe); } } } } private boolean redraw() { Village[][] mVisibleVillages = DataHolder.getSingleton().getVillages(); if (mVisibleVillages == null || mBuffer == null) { return false; } Graphics2D g2d = (Graphics2D) mBuffer.getGraphics(); Composite tempC = g2d.getComposite(); //clear g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR)); g2d.fillRect(0, 0, mBuffer.getWidth(), mBuffer.getHeight()); //reset composite g2d.setComposite(tempC); boolean markPlayer = GlobalOptions.getProperties().getBoolean("mark.villages.on.minimap"); if (ServerSettings.getSingleton().getMapDimension() == null) { //could not draw minimap if dimensions are not loaded yet return false; } boolean showBarbarian = GlobalOptions.getProperties().getBoolean("show.barbarian"); Color DEFAULT = Constants.DS_DEFAULT_MARKER; try { int mark = Integer.parseInt(GlobalOptions.getProperty("default.mark")); if (mark == 0) { DEFAULT = Constants.DS_DEFAULT_MARKER; } else if (mark == 1) { DEFAULT = Color.RED; } else if (mark == 2) { DEFAULT = Color.WHITE; } } catch (Exception e) { DEFAULT = Constants.DS_DEFAULT_MARKER; } Rectangle mapDim = ServerSettings.getSingleton().getMapDimension(); double wField = mapDim.getWidth() / (double) visiblePart.width; double hField = mapDim.getHeight() / (double) visiblePart.height; UserProfile profile = GlobalOptions.getSelectedProfile(); Tribe currentTribe = InvalidTribe.getSingleton(); if (profile != null) { currentTribe = profile.getTribe(); } for (int i = visiblePart.x; i < (visiblePart.width + visiblePart.x); i++) { for (int j = visiblePart.y; j < (visiblePart.height + visiblePart.y); j++) { Village v = mVisibleVillages[i][j]; if (v != null) { Color markerColor = null; boolean isLeft = false; if (v.getTribe() == Barbarians.getSingleton()) { isLeft = true; } else { if ((currentTribe != null) && (v.getTribe().getId() == currentTribe.getId())) { //village is owned by current player. mark it dependent on settings if (markPlayer) { markerColor = Color.YELLOW; } } else { try { Marker marker = MarkerManager.getSingleton().getMarker(v.getTribe()); if (marker != null && !marker.isShownOnMap()) { marker = null; markerColor = DEFAULT; } if (marker == null) { marker = MarkerManager.getSingleton().getMarker(v.getTribe().getAlly()); if (marker != null && marker.isShownOnMap()) { markerColor = marker.getMarkerColor(); } } else { if (marker.isShownOnMap()) { markerColor = marker.getMarkerColor(); } } } catch (Exception e) { markerColor = null; } } } if (!isLeft) { if (markerColor != null) { g2d.setColor(markerColor); } else { g2d.setColor(DEFAULT); } g2d.fillRect((int) Math.round((i - visiblePart.x) * wField), (int) Math.round((j - visiblePart.y) * hField), (int) Math.floor(wField), (int) Math.floor(hField)); } else { if (showBarbarian) { g2d.setColor(Color.LIGHT_GRAY); g2d.fillRect((int) Math.round((i - visiblePart.x) * wField), (int) Math.round((j - visiblePart.y) * hField), (int) Math.floor(wField), (int) Math.floor(hField)); } } } } } try { if (GlobalOptions.getProperties().getBoolean("map.showcontinents")) { g2d.setColor(Color.BLACK); Composite c = g2d.getComposite(); Composite a = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f); Font f = g2d.getFont(); Font t = new Font("Serif", Font.BOLD, (int) Math.round(30 * hField)); g2d.setFont(t); int fact = 10; int mid = (int) Math.round(50 * wField); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) { g2d.setComposite(a); String conti = "K" + (j * 10 + i); Rectangle2D bounds = g2d.getFontMetrics(t).getStringBounds(conti, g2d); int cx = i * fact * 10 - visiblePart.x; int cy = j * fact * 10 - visiblePart.y; cx = (int) Math.round(cx * wField); cy = (int) Math.round(cy * hField); g2d.drawString(conti, (int) Math.rint(cx + mid - bounds.getWidth() / 2), (int) Math.rint(cy + mid + bounds.getHeight() / 2)); g2d.setComposite(c); int wk = 100; int hk = 100; if (i == 9) { wk -= 1; } if (j == 9) { hk -= 1; } g2d.drawRect(cx, cy, (int) Math.round(wk * wField), (int) Math.round(hk * hField)); } } g2d.setFont(f); } } catch (Exception e) { logger.error("Creation of Minimap failed", e); } g2d.dispose(); return true; } }