Commit 4588e9b0 authored by kirandjiska's avatar kirandjiska

Added zoom box view on ConstraintsSelectionDialog

parent 927a9cbb
package mustic.gui.dialog.classifier;
import java.awt.AWTException;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
......@@ -13,12 +12,6 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
......@@ -42,15 +35,10 @@ import java.util.List;
import java.util.Random;
import java.util.Vector;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JInternalFrame;
......@@ -62,9 +50,7 @@ import javax.swing.JSlider;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JWindow;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
......@@ -81,6 +67,8 @@ import jcl.clustering.constraints.MustLinkConstraint;
import jcl.clustering.constraints.NbClusterConstraint;
import jcl.data.Data;
import jcl.utils.Images.StreamedImageReaderWrapper;
import mustic.gui.tools.ZoomBoxPanel;
import mustic.gui.tools.Zoomable;
import mustic.io.RawImage;
import mustic.utils.filters.CSVFileFilter;
import mustic.utils.io.CSVUtils;
......@@ -91,7 +79,7 @@ import mustic.utils.io.CSVUtils;
* @author Baptiste LAFABREGUE
*
*/
public class ConstraintsSelectionDialog extends JInternalFrame {
public class ConstraintsSelectionDialog extends JInternalFrame implements Zoomable {
private static final long serialVersionUID = 1L;
......@@ -105,10 +93,12 @@ public class ConstraintsSelectionDialog extends JInternalFrame {
private BufferedImage imagePoints = null;
private BufferedImage imageSource = null;
private BufferedImage mNew = null;
//private JLabel labelImage;
private JPanel displayPanel = null;
public JPanel mainPanel;
protected int labelClassesCount = 1;
......@@ -175,16 +165,7 @@ public class ConstraintsSelectionDialog extends JInternalFrame {
private Vector<JButton> jb_labelConstraintClassChooseColor = new Vector<JButton>();
/** dynamic JPanel Colors of Label Constraints Classes*/
JPanel labelColorConstraintPanel = new JPanel(new GridLayout(0,1));
/** Components of Lens Zoom*/
private Boolean zoomBoxActivated = false;
private Boolean zoomBoxSelected = false;
// ZoomBoxView zoomBox;
ZoomBoxWindow zoomBox;
JPanel labelColorConstraintPanel = new JPanel(new GridLayout(0,1));
/**
* Constructor to a dialog window to visualize and build a set of
......@@ -212,61 +193,21 @@ public class ConstraintsSelectionDialog extends JInternalFrame {
}
// display the image
// this.labelImage = new JLabel();
// this.labelImage.setHorizontalAlignment(SwingConstants.CENTER);
// panelImage.add(this.labelImage, BorderLayout.CENTER);
// this.labelImage.addMouseWheelListener(new MouseWheelListener() {
// @Override
// public void mouseWheelMoved(MouseWheelEvent e) {
// if (e.getUnitsToScroll() > 0) {
// zoomIn();
// } else {
// zoomOut();
// }
// }
// });
this.displayPanel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Graphics2D g2d = (Graphics2D) g.create();
Point offset = getOffset();
g2d.drawImage(img, offset.x, offset.y, this);
if (zoomPoint != null) { // if clicked inside image bounds
BufferedImage zoomBuffer = updateBuffer(zoomPoint); // create the zoomed image
if (zoomBuffer != null) {
Rectangle bounds = getZoomBounds();
g2d.drawImage(zoomBuffer, bounds.x, bounds.y, this);
g2d.setColor(Color.RED);
g2d.draw(bounds); // draw a red rectangle frame around zoom box panel
}
}
g2d.dispose();
}
}
}
protected Point getOffset() {
if (imagePoints == null) {
return new Point(0, 0);
}
// image displayed at this offset, img centered in JPanel
int x = (displayPanel.getWidth() - imagePoints.getWidth()) / 2;
int y = (displayPanel.getHeight() - imagePoints.getHeight()) / 2;
return new Point(x, y);
}
this.displayPanel = (JPanel) new ZoomBoxPanel(this);
this.displayPanel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
// point coordinates relative to img
// point coordinates relative to img
int x = (int) ((e.getX()
- (int) ((displayPanel.getWidth() - (displayPanel.getIcon().getIconWidth())) / 2.0)) / mZoomRate);
- (int) ((displayPanel.getWidth() - (mNew.getWidth())) / 2.0)) / mZoomRate);
int y = (int) ((e.getY()
- (int) ((displayPanel.getHeight() - (displayPanel.getIcon().getIconHeight())) / 2.0)) / mZoomRate);
- (int) ((displayPanel.getHeight() - (mNew.getHeight())) / 2.0)) / mZoomRate);
// int x = (int) ((e.getX()
// - (int) ((displayPanel.getWidth() - (imagePoints.getWidth())) / 2.0)) / mZoomRate);
// int y = (int) ((e.getY()
// - (int) ((displayPanel.getHeight() - (imagePoints.getHeight())) / 2.0)) / mZoomRate);
if (x >= 0 && y >= 0 && x < imageSource.getWidth() * mZoomRate
&& y < imageSource.getHeight() /* mZoomRate*/) {
switch (currentStep) {
......@@ -288,13 +229,27 @@ public class ConstraintsSelectionDialog extends JInternalFrame {
addSecondPixel(x, y);
break;
default:
// we don't refresh if not a valid step
// we don't refresh if not a valid step
return;
}
displayPixels();
}
}
});
this.displayPanel.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.getUnitsToScroll() > 0) {
zoomIn();
} else {
zoomOut();
}
}
});
panelImage.add(this.displayPanel, BorderLayout.CENTER);
setImage(img);
......@@ -359,21 +314,17 @@ public class ConstraintsSelectionDialog extends JInternalFrame {
otherComponentList.add(constraintsColorChooser);
JCheckBox zoomBoxChkBox = new JCheckBox("Zoom Box");
// zoomBox = new ZoomBoxView(this);
zoomBox = new ZoomBoxWindow(this);
zoomBoxChkBox.setMnemonic(KeyEvent.VK_Z);
zoomBoxChkBox.setSelected(zoomBoxActivated);
// zoomBoxChkBox.setSelected(zoomBoxActivated);
zoomBoxChkBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
// zoomBox.setZoomBoxVisibility(true);
// zoomBoxSelected = true;
((ZoomBoxPanel) displayPanel).setZoomBoxEnabled(true);
} else {
// zoomBox.setZoomBoxVisibility(false);
// zoomBoxSelected = false;
((ZoomBoxPanel) displayPanel).setZoomBoxEnabled(false);
}
}
});
......@@ -403,18 +354,18 @@ public class ConstraintsSelectionDialog extends JInternalFrame {
jb_cannotLinkChooseColor.setBackground(cannotLinkColor);
jb_mustLinkChooseColor.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
chooseMustLinkColor();
}
@Override
public void actionPerformed(ActionEvent e) {
chooseMustLinkColor();
}
});
jb_cannotLinkChooseColor.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
chooseCannotLinkColor();
}
@Override
public void actionPerformed(ActionEvent e) {
chooseCannotLinkColor();
}
});
// initialize the color,
......@@ -450,8 +401,9 @@ public class ConstraintsSelectionDialog extends JInternalFrame {
return panelImage;
}
protected BufferedImage getImage() {
return imagePoints;
@Override
public BufferedImage getDisplayedImage() {
return mNew;
}
protected void exportConstraints() {
......@@ -1286,10 +1238,9 @@ public class ConstraintsSelectionDialog extends JInternalFrame {
private void doZoomOp() {
AffineTransform trans = AffineTransform.getScaleInstance(this.mZoomRate, this.mZoomRate);
AffineTransformOp op = new AffineTransformOp(trans, AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
BufferedImage mNew = op.filter(this.imagePoints, null);
ImageIcon i = new ImageIcon();
i.getImage().
this.labelImage.setIcon(new ImageIcon(mNew));
mNew = op.filter(this.imagePoints, null);
displayPanel.repaint();
}
@SuppressWarnings("unchecked")
......@@ -1455,6 +1406,15 @@ public class ConstraintsSelectionDialog extends JInternalFrame {
System.out.println(Messages.getString("ConstraintsSelectionDialog.29")); //$NON-NLS-1$
}
public JPanel getDisplayPanel() {
return displayPanel;
}
public void setDisplayPanel(JPanel displayPanel) {
this.displayPanel = displayPanel;
}
private abstract class CustomizedActionListener implements ActionListener {
JPanel container;
......@@ -1463,4 +1423,16 @@ public class ConstraintsSelectionDialog extends JInternalFrame {
}
}
@Override
public Image getMatchingImage(int x, int y, int width, int height, float zoom) {
BufferedImage subImage = this.getOriginalImage().getSubimage(x, y, width, height);
return subImage.getScaledInstance((int) (width * zoom), (int) (height *zoom ), Image.SCALE_SMOOTH);
}
public BufferedImage getOriginalImage() {
return imagePoints;
}
}
package mustic.gui.dialog.classifier;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ZoomBoxView extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
protected static final int ZOOM_AREA = 40;
// private BufferedImage originalImage;
private JWindow popup;
private Boolean zoomBoxActivated = false;
private ConstraintsSelectionDialog dialog = null;
private BufferedImage buffer;
private float zoomLevel = 4f;
public ZoomBoxView(ConstraintsSelectionDialog dialog) {
this.dialog = dialog;
popup = new JWindow();
popup.setLayout(new BorderLayout());
popup.add(this);
popup.pack();
popup.setAlwaysOnTop(true);
MouseAdapter ma = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
Point p = e.getPoint();
// System.out.println(p);
Point pos = e.getLocationOnScreen();
Point origPoint = getOriginalPointCoordinates(p); // get the original position of the point coordinate on the zoomed image
updateBuffer(origPoint);
// popup.setLocation(pos.x + 16, pos.y + 16);
popup.setLocation(pos.x - popup.getWidth()/2, pos.y - popup.getHeight()/2);
repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
if (zoomBoxActivated) {
popup.setVisible(true);
}
}
@Override
public void mouseExited(MouseEvent e) {
popup.setVisible(false);
}
};
dialog.getImgLabel().addMouseListener(ma);
dialog.getImgLabel().addMouseMotionListener(ma);
}
/** p - cursor coordinates relative to parent window*/
/**private void updateBuffer(Point p) {
int width = Math.round(ZOOM_AREA);
int height = Math.round(ZOOM_AREA);
buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d =(Graphics2D) originalImage.getGraphics();
AffineTransform at = new AffineTransform();
// center cursor in the zoomBox
int xPos = (ZOOM_AREA / 2) - p.x;
int yPos = (ZOOM_AREA / 2) - p.y;
if (xPos > 0) {
xPos = 0;
}
if (yPos > 0) {
yPos = 0;
}
// if outside the parent window
// fix parent size on original image size
if ((xPos * -1) + ZOOM_AREA > parent.getWidth()) {
xPos = (parent.getWidth() - ZOOM_AREA) * -1;
}
if ((yPos * -1) + ZOOM_AREA > parent.getHeight()) {
yPos = (parent.getHeight()- ZOOM_AREA) * -1;
}
at.translate(xPos, yPos);
g2d.setTransform(at);
parent.paint(g2d);
g2d.dispose();
}*/
private void updateBuffer(Point p) {
int width = Math.round(ZOOM_AREA);
int height = Math.round(ZOOM_AREA);
buffer = dialog.getImage().getSubimage(p.x - ZOOM_AREA/2, p.y - ZOOM_AREA/2, width, height);
//rajoute condition s'il sort dehors
}
@Override
public Dimension getPreferredSize() {
return new Dimension(Math.round(ZOOM_AREA * zoomLevel), Math.round(ZOOM_AREA * zoomLevel));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (buffer != null) {
AffineTransform at = g2d.getTransform();
g2d.setTransform(AffineTransform.getScaleInstance(zoomLevel, zoomLevel));
g2d.drawImage(buffer, 0, 0, this);
g2d.setTransform(at);
}
g2d.setColor(Color.RED);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g2d.drawLine(getWidth()/2-1, 0, getWidth()/2-1, getHeight()-1);
g2d.drawLine(0,getHeight()/2-1,getWidth()-1,getHeight()/2-1 );
g2d.drawRect(getWidth()/2-1-4, getHeight()/2-1-4, 8, 8);
g2d.dispose();
}
protected void setZoomBoxVisibility(boolean visibility) {
popup.setVisible(visibility);
zoomBoxActivated = visibility;
}
private Point getOriginalPointCoordinates(Point p) {
//point coordinated relative to original image
int x = (int) ((p.getX()
- (int) ((dialog.getImgLabel().getWidth() - (dialog.getImgLabel().getIcon().getIconWidth())) / 2.0)) / dialog.getmZoomRate());
int y = (int) ((p.getY()
- (int) ((dialog.getImgLabel().getHeight() - (dialog.getImgLabel().getIcon().getIconHeight())) / 2.0)) / dialog.getmZoomRate());
// if (x >= 0 && y >= 0 && x < originalImage.getWidth() * zoomLevel
// && y < originalImage.getHeight() * zoomLevel) {
return new Point(x,y);
}
}
package mustic.gui.dialog.classifier;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ZoomBoxWindow /*extends JPanel*/ {
private ConstraintsSelectionDialog dialog = null;
private Point zoomPoint; // cursor point relative to img panel
private boolean zoomEnabled = true; // a variable indicating if the zoom box panel is enabled
private int zoomArea = 80; // size of zoom box panel
private float zoom = 2.0f; // zoomRate
public ZoomBoxWindow(ConstraintsSelectionDialog dialog) {
this.dialog = dialog;
MouseAdapter ma = new MouseAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
zoomPoint = getOriginalPointCoordinates(e.getPoint()); // at every mouse motion get coordinates of cursor point and repaint the zoom box panel
// System.out.println("ZoomPoint on mouse motion " + zoomPoint);
paintZoomBox();
// repaint(); //calls paintComponent()
// dialog.getImgLabel().validate();
// dialog.getImgLabel().repaint();
}
@Override
public void mouseEntered(MouseEvent e) {
if (zoomEnabled) {
// repaint();
paintZoomBox();
// dialog.getImgLabel().repaint();
}
}
@Override
public void mouseExited(MouseEvent e) {
zoomPoint = null;
// repaint();
paintZoomBox();
// dialog.getImgLabel().repaint();
}
};
dialog.getImgLabel().addMouseListener(ma);
dialog.getImgLabel().addMouseMotionListener(ma);
}
public float getZoom() {
return zoom;
}
public void setZoom(float zoom) {
this.zoom = zoom;
paintZoomBox();
dialog.getImgLabel().repaint();
}
public int getZoomArea() {
return zoomArea;
}
public void setZoomArea(int zoomArea) {
this.zoomArea = zoomArea;
paintZoomBox();
dialog.getImgLabel().repaint();
}
public boolean isZoomEnabled() {
return zoomEnabled;
}
public void setZoomEnabled(boolean zoomEnabled) {
this.zoomEnabled = zoomEnabled;
paintZoomBox();
dialog.getImgLabel().repaint();
}
// @Override
// public Dimension getPreferredSize() {
// return new Dimension(Math.round(zoomArea * zoom), Math.round(zoomArea * zoom));
// }
//offset of image relative to JLabel
protected Point getOffset() {
if (dialog.getImage() == null) {
return new Point(0, 0);
}
int x = (dialog.getImgLabel().getWidth() - dialog.getImgLabel().getIcon().getIconWidth()) / 2;
int y = (dialog.getImgLabel().getHeight() - dialog.getImgLabel().getIcon().getIconHeight()) / 2;
return new Point(x, y);
}
// set a rectangle frame around image
// create bounds of image size, the offset needed is the offset of the getOffset function
// return this rectangle frame
protected Rectangle getImageBounds() {
Rectangle bounds = new Rectangle(0, 0, 0, 0);
if (dialog.getImage() != null) {
bounds.setLocation(getOffset());
bounds.setSize(dialog.getImage().getWidth(), dialog.getImage().getHeight());
}
return bounds;
}