blob: 4701f2908e906edac4b376ca114a65e536cdf470 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.netbeans.modules.print.util;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComboBox;
import javax.swing.KeyStroke;
import javax.swing.text.JTextComponent;
import static org.netbeans.modules.print.util.UI.*;
/**
* @author Vladimir Yaroslavskiy
* @version 2006.03.13
*/
public final class Percent extends JComboBox implements ActionListener {
public interface Listener {
double getCustomValue(int index);
void valueChanged(double value, int index);
void invalidValue(String value);
}
public Percent(Listener listener, double initValue, int[] values, final int defaultCustomIndex, String[] customs, String toolTip) {
//out("<New> Percent: " + initValue);
for (int value : values) {
addItem(value + PERCENT);
}
if (customs != null) {
for (String custom : customs) {
addItem(custom);
}
}
setToolTipText(toolTip);
setEditable(true);
myCustoms = customs;
myListener = listener;
JTextComponent editor = (JTextComponent) getEditor().getEditorComponent();
InputMap inputMap = editor.getInputMap();
ActionMap actionMap = editor.getActionMap();
inputMap.put(KeyStroke.getKeyStroke('+'), INCREASE);
inputMap.put(KeyStroke.getKeyStroke('='), INCREASE);
inputMap.put(KeyStroke.getKeyStroke('-'), DECREASE);
inputMap.put(KeyStroke.getKeyStroke('_'), DECREASE);
inputMap.put(KeyStroke.getKeyStroke('/'), NORMAL);
inputMap.put(KeyStroke.getKeyStroke('*'), CUSTOM);
actionMap.put(INCREASE, new AbstractAction() {
public void actionPerformed(ActionEvent event) {
increaseValue();
}
});
actionMap.put(DECREASE, new AbstractAction() {
public void actionPerformed(ActionEvent event) {
decreaseValue();
}
});
actionMap.put(NORMAL, new AbstractAction() {
public void actionPerformed(ActionEvent event) {
normalValue();
}
});
actionMap.put(CUSTOM, new AbstractAction() {
public void actionPerformed(ActionEvent event) {
customValue(defaultCustomIndex);
}
});
addActionListener(this);
setValue(initValue);
selectValue();
}
private void selectValue() {
String text = getEditorItem();
for (int i = 0; i < getItemCount(); i++) {
if (text.equals(getItemAt(i))) {
setSelectedIndex(i);
}
}
}
public boolean isCustomValue() {
return getCustomIndex(getEditorItem()) != -1;
}
public String getEditorItem() {
return getEditor().getItem().toString();
}
public void actionPerformed(ActionEvent event) {
//out();
String value = getEditorItem();
//out("Action: " + value);
int k = getCustomIndex(value);
if (k != -1) {
//out(" it is custom");
valueChanged(getCustomValue(k), k);
return;
}
double percent = parsePercent(value);
if (isValid(percent)) {
//out(" it's valid value");
int i = getCustomIndex(percent);
if (i != -1) {
setValue(percent, i);
}
else {
valueChanged(percent, i);
}
}
else {
//out(" it's invalid value");
myListener.invalidValue(value);
//out(" restore.");
setText(myCurrentText);
}
}
private int getCustomIndex(String value) {
if (myCustoms == null) {
return -1;
}
for (int i = 0; i < myCustoms.length; i++) {
if (myCustoms[i].equals(value)) {
return i;
}
}
return -1;
}
public double getValue() {
return myCurrentValue;
}
public void increaseValue() {
if (myCurrentValue < THRESHOLD) {
setValue(myCurrentValue + SUBTRAHEND);
}
else {
setValue(myCurrentValue * FACTOR);
}
}
public void decreaseValue() {
if (myCurrentValue > THRESHOLD) {
setValue(myCurrentValue / FACTOR);
}
else {
setValue(myCurrentValue - SUBTRAHEND);
}
}
public void normalValue() {
setValue(1.0);
}
public void customValue(int index) {
setValue(getCustomValue(index), index);
}
public void setValue(double value) {
//out("SET value: " + value);
setValue(value, getCustomIndex(value));
}
private void setValue(double value, int index) {
//out(" set value: " + value + " " + index);
String text = valueChanged(value, index);
if (text != null) {
setText(text);
}
}
private String valueChanged(double value, int index) {
boolean isCustomValue = index != -1;
//out(" value changed: " + value + " " + isCustomValue);
if ( !isCustomValue && !isValid(value)) {
//out(" it's not valid value");
return null;
}
myCurrentValue = value;
//out("myCurrentValue: " + myCurrentValue);
if (isCustomValue && myCustoms != null) {
myCurrentText = myCustoms[index];
}
else {
myCurrentText = getPercent(value);
}
//out("myCurrentText: " + myCurrentText);
myListener.valueChanged(value, index);
return myCurrentText;
}
private void setText(String text) {
getEditor().setItem(text);
}
private int getCustomIndex(double value) {
if (myCustoms == null) {
return -1;
}
//out("-- " + getPercent(value) + " " + getPercent(getCustomValue()));
for (int i = 0; i < myCustoms.length; i++) {
if (getPercent(value).equals(getPercent(getCustomValue(i)))) {
return i;
}
}
return -1;
}
private boolean isValid(double value) {
//out("is valid: " + value);
return MIN_VALUE <= value && value <= MAX_VALUE;
}
private double getCustomValue(int index) {
return myListener.getCustomValue(index);
}
private double parsePercent(String text) {
String value = text;
if (value.endsWith(PERCENT)) {
value = value.substring(0, value.length() - 1);
}
return getInt(value.trim()) / YUZ;
}
private String getPercent(double value) {
return (int) Math.round(YUZ * value) + PERCENT;
}
public static double getZoomFactor(double zoom, double defaultValue) {
if (0 < zoom && zoom <= MAX_VALUE) {
return zoom;
}
return defaultValue;
}
public static int getZoomWidth(double zoom, int defaultValue) {
if (BOUND_1 <= zoom && zoom < BOUND_2) {
return round(zoom - BOUND_1);
}
return defaultValue;
}
public static int getZoomHeight(double zoom, int defaultValue) {
if (BOUND_2 <= zoom) {
return round(zoom - BOUND_2);
}
return defaultValue;
}
public static boolean isZoomFactor(double zoom) {
return zoom < BOUND_1;
}
public static boolean isZoomWidth(double zoom) {
return BOUND_1 <= zoom && zoom < BOUND_2;
}
public static boolean isZoomHeight(double zoom) {
return BOUND_2 <= zoom;
}
public static boolean isZoomPage(double zoom) {
return zoom == 0.0;
}
public static double createZoomWidth(double zoom) {
return BOUND_1 + zoom;
}
public static double createZoomHeight(double zoom) {
return BOUND_2 + zoom;
}
private Listener myListener;
private String[] myCustoms;
private String myCurrentText;
private double myCurrentValue;
private static final int BOUND_1 = 1000;
private static final int BOUND_2 = 2000;
private static final double THRESHOLD = 0.2;
private static final double SUBTRAHEND = 0.01;
private static final double MIN_VALUE = 0.01;
private static final double MAX_VALUE = 15.0;
private static final String CUSTOM = "custom"; // NOI18N
private static final String NORMAL = "normal"; // NOI18N
private static final String INCREASE = "increase"; // NOI18N
private static final String DECREASE = "decrease"; // NOI18N
private static final double YUZ = 100.0;
private static final String PERCENT = "%"; // NOI18N
public static final double FACTOR = 1.09;
}