package jp.crwdev.app.gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
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.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.LinkedList;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SpringLayout;
import jp.crwdev.app.BufferedImageIO;
import jp.crwdev.app.EventObserver;
import jp.crwdev.app.EventObserver.OnEventListener;
import jp.crwdev.app.container.ImageFileInfoSplitWrapper;
import jp.crwdev.app.imagefilter.AddSpaceFilter;
import jp.crwdev.app.imagefilter.ImageFilterParam;
import jp.crwdev.app.imagefilter.PreviewImageFilter;
import jp.crwdev.app.imagefilter.ResizeFilter;
import jp.crwdev.app.imagefilter.SplitFilter;
import jp.crwdev.app.interfaces.IImageFileInfo;
import jp.crwdev.app.setting.ImageFilterParamSet;
import jp.crwdev.app.util.ImageCache;
import jp.crwdev.app.util.ImageCache.ImageData;
@SuppressWarnings("serial")
public class ImagePanel extends JPanel implements MouseListener, MouseMotionListener, MouseWheelListener, OnEventListener {
private PreviewImageFilter mImageFilter = new PreviewImageFilter();
/** Zoom用の画像を作るかどうか */
private float mZoomScale = 1.75f;
private boolean mCreateZoomImage = true;
private PreviewImageFilter mPreviewZoomFilter = new PreviewImageFilter();
private BufferedImage mPreviewZoomImage = null;
private Object mLockZoomImage = new Object();
private boolean mFitZoom = false;
private int mPreviewMargin = 20;
private IImageFileInfo mFileInfo = null;
private int mInfoIndex = 0;
private BufferedImage mOriginalImage = null;
private BufferedImage mDisplayImage = null;
private boolean mIsOutputSizePreview = false;
private Dimension mPreviewSize = new Dimension(600,800);
private Point ptLeftTop = null;
private Point ptRightBottom = null;
private Point ptRotateA = null;
private Point ptRotateB = null;
private boolean mIsRotateVertical = true;
private LineHandleSet guideLineHandle = new LineHandleSet();
private boolean mIsEditMode = false;
private boolean mIsZoomDrag = false;
private Point mZoomPoint = new Point();
private Rectangle mImageArea = new Rectangle();
/** カスタム分割モード */
private boolean mIsCustomSplitMode = false;
private SplitLineSet splitLineHandle = new SplitLineSet();
public ImagePanel(){
SpringLayout layout = new SpringLayout();
setLayout(layout);
addMouseListener(this);
addMouseMotionListener(this);
addMouseWheelListener(this);
addComponentListener(new ComponentListener(){
@Override
public void componentResized(ComponentEvent e) {
onAncestorResized();
updateDisplayImage(true);
}
@Override
public void componentMoved(ComponentEvent e) {
// NOP
}
@Override
public void componentShown(ComponentEvent e) {
// NOP
}
@Override
public void componentHidden(ComponentEvent e) {
// NOP
}
});
}
public void onAncestorResized(){
if(!mIsOutputSizePreview){
mImageFilter.setPreviewSize(getWidth() - mPreviewMargin, getHeight() - mPreviewMargin);
if(mCreateZoomImage){
mPreviewZoomFilter.setPreviewSize((int)(getWidth()*mZoomScale)-mPreviewMargin, (int)(getHeight()*mZoomScale)-mPreviewMargin);
}
System.out.println("width=" + getWidth() + " height=" + getHeight());
}
}
public void finalize(){
finalizeThread();
}
private EventObserver mEventSender = null;
public void setEventObserver(EventObserver observer){
mEventSender = observer;
}
public void setImageFilterParam(ImageFilterParamSet params){
mImageFilter.setImageFilterParam(params);
if(mCreateZoomImage){
mPreviewZoomFilter.setImageFilterParam(params);
}
mIsEditMode = params.get(ImageFilterParamSet.FILTER_INDEX_BASIC).isPreview();
//updateDisplayImage();
}
//@Override
public void paint(Graphics g){
super.paint(g); //JPanelのクリア
int w = getWidth();
int h = getHeight();
g.setColor(Color.LIGHT_GRAY);
g.fillRect(0, 0, w, h);
if (mDisplayImage != null){
int imageW = mDisplayImage.getWidth();
int imageH = mDisplayImage.getHeight();
int x = (w - imageW)/2;
int y = (h - imageH)/2;
mImageArea.setBounds(x, y, imageW, imageH);
if(mIsCustomSplitMode){
g.drawImage(mDisplayImage, x, y, this);
splitLineHandle.paint(g, w, h, imageW, imageH);
}
else{
if(!mIsEditMode && !mIsZoomDrag){
if(mFitZoom){
int width = w - mPreviewMargin;
int height = h - mPreviewMargin;
int ow = mDisplayImage.getWidth();
int oh = mDisplayImage.getHeight();
if(width > ow && height > oh){
int scale = 1;
do{
scale *= 2;
}while(!(ow * scale >= width && oh * scale >= height));
Dimension size = ResizeFilter.getResizeDimension(ow*scale, oh*scale, width, height);
int zw = size.width;
int zh = size.height;
int zx = width / 2 - zw / 2 + mPreviewMargin / 2;
int zy = height / 2 - zh / 2 + mPreviewMargin / 2;
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);//RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.drawImage(mDisplayImage, zx, zy, zx+zw, zy+zh, 0, 0, ow, oh, null);
mImageArea.setBounds(zx, zy, zw, zh);
}
else{
g.drawImage(mDisplayImage, x, y, this);
}
}
else{
g.drawImage(mDisplayImage, x, y, this);
}
}
else if(!mIsEditMode && mIsZoomDrag){
if(mCreateZoomImage){
createZoomImage();
}
synchronized(mLockZoomImage){
float scale = mZoomScale;
int mx = mZoomPoint.x;
int my = mZoomPoint.y;
int cx = w / 2;
int cy = h / 2;
mx += (mx - cx);
my += (my - cy);
int dw = (int)(imageW);
int dh = (int)(imageH);
int zw = (int)(dw * scale);
int zh = (int)(dh * scale);
int pw = mPreviewZoomImage.getWidth();
int ph = mPreviewZoomImage.getHeight();
if(mPreviewZoomImage != null){
if(zw < pw || zh < ph){
zw = pw;
zh = ph;
}
}
float panX = (float)(mx - cx) / (float)dw;
float panY = (float)(my - cy) / (float)dh;
int zx = mx - (int)(zw * (0.5f + panX));
int zy = my - (int)(zh * (0.5f + panY));
// if(zx > 0){
// g.fillRect(0, 0, zx, h);
// }
// if(zx+zw < w){
// g.fillRect(zx+zw, 0, w, h);
// }
// if(zy > 0){
// g.fillRect(zx, 0, zw, zy);
// }
// if(zy+zh < h){
// g.fillRect(zx, zy+zh, zw, h);
// }
if(mPreviewZoomImage != null){
if(zw != pw || zh != ph){
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);//RenderingHints.VALUE_INTERPOLATION_BICUBIC);
}
g.drawImage(mPreviewZoomImage, zx, zy, zx+zw, zy+zh, 0, 0, pw, ph, null);
}else{
if(zw != imageW || zh != imageH){
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);//RenderingHints.VALUE_INTERPOLATION_BICUBIC);
}
g.drawImage(mDisplayImage, zx, zy, zx+zw, zy+zh, 0, 0, imageW, imageH, null);
}
}
}
else{
g.drawImage(mDisplayImage, x, y, this);
}
if(guideLineHandle.isDragHandle()){
}
else if(ptLeftTop != null && ptRightBottom != null){
Rectangle cropRect = new Rectangle(ptLeftTop.x, ptLeftTop.y, (ptRightBottom.x-ptLeftTop.x), (ptRightBottom.y-ptLeftTop.y));
g.setColor(Color.BLACK);
g.drawRect(cropRect.x, cropRect.y, cropRect.width, cropRect.height);
}
if(ptRotateA != null && ptRotateB != null){
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.RED);
g2.drawLine(ptRotateA.x, ptRotateA.y, ptRotateB.x, ptRotateB.y);
//g.setColor(Color.RED);
//g.drawLine(ptRotateA.x, ptRotateA.y, ptRotateB.x, ptRotateB.y);
double angle = radian((double)(ptRotateB.x-ptRotateA.x), (double)(ptRotateB.y-ptRotateA.y));
System.out.println("rad=" + angle);
}
if(mIsEditMode){
//guideLineHandle.setScale((float)mImageFilter.getResizedScaleW(), (float)mImageFilter.getResizedScaleH());
guideLineHandle.paint(g, w, h, imageW, imageH);
}
}
}
else{
mImageArea.setBounds(0,0,0,0);
}
}
private void createZoomImage(){
if(mCreateZoomImage){
if(ImageCache.enable){
if(mPreviewZoomImage == null){
ImageData data = ImageCache.getInstance().getImageData(mInfoIndex);
BufferedImage image = data.getZoomImage(mPreviewZoomFilter);
synchronized(mLockZoomImage){
mPreviewZoomImage = image;
}
}
}else{
if(mPreviewZoomImage == null){
synchronized(mImageFilter){
BufferedImage filtered = mPreviewZoomFilter.filter(BufferedImageIO.copyBufferedImage(mOriginalImage), mFileInfo.getFilterParam());
synchronized(mLockZoomImage){
mPreviewZoomImage = filtered;
}
}
}
}
}
}
private Rectangle getCropRect(){
Rectangle rect = null;
if (mDisplayImage != null && ptLeftTop != null && ptRightBottom != null){
int w = getWidth();
int h = getHeight();
int imageW = mDisplayImage.getWidth();
int imageH = mDisplayImage.getHeight();
int x = (w - imageW)/2;
int y = (h - imageH)/2;
Rectangle cropRect = new Rectangle(ptLeftTop.x, ptLeftTop.y, (ptRightBottom.x-ptLeftTop.x), (ptRightBottom.y-ptLeftTop.y));
Rectangle imageRect = new Rectangle(x, y, imageW, imageH);
Rectangle intersect = imageRect.intersection(cropRect);
if(intersect.width > 0 && intersect.height > 0){
rect = intersect;
ptLeftTop.x = rect.x;
ptLeftTop.y = rect.y;
ptRightBottom.x = rect.x + rect.width;
ptRightBottom.y = rect.y + rect.height;
}
}
return rect;
}
@SuppressWarnings("unused")
private float getScale(){
if(mOriginalImage != null && mDisplayImage != null){
//SplitModeの場合は表示イメージの幅がオリジナルの半分になってしまうため、ここでは高さを元にスケールを計算する
// 今後SplitModeに縦分割等が入る場合は修正が必要
float oh = (float)mOriginalImage.getHeight();
float dh = (float)mDisplayImage.getHeight();
return dh/oh;
}
return 1.0f;
}
private float getScaleX(float ow){
if(mDisplayImage != null){
float dw = (float)mDisplayImage.getWidth();
return dw/ow;
}
return 1.0f;
}
private float getScaleY(float oh){
if(mDisplayImage != null){
float dh = (float)mDisplayImage.getHeight();
return dh/oh;
}
return 1.0f;
}
public void setImage(BufferedImage image, IImageFileInfo info, int rowIndex){
AddSpaceFilter filter = new AddSpaceFilter();
mOriginalImage = filter.filter(image, info.getFilterParam());
mFileInfo = info;
mInfoIndex = rowIndex;
ptLeftTop = null;
ptRightBottom = null;
if(mOriginalImage != null){
updateDisplayImage(false);
}
}
public void updateDisplayImage(boolean async){
ptLeftTop = null;
ptRightBottom = null;
if(mOriginalImage == null){
return;
}
if(async){
startRenderImage();
}
else{
updateDisplayImageInternal();
}
}
// private QueueingThread mZoomThread = null;
public Object mLockRender = new Object();
public void updateDisplayImageInternal(){
if(mImageFilter != null){
try {
if(ImageCache.enable){
ImageData data = ImageCache.getInstance().getImageData(mInfoIndex);
mDisplayImage = data.getDisplayImage(mImageFilter, true);
mPreviewZoomImage = null;
if(mCreateZoomImage && !mIsEditMode){
new Thread(){
@Override
public void run(){
createZoomImage();
}
}.start();
}
}
else{
synchronized(mImageFilter){
BufferedImage filtered = mImageFilter.filter(BufferedImageIO.copyBufferedImage(mOriginalImage), mFileInfo.getFilterParam());
mDisplayImage = filtered;
}
mPreviewZoomImage = null;
if(mCreateZoomImage && !mIsEditMode){
new Thread(){
@Override
public void run(){
createZoomImage();
}
}.start();
}
}
}catch(OutOfMemoryError e){
mEventSender.setProgressMessage(e.getMessage());
e.printStackTrace();
}
}
repaint();
//System.out.println("updateDisplayInternal()");
}
private LinkedList<Integer> mQueue = new LinkedList<Integer>();
private Object mThreadLock = new Object();
private Thread mThread = null;
private boolean mThreadFinish = false;
public void startRenderImage(){
if(mThread == null){
mThread = new Thread(){
@Override
public void run(){
while(!mThreadFinish){
synchronized(mThreadLock){
if(mQueue.isEmpty()){
try {
mThreadLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(!mQueue.isEmpty()){
mQueue.pop();
}
}
try {
boolean loop = true;
while(loop && !mThreadFinish){
updateDisplayImageInternal();
synchronized(mQueue){
loop = !mQueue.isEmpty();
if(loop){
mQueue.pop();
}
}
}
}catch(Exception e){
mEventSender.setProgressMessage(e.getMessage());
}catch(OutOfMemoryError e){
mEventSender.setProgressMessage(e.getMessage());
}
}
mThread = null;
}
};
mThread.setPriority(Thread.MAX_PRIORITY);
mThread.start();
}
synchronized(mThreadLock){
while(mQueue.size() > 0){
mQueue.remove();
}
mQueue.push(0);
mThreadLock.notify();
}
}
private void finalizeThread(){
if(mThread != null){
mThreadFinish = true;
synchronized(mThreadLock){
mThreadLock.notify();
}
mThread = null;
}
}
public void updateTableInfo(){
mEventSender.sendEvent(EventObserver.EventTarget_Table, EventObserver.EventType_UpdateFileInfo, mInfoIndex);
mEventSender.setModified();
}
@Override
public void mouseClicked(MouseEvent e) {
if(javax.swing.SwingUtilities.isLeftMouseButton(e) && e.getClickCount() >= 2){
int width = this.getWidth();
int x = e.getX();
if(x > width - 100){
mEventSender.sendEvent(EventObserver.EventTarget_Setting, EventObserver.EventType_ShowSettingPanel, 0);
mEventSender.sendEvent(EventObserver.EventTarget_Main, EventObserver.EventType_ShowSettingPanel, 0);
updateDisplayImage(true);
}
}
if(mFileInfo == null){
return;
}
int x = e.getX();
int y = e.getY();
if(mIsCustomSplitMode){
splitLineHandle.mouseClicked(e);
}
if(javax.swing.SwingUtilities.isRightMouseButton(e)){
if(mImageArea.contains(x, y)){
if(mIsCustomSplitMode){
return;
}
mFileInfo.getFilterParam().setRotate(false);
mFileInfo.getFilterParam().setRotateAngle(0.0f);
updateDisplayImage(true);
updateTableInfo();
}
else{
showSettingPopupMenu(x, y);
}
}
else{
if(mIsCustomSplitMode){
return;
}
if(mImageArea.contains(x, y)){
if(!mIsEditMode){
if(e.getClickCount() >= 2){
mEventSender.sendEvent(EventObserver.EventTarget_Main, EventObserver.EventType_BeginFullscreen, mFitZoom ? 1 : 0);
}
}else{
clearCropRect();
}
}
else{
mEventSender.sendEvent(EventObserver.EventTarget_Table, EventObserver.EventType_MoveInfo, 1);
}
}
}
@Override
public void mouseEntered(MouseEvent e) {
if(mIsCustomSplitMode){
splitLineHandle.mouseEntered(e);
}
else{
if(mIsEditMode){
guideLineHandle.mouseEntered(e);
}
}
}
@Override
public void mouseExited(MouseEvent e) {
if(mIsCustomSplitMode){
splitLineHandle.mouseExited(e);
}
else{
if(mIsEditMode){
guideLineHandle.mouseExited(e);
}
}
}
private Point mBasePoint = new Point();
@Override
public void mousePressed(MouseEvent e) {
if(mIsCustomSplitMode){
splitLineHandle.mousePressed(e);
}
else{
int x = e.getX();
int y = e.getY();
if(javax.swing.SwingUtilities.isRightMouseButton(e)){
if(mIsEditMode){
guideLineHandle.mousePressed(e);
if(guideLineHandle.isDragHandle()){
return;
}
}
if(ptRotateA == null){
ptRotateA = new Point(x, y);
ptRotateB = new Point(x, y);
}
}
else{
if(mIsEditMode){
guideLineHandle.mousePressed(e);
if(guideLineHandle.isDragHandle()){
}
else{
ptLeftTop = new Point();
ptRightBottom = new Point();
mBasePoint.setLocation(x, y);
ptLeftTop.setLocation(x, y);
ptRightBottom.setLocation(x, y);
}
}
else{
// Zoom start
if(mImageArea.contains(x, y)){
mIsZoomDrag = true;
mZoomPoint.setLocation(x, y);
repaint();
}
}
}
}
}
public double radian(double x,double y) { /*ベクトルの角度を計算*/
if(mIsRotateVertical){
double s =Math.acos(x/Math.sqrt(x*x+y*y));
s=(s/Math.PI)*180.0;
return -(s-90.0);
}
else{
double s =Math.acos(y/Math.sqrt(x*x+y*y));
s=(s/Math.PI)*180.0;
return (s-90);
}
}
@Override
public void mouseReleased(MouseEvent e) {
if(mFileInfo == null){
return;
}
if(mIsCustomSplitMode){
splitLineHandle.mouseReleased(e);
}
else{
if(javax.swing.SwingUtilities.isRightMouseButton(e)){
if(mIsEditMode){
boolean handle = guideLineHandle.isDragHandle();
guideLineHandle.mouseReleased(e);
if(handle){
return;
}
}
if(ptRotateA != null && ptRotateB != null){
if(!ptRotateA.equals(ptRotateB)){
ImageFilterParam param = mFileInfo.getFilterParam();
param.setRotate(true);
double angle = radian((double)(ptRotateB.x-ptRotateA.x), (double)(ptRotateB.y-ptRotateA.y));
param.setRotateAngle(angle + param.getRotateAngle());
updateDisplayImage(true);
updateTableInfo();
}
ptRotateA = null;
ptRotateB = null;
}
}
else {
if(mIsEditMode){
boolean isDragged = guideLineHandle.isDragHandle();
if(!isDragged){
setCropRect();
}
guideLineHandle.mouseReleased(e);
if(isDragged){
Dimension offset = new Dimension(0, 0);
guideLineHandle.getHandleOffset(offset);
System.out.println("offset=" + offset.toString());
if(!(offset.width == 0 && offset.height == 0)){
/* 回転→移動の場合 */
ImageFilterParam param = mFileInfo.getFilterParam();
param.setTranslate(true);
double scaleW = mImageFilter.getResizedScaleW(); // 最後のResize時のScale値
double scaleH = mImageFilter.getResizedScaleH();
double angle = param.isRotate() ? param.getRotateAngle() : 0.0f;
double radian = Math.toRadians(angle);
AffineTransform af = new AffineTransform();
af.setToRotation(-radian);
double[] srcPoints = new double[]{ (double)offset.width, (double)offset.height };
double[] dstPoints = new double[2];
af.transform(srcPoints, 0, dstPoints, 0, 1);
System.out.println("src=" + srcPoints[0] + "," + srcPoints[1] + " dst=" +dstPoints[0] + "," + dstPoints[1]);
param.setTranslateX(param.getTranslateX() - (int)(dstPoints[0] / scaleW));
param.setTranslateY(param.getTranslateY() - (int)(dstPoints[1] / scaleH));
//param.setTranslateX(param.getTranslateX() - (int)(offset.width / scaleW));
//param.setTranslateY(param.getTranslateY() - (int)(offset.height / scaleH));
updateDisplayImage(true);
updateTableInfo();
return;
/* 移動→回転の場合
ImageFilterParam param = mFileInfo.getFilterParam();
param.setTranslate(true);
double scaleW = mImageFilter.getResizedScaleW(); // 最後のResize時のScale値
double scaleH = mImageFilter.getResizedScaleH();
param.setTranslateX(param.getTranslateX() - (int)(offset.width / scaleW));
param.setTranslateY(param.getTranslateY() - (int)(offset.height / scaleH));
updateDisplayImage();
updateTableInfo();
return;
*/
}
}
}
else{
// Zoom end
mIsZoomDrag = false;
}
}
}
repaint();
}
private void setCropRect(){
Rectangle cropRect = getCropRect();
if(cropRect != null && mFileInfo != null){
//float scale = getScale();
Dimension size = SplitFilter.getSplitSize(mOriginalImage, mFileInfo.getFilterParam());
float scaleX = getScaleX(size.width);
float scaleY = getScaleY(size.height);
Rectangle dispImageRect = getDisplayImageRect();
int left = cropRect.x - dispImageRect.x;
int top = cropRect.y - dispImageRect.y;
int right = (dispImageRect.x + dispImageRect.width) - (cropRect.x + cropRect.width);
int bottom = (dispImageRect.y + dispImageRect.height) - (cropRect.y + cropRect.height);
float orgLeft = (float)left / scaleX;
float orgRight = (float)right / scaleX;
float orgTop = (float)top / scaleY;
float orgBottom = (float)bottom / scaleY;
ImageFilterParam param = mFileInfo.getFilterParam();
param.setFullPageCrop(true);
param.setFullPageCrop((int)orgLeft, (int)orgTop, (int)orgRight, (int)orgBottom);
param.setTextPageCrop(true);
param.setTextPageCrop(0, 0, 0, 0);
param.setPictPageCrop(true);
param.setPictPageCrop(0, 0, 0, 0);
//if(param.getPageType() == FileInfoTable.TYPE_SPLIT_CROP){
updateDisplayImage(true);
//}
}
}
private void clearCropRect(){
ImageFilterParam param = mFileInfo.getFilterParam();
param.setFullPageCrop(false);
param.setFullPageCrop(0, 0, 0, 0);
param.setTextPageCrop(false);
param.setTextPageCrop(0, 0, 0, 0);
param.setPictPageCrop(false);
param.setPictPageCrop(0, 0, 0, 0);
//if(param.getPageType() == FileInfoTable.TYPE_SPLIT_CROP){
updateDisplayImage(true);
}
private Rectangle getDisplayImageRect(){
int w = getWidth();
int h = getHeight();
int imageW = mDisplayImage.getWidth();
int imageH = mDisplayImage.getHeight();
int x = (w - imageW)/2;
int y = (h - imageH)/2;
return new Rectangle(x, y, imageW, imageH);
}
@Override
public void mouseDragged(MouseEvent e) {
if(mIsCustomSplitMode){
splitLineHandle.mouseDragged(e);
repaint();
}
else{
int x = e.getX();
int y = e.getY();
if(javax.swing.SwingUtilities.isRightMouseButton(e)){
if(mIsEditMode){
guideLineHandle.mouseDragged(e);
if(guideLineHandle.isDragHandle()){
repaint();
return;
}
}
if(ptRotateA != null && ptRotateB != null){
ptRotateB.setLocation(x, y);
repaint();
}
}
else{
if(mIsEditMode){
guideLineHandle.mouseDragged(e);
if(guideLineHandle.isDragHandle()){
}
else{
if(x < mBasePoint.x){
ptLeftTop.x = x;
ptRightBottom.x = mBasePoint.x;
}
if(mBasePoint.x < x){
ptRightBottom.x = x;
ptLeftTop.x = mBasePoint.x;
}
if(y < mBasePoint.y){
ptLeftTop.y = y;
ptRightBottom.y = mBasePoint.y;
}
if(mBasePoint.y < y){
ptRightBottom.y = y;
ptLeftTop.y = mBasePoint.y;
}
}
repaint();
}
else{
// Zoom
mZoomPoint.setLocation(x, y);
repaint();
}
}
}
}
@Override
public void mouseMoved(MouseEvent e) {
if(mIsCustomSplitMode){
splitLineHandle.mouseMoved(e);
}
else{
if(mIsEditMode){
guideLineHandle.mouseMoved(e);
}
}
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if(mFileInfo == null){
return;
}
if(!mIsEditMode){
int step = 1;
if(e.getWheelRotation() < 0){
step = -1;
}
mEventSender.sendEvent(EventObserver.EventTarget_Table, EventObserver.EventType_MoveInfo, step);
return;
}
if(mIsCustomSplitMode){
}
else{
int rotation = e.getWheelRotation();
long when = e.getWhen();
System.out.println("rotation=" + rotation + " when=" + when);
ImageFilterParam param = mFileInfo.getFilterParam();
param.setRotate(true);
double angle = 0.1 * rotation;
param.setRotateAngle(angle + param.getRotateAngle());
updateDisplayImage(true);
updateTableInfo();
// ImageFilterParam param = mFileInfo.getFilterParam();
// double angle = 0.5 * rotation;
//
// int x = e.getX();
// int y = e.getY();
// int w = getWidth();
// int h = getHeight();
// AffineTransform af = new AffineTransform();
// af.rotate(-Math.toRadians(angle), w/2, h/2);
//
// double[] srcPoints = new double[]{ (double)x, (double)y };
// double[] dstPoints = new double[2];
// af.transform(srcPoints, 0, dstPoints, 0, 1);
//
// double offsetx = dstPoints[0] - srcPoints[0];
// double offsety = dstPoints[1] - srcPoints[1];
//
// param.setRotate(true);
// param.setRotateAngle(angle + param.getRotateAngle());
// param.setTranslate(true);
// param.setTranslateX(param.getTranslateX() + (int)offsetx);
// param.setTranslateY(param.getTranslateY() + (int)offsety);
// updateDisplayImage();
// updateTableInfo();
}
}
private void showSettingPopupMenu(int x, int y){
JPopupMenu popup = new JPopupMenu();
JMenuItem item1 = new JMenuItem("ガイド位置初期化");
item1.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
guideLineHandle.resetPosition();
repaint();
}
});
String check0 = guideLineHandle.isVisible() ? "●" : " ";
JMenuItem item2 = new JMenuItem(check0 + "ガイド表示");
item2.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
guideLineHandle.setVisible(!guideLineHandle.isVisible());
repaint();
}
});
String check1 = guideLineHandle.isSyncLineHorizontal() ? "●" : " ";
JMenuItem item3 = new JMenuItem(check1 + "上下ガイド同期");
item3.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
guideLineHandle.setSyncLineHorizontal(!guideLineHandle.isSyncLineHorizontal());
repaint();
}
});
String check2 = guideLineHandle.isSyncLineVertical() ? "●" : " ";
JMenuItem item4 = new JMenuItem(check2 + "左右ガイド同期");
item4.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
guideLineHandle.setSyncLineVertical(!guideLineHandle.isSyncLineVertical());
repaint();
}
});
popup.add(item1);
popup.add(item2);
popup.add(item3);
popup.add(item4);
if(mFileInfo != null){
final ImageFilterParam param = mFileInfo.getFilterParam();
if(param.isTranslate() && (param.getTranslateX() != 0 || param.getTranslateY() != 0)){
// 座標移動されていた場合
JMenuItem item5 = new JMenuItem("位置リセット");
item5.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
param.setTranslate(false);
param.setTranslateX(0);
param.setTranslateY(0);
updateDisplayImage(true);
updateTableInfo();
}
});
popup.add(item5);
}
}
JMenuItem item5 = new JMenuItem("傾き補正切り替え");
item5.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
mIsRotateVertical = !mIsRotateVertical;
}
});
popup.add(item5);
String check4 = guideLineHandle.isFixed() ? "●" : " ";
JMenuItem fixMenu1 = new JMenuItem(check4 + "ガイド枠固定");
fixMenu1.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
guideLineHandle.fixPosition(!guideLineHandle.isFixed());
}
});
popup.add(fixMenu1);
JMenu areaMenu = new JMenu("ガイド枠");
JMenuItem areaMenuItem1 = new JMenuItem("本文ページ切り出し領域に設定");
areaMenuItem1.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
float top = guideLineHandle.getTopOffset() + 0.5f;
float bottom = guideLineHandle.getBottomOffset() + 0.5f;
float left = guideLineHandle.getLeftOffset() + 0.5f;
float right = guideLineHandle.getRightOffset() + 0.5f;
if(top < 0){ top = 0; }
if(top > 1.0f){ top = 1.0f; }
if(bottom < 0){ bottom = 0; }
if(bottom > 1.0f){ bottom = 1.0f; }
if(left < 0){ left = 0; }
if(left > 1.0f){ left = 1.0f; }
if(right < 0){ right = 0; }
if(right > 1.0f){ right = 1.0f; }
if(mFileInfo != null && mOriginalImage != null){
Dimension size = SplitFilter.getSplitSize(mOriginalImage, mFileInfo.getFilterParam());
int imageWidth = size.width;
int imageHeight = size.height;
ImageFilterParam param = new ImageFilterParam();
param.setTextPageCrop(true);
param.setTextPageCrop((int)(imageWidth * left), (int)(imageHeight * top), imageWidth - (int)(imageWidth * right), imageHeight - (int)(imageHeight * bottom));
mEventSender.sendEvent(EventObserver.EventTarget_Setting, EventObserver.EventType_UpdateFilterParamOnlyEnable, ImageFilterParamSet.FILTER_INDEX_TEXT, param);
}
}
});
JMenuItem areaMenuItem2 = new JMenuItem("個別ページ切り出し領域に設定");
areaMenuItem2.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
float top = guideLineHandle.getTopOffset() + 0.5f;
float bottom = guideLineHandle.getBottomOffset() + 0.5f;
float left = guideLineHandle.getLeftOffset() + 0.5f;
float right = guideLineHandle.getRightOffset() + 0.5f;
if(top < 0){ top = 0; }
if(top > 1.0f){ top = 1.0f; }
if(bottom < 0){ bottom = 0; }
if(bottom > 1.0f){ bottom = 1.0f; }
if(left < 0){ left = 0; }
if(left > 1.0f){ left = 1.0f; }
if(right < 0){ right = 0; }
if(right > 1.0f){ right = 1.0f; }
System.out.println("t=" + top + " l=" + left + " b=" + bottom + " r=" + right);
if(mFileInfo != null && mOriginalImage != null){
Dimension size = SplitFilter.getSplitSize(mOriginalImage, mFileInfo.getFilterParam());
int imageWidth = size.width;
int imageHeight = size.height;
//float scaleX = getScaleX(size.width);
//float scaleY = getScaleY(size.height);
int l = (int)(imageWidth * left);
int t = (int)(imageHeight * top);
int r = (int)(imageWidth - (int)(imageWidth * right));
int b = (int)(imageHeight - (int)(imageHeight * bottom));
ImageFilterParam param = mFileInfo.getFilterParam();
param.setFullPageCrop(true);
param.setFullPageCrop(l, t, r, b);
updateDisplayImage(true);
}
}
});
JMenuItem areaMenuItem3 = new JMenuItem("縦横比変更(上下固定3:4)");
areaMenuItem3.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
guideLineHandle.setAspect(600, 800, mImageArea.width, mImageArea.height, true);
repaint();
}
});
areaMenu.add(areaMenuItem1);
areaMenu.add(areaMenuItem2);
areaMenu.add(areaMenuItem3);
popup.add(areaMenu);
// boolean isSplited = false;
if(mFileInfo instanceof ImageFileInfoSplitWrapper){
JMenuItem splitMenu = new JMenuItem("分割解除");
splitMenu.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
ImageFileInfoSplitWrapper wrapInfo = (ImageFileInfoSplitWrapper)mFileInfo;
wrapInfo = wrapInfo.getFirstSplitInfo();
wrapInfo.getFilterParam().setSplitType(SplitFilter.TYPE_NONE);
mEventSender.sendEvent(EventObserver.EventTarget_Table, EventObserver.EventType_RenewalList, 0);
//updateDisplayImage();
}
});
popup.add(splitMenu);
}
// else{
// JMenuItem splitMenu1 = new JMenuItem("カスタム分割モード(3x3)");
// splitMenu1.addActionListener(new ActionListener(){
// @Override
// public void actionPerformed(ActionEvent arg0) {
// if(mIsCustomSplitMode){
// float[] v = splitLineHandle.getV();
// float[] h = splitLineHandle.getH();
// mFileInfo.getFilterParam().setSplitType(SplitFilter.TYPE_CUSTOM, v, h);
// mEventSender.sendEvent(EventObserver.EventTarget_Table, EventObserver.EventType_RenewalList, 0);
// }
// mIsCustomSplitMode = !mIsCustomSplitMode;
// splitLineHandle.setSplitColRow(3, 3);
// repaint();
// }
// });
// JMenuItem splitMenu2 = new JMenuItem("カスタム分割モード(3x4)");
// splitMenu2.addActionListener(new ActionListener(){
// @Override
// public void actionPerformed(ActionEvent arg0) {
// if(mIsCustomSplitMode){
// float[] v = splitLineHandle.getV();
// float[] h = splitLineHandle.getH();
// mFileInfo.getFilterParam().setSplitType(SplitFilter.TYPE_CUSTOM, v, h);
// mEventSender.sendEvent(EventObserver.EventTarget_Table, EventObserver.EventType_RenewalList, 0);
// }
// mIsCustomSplitMode = !mIsCustomSplitMode;
// splitLineHandle.setSplitColRow(3, 4);
// repaint();
// }
// });
//
// popup.add(splitMenu1);
// popup.add(splitMenu2);
// }
JMenuItem item9 = new JMenuItem("単一ページ変換");
item9.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
showOutputFolderDialog();
}
});
popup.add(item9);
popup.show(this, x, y);
}
private void showOutputFolderDialog(){
JFileChooser filechooser = new JFileChooser();
filechooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
String desktopFolder = System.getProperty("user.home") + "/Desktop";
File defaultFolder = new File(desktopFolder);//InifileProperty.getInstance().getOutputFolder());
if(defaultFolder.exists() && defaultFolder.isDirectory()){
filechooser.setSelectedFile(defaultFolder);
}
filechooser.setDialogTitle("保存先フォルダ選択");
int selected = filechooser.showOpenDialog(getParent());
if(selected == JFileChooser.APPROVE_OPTION){
File file = filechooser.getSelectedFile();
String path = file.getAbsolutePath();
mEventSender.sendEvent(EventObserver.EventTarget_Main, EventObserver.EventType_BeginConvertOne, mInfoIndex, path);
}
}
public void setOutputSizePreview(boolean enable, int width, int height){
mIsOutputSizePreview = enable;
if(enable){
mPreviewSize.setSize(width, height);
}else{
mPreviewSize.setSize(getWidth(), getHeight());
}
mImageFilter.setPreviewSize(mPreviewSize.width - mPreviewMargin, mPreviewSize.height - mPreviewMargin);
}
public void setSimpleZoom(boolean simpleZoom){
//mCreateZoomImage = !simpleZoom;
mFitZoom = simpleZoom;
if(mCreateZoomImage){
mPreviewZoomImage = null;
}
}
@Override
public void onEventReceived(int type, int arg1, int arg2, Object obj) {
switch(type){
case EventObserver.EventType_PreviewSize:
Dimension size = (Dimension)obj;
setOutputSizePreview(arg1 == 1, size.width, size.height);
break;
default:
break;
}
}
}