/* Copyright (C) 2005-2011 Fabio Riccardi */
package com.lightcrafts.ui.rotate;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import static com.lightcrafts.ui.rotate.Locale.LOCALE;
import com.lightcrafts.ui.LightZoneSkin;
// A validating text field that synchronizes with the RotorControl sliders.
class RotorTextField
extends JTextField implements DocumentListener, MouseWheelListener
{
private final static NumberFormat Format = new DecimalFormat("+0.00;-0.00");
private final static String TooltipText = LOCALE.get("RotorTextToolTip");
private RotorControl control;
private boolean isUpdating; // Suppress the DocumentListener
RotorTextField(RotorControl control) {
this.control = control;
setHorizontalAlignment(RIGHT);
setToolTipText(TooltipText);
setText("+100.00");
Dimension size = getPreferredSize();
setMinimumSize(size);
setPreferredSize(size);
setMaximumSize(size);
update();
setInputVerifier(new AngleVerifier());
Document doc = getDocument();
doc.addDocumentListener(this);
addMouseWheelListener(this);
addFocusListener(
new FocusAdapter() {
public void focusGained(FocusEvent event) {
selectAll();
}
}
);
}
void update() {
double angle = control.getDegrees();
String text = Format.format(angle);
isUpdating = true;
setText(text);
isUpdating = false;
}
public void changedUpdate(DocumentEvent event) {
handleDocumentChange();
}
public void insertUpdate(DocumentEvent event) {
handleDocumentChange();
}
public void removeUpdate(DocumentEvent event) {
handleDocumentChange();
}
// When the text changes, give verification feedback and maybe update
// the control:
private void handleDocumentChange() {
if (isUpdating) {
return;
}
InputVerifier verifier = getInputVerifier();
boolean verified = verifier.verify(this);
if (! verified) {
setForeground(Color.red);
}
else {
String text = getText();
try {
setForeground(LightZoneSkin.Colors.ToolPanesForeground);
double value = Format.parse(text).doubleValue();
control.setDegrees(value);
}
catch (ParseException e) {
System.err.println("Unparsable verified text: " + text);
setForeground(Color.red);
}
}
}
public void mouseWheelMoved(MouseWheelEvent e) {
InputVerifier verifier = getInputVerifier();
boolean verified = verifier.verify(this);
if (verified) {
int count = e.getWheelRotation();
String text = getText();
try {
double value = Format.parse(text).doubleValue();
value -= 0.1 * count;
value = Math.round(10 * value) / 10d;
control.setDegrees(value);
update();
selectAll();
}
catch (ParseException e1) {
System.err.println("Unparsable verified text: " + text);
// do nothing, let the wheel have no effect
}
}
}
// An InputVerifier that checks the text is a number:
private class AngleVerifier extends InputVerifier {
public boolean verify(JComponent input) {
String text = getText();
try {
Format.parse(text);
return true;
}
catch (ParseException e) {
return false;
}
}
}
}