package client.components.imagePanel; import client.components.imagePanel.listeners.ImageControlsListener; import client.components.listeners.DrawingListener; import client.persistence.*; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseWheelEvent; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; public class ScalableImage extends JPanel { private BufferedImage image; private int w_originX; private int w_originY; private double scale; private boolean dragging; private int w_dragStartX; private int w_dragStartY; private int w_dragStartOriginX; private int w_dragStartOriginY; private ImageTable imageTable; private double MAX_SCROLL = 1.0f; private double MIN_SCROLL = 0.2f; private ImageState imageState; public ScalableImage(ImageState imageState) { this.imageState = imageState; this.setBackground(Color.DARK_GRAY); initDrag(); this.addMouseListener(mouseAdapter); this.addMouseMotionListener(mouseAdapter); this.addMouseWheelListener(mouseAdapter); setupView(); this.imageState.addListener(imageStateListener); this.imageState.addNewProjectListener(newProjectListener); } private void setupView() { image = imageState.getImage(); imageTable = new ImageTable(imageState); this.setOrigin(imageState.getSettings().getImageOriginX(), imageState.getSettings().getImageOriginY()); this.setScale(imageState.getSettings().getImageScaleLevel()); this.repaint(); } public void refreshImage() { imageTable.setDeactivated(true); setupView(); } boolean redrawHack = false; @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; g2.translate(this.getWidth() / 2, this.getHeight() / 2); g2.scale(scale, scale); g2.translate(-w_originX, -w_originY); g2.drawImage(image, 0, 0, null); imageTable.paint(g2); if(!redrawHack) { redrawHack = true; this.repaint(); } } public void invertImage(BufferedImage b) { for (int x = 0; x < b.getWidth(); x++) { for (int y = 0; y < b.getHeight(); y++) { int rgba = b.getRGB(x, y); Color col = new Color(rgba, true); col = new Color(255 - col.getRed(), 255 - col.getGreen(), 255 - col.getBlue()); b.setRGB(x, y, col.getRGB()); } } boolean current = imageState.getSettings().isImageInverted(); imageState.getSettings().setImageInverted(!current); redrawHack = false; this.repaint(); } public void setValue(Cell cell, String value) { imageTable.setCurrentCell(cell.getField(), cell.getRecord()); this.repaint(); } public void setCurrentCell(Cell cell) { imageTable.setCurrentCell(cell.getField(), cell.getRecord()); this.repaint(); } private void initDrag() { dragging = false; w_dragStartX = 0; w_dragStartY = 0; w_dragStartOriginX = 0; w_dragStartOriginY = 0; } public void setScale(double newScale) { scale = newScale; this.repaint(); } public void setOrigin(int w_newOriginX, int w_newOriginY) { w_originX = w_newOriginX; w_originY = w_newOriginY; this.repaint(); } private MouseAdapter mouseAdapter = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if(!imageState.isHasImage()) return; int d_X = e.getX(); int d_Y = e.getY(); AffineTransform transform = new AffineTransform(); transform.translate(getWidth()/2, getHeight()/2); transform.scale(scale, scale); transform.translate(-w_originX, -w_originY); Point2D d_Pt = new Point2D.Double(d_X, d_Y); Point2D w_Pt = new Point2D.Double(); try { transform.inverseTransform(d_Pt, w_Pt); } catch (NoninvertibleTransformException ex) { return; } int w_X = (int)w_Pt.getX(); int w_Y = (int)w_Pt.getY(); imageTable.contains(w_X, w_Y); dragging = true; w_dragStartX = w_X; w_dragStartY = w_Y; w_dragStartOriginX = w_originX; w_dragStartOriginY = w_originY; repaint(); } @Override public void mouseDragged(MouseEvent e) { if (dragging) { int d_X = e.getX(); int d_Y = e.getY(); AffineTransform transform = new AffineTransform(); transform.translate(getWidth()/2, getHeight()/2); transform.scale(scale, scale); transform.translate(-w_dragStartOriginX, -w_dragStartOriginY); Point2D d_Pt = new Point2D.Double(d_X, d_Y); Point2D w_Pt = new Point2D.Double(); try { transform.inverseTransform(d_Pt, w_Pt); } catch (NoninvertibleTransformException ex) { return; } int w_X = (int)w_Pt.getX(); int w_Y = (int)w_Pt.getY(); int w_deltaX = w_X - w_dragStartX; int w_deltaY = w_Y - w_dragStartY; w_originX = w_dragStartOriginX - w_deltaX; w_originY = w_dragStartOriginY - w_deltaY; repaint(); } } @Override public void mouseReleased(MouseEvent e) { initDrag(); imageState.getSettings().setImageOriginX(w_originX); imageState.getSettings().setImageOriginY(w_originY); } @Override public void mouseWheelMoved(MouseWheelEvent e) { int rotation = e.getWheelRotation(); if((rotation > 0) && scale > MIN_SCROLL ) { setScale(scale - 0.02f); } else if (scale < MAX_SCROLL) { setScale(scale + 0.02f); } imageState.getSettings().setImageScaleLevel(scale); } }; private ImageStateListener imageStateListener = new ImageStateListener() { @Override public void valueChanged(Cell cell, String newValue) { return; } @Override public void selectedCellChanged(Cell newSelectedCell) { imageTable.setCurrentCell(newSelectedCell.getField(), newSelectedCell.getRecord()); repaint(); } }; private NewProjectListener newProjectListener = new NewProjectListener() { @Override public void hasNewProject() { refreshImage(); } }; private ImageControlsListener imageControlsListener = new ImageControlsListener() { @Override public void onScrollIncrease() { if (scale < MAX_SCROLL) { setScale(scale + 0.02f); } } @Override public void onScrollDecrease() { if(scale > MIN_SCROLL ) { setScale(scale - 0.02f); } } @Override public void onInvertImage() { invertImage(image); } @Override public void onToggleHighlights() { if(imageTable.isHighlightsEnabled()) { imageTable.enableHighlights(false); } else { imageTable.enableHighlights(true); } repaint(); } }; public ImageControlsListener getImageControlsListener() { return imageControlsListener; } }