package jp.crwdev.app.gui;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SpringLayout;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import jp.crwdev.app.imagefilter.ImageFilterParam;
import jp.crwdev.app.setting.ImageFilterParamSet;
@SuppressWarnings("serial")
public class SettingTabPanel extends JPanel {
private int mFilterIndex = ImageFilterParamSet.FILTER_INDEX_BASIC;
// Label
// public JLabel labelGamma = new JLabel("ガンマ補正値");
public JLabel labelContrast = new JLabel("Co:0");
public JLabel labelBrightness = new JLabel("Br:0");
// CheckBox
public JCheckBox checkEnable = new JCheckBox("無変換");
public JCheckBox checkBlur = new JCheckBox("ぼかし");
public JCheckBox checkSharpness = new JCheckBox("シャープネス");
public JCheckBox checkContrast = new JCheckBox("コントラスト");
public JCheckBox checkGamma = new JCheckBox("ガンマ補正");
public JCheckBox checkGrayscale = new JCheckBox("グレースケール");
public JCheckBox checkCrop = new JCheckBox("切り抜き");
public JCheckBox checkUnification = new JCheckBox("本文ページサイズ統一");
public JCheckBox checkAutoCrop = new JCheckBox("自動余白除去");
// Spinner
public JSpinner spinSharpness = new JSpinner();
public JSpinner spinGamma = new JSpinner();
public JSpinner spinCropLeft = new JSpinner();
public JSpinner spinCropRight = new JSpinner();
public JSpinner spinCropTop = new JSpinner();
public JSpinner spinCropBottom = new JSpinner();
public JSpinner spinCropThreshold = new JSpinner();
// Slider
public JSlider sliderContrast = new JSlider();
public JSlider sliderBrightness = new JSlider();
private SettingPanel mParent = null;
public SettingTabPanel(SettingPanel parent, int filterIndex){
super();
mParent = parent;
mFilterIndex = filterIndex;
initialize();
}
public String getTabTitle(){
switch(mFilterIndex){
case ImageFilterParamSet.FILTER_INDEX_COLOR:
return "カラー";
case ImageFilterParamSet.FILTER_INDEX_PICT:
return "挿絵";
case ImageFilterParamSet.FILTER_INDEX_TEXT:
return "本文";
case ImageFilterParamSet.FILTER_INDEX_BASIC:
default:
return "未設定";
}
}
private void initialize(){
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
//setPreferredSize(new Dimension(300,400));
JPanel checkPanel = new JPanel();
SpringLayout layout1 = new SpringLayout();
checkPanel.setLayout(layout1);
// 無変換
checkPanel.add(checkEnable);
checkEnable.setEnabled(false); //TODO: 未実装なのでDisable
layout1.putConstraint(SpringLayout.WEST, checkEnable, 0, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, checkEnable, 0, SpringLayout.NORTH, checkPanel);
// ぼかし
checkPanel.add(checkBlur);
layout1.putConstraint(SpringLayout.WEST, checkBlur, 0, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, checkBlur, 0, SpringLayout.SOUTH, checkEnable);
// シャープネス
checkPanel.add(checkSharpness);
layout1.putConstraint(SpringLayout.WEST, checkSharpness, 0, SpringLayout.EAST, checkBlur);
layout1.putConstraint(SpringLayout.NORTH, checkSharpness, 0, SpringLayout.NORTH, checkBlur);
checkPanel.add(spinSharpness);
layout1.putConstraint(SpringLayout.WEST, spinSharpness, 0, SpringLayout.EAST, checkSharpness);
layout1.putConstraint(SpringLayout.BASELINE, spinSharpness, 0, SpringLayout.BASELINE, checkSharpness);
// グレースケール
checkPanel.add(checkGrayscale);
layout1.putConstraint(SpringLayout.WEST, checkGrayscale, 0, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, checkGrayscale, 0, SpringLayout.SOUTH, checkBlur);
//
Component current = checkGrayscale;
if(mFilterIndex == ImageFilterParamSet.FILTER_INDEX_TEXT){
checkPanel.add(checkUnification);
layout1.putConstraint(SpringLayout.WEST, checkUnification, 0, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, checkUnification, 0, SpringLayout.SOUTH, checkGrayscale);
current = checkUnification;
}
// ガンマ
checkPanel.add(checkGamma);
layout1.putConstraint(SpringLayout.WEST, checkGamma, 0, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, checkGamma, 0, SpringLayout.SOUTH, current);
checkPanel.add(spinGamma);
layout1.putConstraint(SpringLayout.WEST, spinGamma, 0, SpringLayout.EAST, checkGamma);
layout1.putConstraint(SpringLayout.BASELINE, spinGamma, 0, SpringLayout.BASELINE, checkGamma);
// コントラスト
checkPanel.add(checkContrast);
layout1.putConstraint(SpringLayout.WEST, checkContrast, 0, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, checkContrast, 0, SpringLayout.SOUTH, checkGamma);
checkPanel.add(sliderContrast);
layout1.putConstraint(SpringLayout.WEST, sliderContrast, 0, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.EAST, sliderContrast, 180, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, sliderContrast, 0, SpringLayout.SOUTH, checkContrast);
checkPanel.add(labelContrast);
layout1.putConstraint(SpringLayout.WEST, labelContrast, 6, SpringLayout.EAST, sliderContrast);
layout1.putConstraint(SpringLayout.NORTH, labelContrast, 0, SpringLayout.NORTH, sliderContrast);
checkPanel.add(sliderBrightness);
layout1.putConstraint(SpringLayout.WEST, sliderBrightness, 0, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.EAST, sliderBrightness, 180, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, sliderBrightness, 4, SpringLayout.SOUTH, sliderContrast);
checkPanel.add(labelBrightness);
layout1.putConstraint(SpringLayout.WEST, labelBrightness, 6, SpringLayout.EAST, sliderBrightness);
layout1.putConstraint(SpringLayout.NORTH, labelBrightness, 0, SpringLayout.NORTH, sliderBrightness);
// 切り抜き
checkPanel.add(checkCrop);
checkPanel.add(spinCropLeft);
checkPanel.add(spinCropTop);
checkPanel.add(spinCropRight);
checkPanel.add(spinCropBottom);
checkPanel.add(checkAutoCrop);
checkPanel.add(spinCropThreshold);
layout1.putConstraint(SpringLayout.WEST, checkCrop, 0, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, checkCrop, 0, SpringLayout.SOUTH, labelBrightness);
layout1.putConstraint(SpringLayout.WEST, spinCropLeft, 10, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, spinCropLeft, 12, SpringLayout.SOUTH, checkCrop);
layout1.putConstraint(SpringLayout.WEST, spinCropTop, 63, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, spinCropTop, 0, SpringLayout.SOUTH, checkCrop);
layout1.putConstraint(SpringLayout.WEST, spinCropBottom, 63, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, spinCropBottom, 2, SpringLayout.SOUTH, spinCropTop);
layout1.putConstraint(SpringLayout.WEST, spinCropRight, 116, SpringLayout.WEST, checkPanel);
layout1.putConstraint(SpringLayout.NORTH, spinCropRight, 0, SpringLayout.NORTH, spinCropLeft);
layout1.putConstraint(SpringLayout.WEST, checkAutoCrop, 3, SpringLayout.EAST, checkCrop);
layout1.putConstraint(SpringLayout.NORTH, checkAutoCrop, 0, SpringLayout.NORTH, checkCrop);
layout1.putConstraint(SpringLayout.WEST, spinCropThreshold, 5, SpringLayout.EAST, spinCropRight);
layout1.putConstraint(SpringLayout.NORTH, spinCropThreshold, 0, SpringLayout.NORTH, spinCropRight);
add(checkPanel);
spinCropLeft.setPreferredSize(new Dimension(50, 20));
spinCropTop.setPreferredSize(new Dimension(50, 20));
spinCropRight.setPreferredSize(new Dimension(50, 20));
spinCropBottom.setPreferredSize(new Dimension(50, 20));
spinCropLeft.setModel(new SpinnerNumberModel(0, 0, 1000, 1));
spinCropTop.setModel(new SpinnerNumberModel(0, 0, 1000, 1));
spinCropRight.setModel(new SpinnerNumberModel(0, 0, 1000, 1));
spinCropBottom.setModel(new SpinnerNumberModel(0, 0, 1000, 1));
spinCropThreshold.setPreferredSize(new Dimension(50, 20));
spinCropThreshold.setModel(new SpinnerNumberModel(0, 0, 100, 1));
spinCropThreshold.setToolTipText("自動余白除去時の白色判定閾値を指定します。");
spinGamma.setPreferredSize(new Dimension(40, 20));
spinGamma.setModel(new SpinnerNumberModel(1.6f, 0.0f, 30.0f, 0.1f));
mOldSharpLevel = 1;
spinSharpness.setPreferredSize(new Dimension(40, 20));
spinSharpness.setModel(new SpinnerNumberModel(1, 1, 10, 1));
MouseAdapter mouseClickAdapter = new MouseAdapter(){
public void mouseClicked(MouseEvent evt) {
updateSettingValues();
}
};
checkEnable.addMouseListener(mouseClickAdapter);
checkBlur.addMouseListener(mouseClickAdapter);
checkSharpness.addMouseListener(mouseClickAdapter);
checkUnification.addMouseListener(mouseClickAdapter);
checkGrayscale.addMouseListener(mouseClickAdapter);
checkGamma.addMouseListener(mouseClickAdapter);
checkContrast.addMouseListener(mouseClickAdapter);
checkCrop.addMouseListener(mouseClickAdapter);
checkAutoCrop.addMouseListener(mouseClickAdapter);
checkUnification.setToolTipText("本文ページの画像サイズを統一します。");
checkCrop.setToolTipText("画像端から指定されたサイズをカットします。");
checkAutoCrop.setToolTipText("指定されたサイズを元に余白と判定した部分をカットします。上下と左右は連動します。");
spinGamma.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent arg0) {
if(checkGamma.isSelected()){
double gamma = getGammaValue();
if(mOldGamma != gamma){
mOldGamma = gamma;
updateSettingValues();
}
}
}
});
spinSharpness.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent arg0) {
if(checkSharpness.isSelected()){
int sharpLevel = (Integer)spinSharpness.getValue();
if(mOldSharpLevel != sharpLevel){
mOldSharpLevel = sharpLevel;
updateSettingValues();
}
}
}
});
sliderContrast.setMinimum(-255);
sliderContrast.setMaximum(255);
sliderContrast.setValue(0);
sliderBrightness.setMinimum(-255);
sliderBrightness.setMaximum(255);
sliderBrightness.setValue(0);
sliderContrast.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent arg0) {
int contrast = sliderContrast.getValue();
labelContrast.setText("Co:" + contrast);
}
});
sliderBrightness.addChangeListener(new ChangeListener(){
@Override
public void stateChanged(ChangeEvent arg0) {
int brightness = sliderBrightness.getValue();
labelBrightness.setText("Br:" + brightness);
}
});
sliderContrast.addMouseListener(new MouseAdapter(){
@Override
public void mouseReleased(MouseEvent arg0) {
if(checkContrast.isSelected()){
updateSettingValues();
}
}
});
sliderBrightness.addMouseListener(new MouseAdapter(){
@Override
public void mouseReleased(MouseEvent arg0) {
if(checkContrast.isSelected()){
updateSettingValues();
}
}
});
ChangeListener listener = new ChangeListener(){
@Override
public void stateChanged(ChangeEvent e) {
if(checkCrop.isSelected() || checkAutoCrop.isSelected()){
updateSettingValues();
}
}
};
spinCropLeft.addChangeListener(listener);
spinCropRight.addChangeListener(listener);
spinCropTop.addChangeListener(listener);
spinCropBottom.addChangeListener(listener);
spinCropThreshold.addChangeListener(listener);
}
private void updateSettingValues(){
if(mParent != null){
mParent.updateSettingValues();
}
}
public boolean setImageFilterParam(ImageFilterParam param, boolean onlyEnable){
boolean update = false;
if(param == null){
return false;
}
if(onlyEnable){
if(param.isEnable()){
checkEnable.setSelected(param.isEnable());
}
if(param.isContrast()){
checkContrast.setSelected(param.isContrast());
}
if(param.isGamma()){
checkGamma.setSelected(param.isGamma());
}
if(param.isBlur()){
checkBlur.setSelected(param.isBlur());
}
if(param.isSharpness()){
checkSharpness.setSelected(param.isSharpness());
}
if(param.isGrayscale()){
checkGrayscale.setSelected(param.isGrayscale());
}
switch(mFilterIndex){
case ImageFilterParamSet.FILTER_INDEX_COLOR:
if(param.isColorPageCrop()){
checkCrop.setSelected(param.isColorPageCrop());
}
if(param.isColorPageAutoCrop()){
checkAutoCrop.setSelected(param.isColorPageAutoCrop());
}
break;
case ImageFilterParamSet.FILTER_INDEX_PICT:
if(param.isPictPageCrop()){
checkCrop.setSelected(param.isPictPageCrop());
}
if(param.isPictPageAutoCrop()){
checkAutoCrop.setSelected(param.isPictPageAutoCrop());
}
break;
case ImageFilterParamSet.FILTER_INDEX_TEXT:
if(param.isTextPageCrop()){
checkCrop.setSelected(param.isTextPageCrop());
}
if(param.isTextPageAutoCrop()){
checkAutoCrop.setSelected(param.isTextPageAutoCrop());
}
break;
case ImageFilterParamSet.FILTER_INDEX_BASIC:
default:
if(param.isFullPageCrop()){
checkCrop.setSelected(param.isFullPageCrop());
}
if(param.isFullPageAutoCrop()){
checkAutoCrop.setSelected(param.isFullPageAutoCrop());
}
break;
}
if(mFilterIndex == ImageFilterParamSet.FILTER_INDEX_TEXT && param.isUnificationTextPage()){
checkUnification.setSelected(param.isUnificationTextPage());
}
}else{
checkEnable.setSelected(param.isEnable());
checkBlur.setSelected(param.isBlur());
checkSharpness.setSelected(param.isSharpness());
checkContrast.setSelected(param.isContrast());
checkGamma.setSelected(param.isGamma());
checkGrayscale.setSelected(param.isGrayscale());
switch(mFilterIndex){
case ImageFilterParamSet.FILTER_INDEX_COLOR:
checkCrop.setSelected(param.isColorPageCrop());
checkAutoCrop.setSelected(param.isColorPageAutoCrop());
break;
case ImageFilterParamSet.FILTER_INDEX_PICT:
checkCrop.setSelected(param.isPictPageCrop());
checkAutoCrop.setSelected(param.isPictPageAutoCrop());
break;
case ImageFilterParamSet.FILTER_INDEX_TEXT:
checkCrop.setSelected(param.isTextPageCrop());
checkAutoCrop.setSelected(param.isTextPageAutoCrop());
break;
case ImageFilterParamSet.FILTER_INDEX_BASIC:
default:
checkCrop.setSelected(param.isFullPageCrop());
checkAutoCrop.setSelected(param.isFullPageAutoCrop());
break;
}
if(mFilterIndex == ImageFilterParamSet.FILTER_INDEX_TEXT){
checkUnification.setSelected(param.isUnificationTextPage());
}
}
if(param.isBlur()){
}
if(param.isSharpness()){
spinSharpness.setValue((int)param.getSharpnessPixels());
}
if(param.isGamma()){
spinGamma.setValue((float)param.getGamma());
}
if(param.isContrast()){
sliderContrast.setValue(convContrast(param.getContrast()));
sliderBrightness.setValue((int)param.getBrightness());
}
switch(mFilterIndex){
case ImageFilterParamSet.FILTER_INDEX_COLOR:
if(param.isColorPageAutoCrop() || param.isColorPageCrop()){
spinCropLeft.setValue(param.getColorPageCropLeft());
spinCropRight.setValue(param.getColorPageCropRight());
spinCropTop.setValue(param.getColorPageCropTop());
spinCropBottom.setValue(param.getColorPageCropBottom());
spinCropThreshold.setValue(param.getColorPageAutoCropThreshold());
if(checkCrop.isSelected()){
update = true;
}
}
break;
case ImageFilterParamSet.FILTER_INDEX_PICT:
if(param.isPictPageAutoCrop() || param.isPictPageCrop()){
spinCropLeft.setValue(param.getPictPageCropLeft());
spinCropRight.setValue(param.getPictPageCropRight());
spinCropTop.setValue(param.getPictPageCropTop());
spinCropBottom.setValue(param.getPictPageCropBottom());
spinCropThreshold.setValue(param.getPictPageAutoCropThreshold());
if(checkCrop.isSelected()){
update = true;
}
}
break;
case ImageFilterParamSet.FILTER_INDEX_TEXT:
if(param.isTextPageAutoCrop() || param.isTextPageCrop()){
spinCropLeft.setValue(param.getTextPageCropLeft());
spinCropRight.setValue(param.getTextPageCropRight());
spinCropTop.setValue(param.getTextPageCropTop());
spinCropBottom.setValue(param.getTextPageCropBottom());
spinCropThreshold.setValue(param.getTextPageAutoCropThreshold());
if(checkCrop.isSelected()){
update = true;
}
}
break;
case ImageFilterParamSet.FILTER_INDEX_BASIC:
default:
if(param.isFullPageAutoCrop() || param.isFullPageCrop()){
spinCropLeft.setValue(param.getFullPageCropLeft());
spinCropRight.setValue(param.getFullPageCropRight());
spinCropTop.setValue(param.getFullPageCropTop());
spinCropBottom.setValue(param.getFullPageCropBottom());
spinCropThreshold.setValue(param.getFullPageAutoCropThreshold());
if(checkCrop.isSelected()){
update = true;
}
}
break;
}
if(param.isUnificationTextPage()){
update = true;
}
return update;
}
public ImageFilterParam getImageFilterParam(){
boolean isEnable = checkEnable.isSelected();
boolean isBlur = checkBlur.isSelected();
boolean isSharpness = checkSharpness.isSelected();
boolean isContrast = checkContrast.isSelected();
boolean isGamma = checkGamma.isSelected();
boolean isGrayscale = checkGrayscale.isSelected();
boolean isCrop = checkCrop.isSelected();
boolean isAutoCrop = checkAutoCrop.isSelected();
boolean isUnificationTextPage = false;
if(mFilterIndex == ImageFilterParamSet.FILTER_INDEX_TEXT){
isUnificationTextPage = checkUnification.isSelected();
}
// Spinner
int cropLeft = (Integer)spinCropLeft.getValue();
int cropRight = (Integer)spinCropRight.getValue();
int cropTop = (Integer)spinCropTop.getValue();
int cropBottom = (Integer)spinCropBottom.getValue();
int cropThreshold = (Integer)spinCropThreshold.getValue();
double gamma = getGammaValue() / 10;
// Slider
int contrast = sliderContrast.getValue();
int brightness = sliderBrightness.getValue();
ImageFilterParam param = new ImageFilterParam();
param.setEnable(isEnable);
param.setBlur(isBlur);
param.setSharpness(isSharpness);
param.setSharpnessPixels((Integer)spinSharpness.getValue());
param.setContrast(isContrast);
param.setGamma(isGamma);
param.setGrayscale(isGrayscale);
switch(mFilterIndex){
case ImageFilterParamSet.FILTER_INDEX_COLOR:
param.setColorPageAutoCrop(isAutoCrop);
param.setColorPageAutoCropThreshold(cropThreshold);
param.setColorPageCrop(isAutoCrop ? false : isCrop);
param.setColorPageCrop(cropLeft, cropTop, cropRight, cropBottom);
break;
case ImageFilterParamSet.FILTER_INDEX_PICT:
param.setPictPageAutoCrop(isAutoCrop);
param.setPictPageAutoCropThreshold(cropThreshold);
param.setPictPageCrop(isAutoCrop ? false : isCrop);
param.setPictPageCrop(cropLeft, cropTop, cropRight, cropBottom);
break;
case ImageFilterParamSet.FILTER_INDEX_TEXT:
param.setTextPageAutoCrop(isAutoCrop);
param.setTextPageAutoCropThreshold(cropThreshold);
param.setTextPageCrop(isAutoCrop ? false : isCrop);
param.setTextPageCrop(cropLeft, cropTop, cropRight, cropBottom);
break;
case ImageFilterParamSet.FILTER_INDEX_BASIC:
default:
param.setFullPageAutoCrop(isAutoCrop);
param.setFullPageAutoCropThreshold(cropThreshold);
param.setFullPageCrop(isAutoCrop ? false : isCrop);
param.setFullPageCrop(cropLeft, cropTop, cropRight, cropBottom);
break;
}
param.setGamma(gamma);
param.setContrast(convContrast(contrast));
param.setBrightness((float)brightness);
if(mFilterIndex == ImageFilterParamSet.FILTER_INDEX_TEXT){
param.setUnificationTextPage(isUnificationTextPage);
}
return param;
}
public boolean isUnification(){
if(mFilterIndex == ImageFilterParamSet.FILTER_INDEX_TEXT){
return checkUnification.isSelected();
}else{
return false;
}
}
private int mOldSharpLevel = 1;
private double mOldGamma = 1.0f;
private double getGammaValue(){
double gamma = 1.0f;
try {
Object val = spinGamma.getValue();
if(val instanceof Double){
gamma = (Double)val;
}
else if(val instanceof Float){
gamma = (Float)val;
}
else{
gamma = (Integer)val;
}
//gamma = val;
}catch(Exception e){
e.printStackTrace();
}
return Math.round(gamma*10);
}
private int convContrast(float scale){
int value = (int)(255 * scale - 255);
return value;
}
private float convContrast(int scale){
float value = (scale + 255) / 255.0f;
return value;
}
}