package com.github.sarxos.l2fprod.sheet.editor;
import java.awt.BorderLayout;
import java.awt.ContainerOrderFocusTraversalPolicy;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JSpinner.DefaultEditor;
import javax.swing.JTextField;
import javax.swing.UIManager;
import com.github.sarxos.l2fprod.sheet.ResizeLayout;
import com.l2fprod.common.beans.editor.AbstractPropertyEditor;
/**
* Editor containing spinner inside. It can be used for various models such as
* date, numbers, chars, etc.
*
* @author Bartosz Firyn (SarXos)
*/
public class SpinnerEditor extends AbstractPropertyEditor {
protected class ContainerPanel extends JPanel implements KeyListener, FocusListener {
private static final long serialVersionUID = 11429722436474288L;
private JComponent component = null;
private boolean active = false;
public ContainerPanel(JComponent component) {
this.component = component;
addKeyListener(this);
addFocusListener(this);
setBorder(null);
setFocusCycleRoot(true);
setFocusTraversalPolicy(new ContainerOrderFocusTraversalPolicy());
add(component);
if (getUI().getClass().getSimpleName().equals("SubstancePanelUI")) {
setLayout(new ResizeLayout());
} else {
setLayout(new BorderLayout());
}
}
@Override
public void keyTyped(KeyEvent e) {
component.dispatchEvent(e);
}
@Override
public void keyPressed(KeyEvent e) {
component.dispatchEvent(e);
}
@Override
public void keyReleased(KeyEvent e) {
component.dispatchEvent(e);
}
@Override
public void focusGained(FocusEvent e) {
if (!active) {
// received focus for the first time, mark component as active
active = true;
component.transferFocusDownCycle();
} else {
// received focus back from cycle, finish edit
SpinnerEditor.this.firePropertyChange(oldValue, spinner.getValue());
}
}
@Override
public void focusLost(FocusEvent e) {
}
}
private Object oldValue;
protected JSpinner spinner = null;
protected JPanel panel = null;
public SpinnerEditor() {
spinner = new JSpinner() {
private static final long serialVersionUID = 6795837270307274730L;
@Override
public void setValue(Object value) {
super.setValue(value);
}
@Override
public void paint(Graphics g) {
super.paint(g);
}
};
spinner.setBorder(BorderFactory.createEmptyBorder());
spinner.setOpaque(false);
spinner.setFont(UIManager.getFont("Table.font"));
spinner.setLocation(new Point(-1, -1));
editor = new ContainerPanel(spinner);
formatSpinner();
}
protected void formatSpinner() {
DefaultEditor ne = (DefaultEditor) spinner.getEditor();
ne.setFont(UIManager.getFont("Table.font"));
ne.getTextField().setHorizontalAlignment(JTextField.LEFT);
ne.getTextField().setAlignmentX(JTextField.LEFT_ALIGNMENT);
ne.getTextField().setFont(UIManager.getFont("Table.font"));
}
@Override
public Object getValue() {
Object value = spinner.getValue();
if (value instanceof ObjectWrapper) {
return ((ObjectWrapper) value).value;
} else {
return value;
}
}
@Override
public void setValue(Object value) {
if (value != spinner.getValue()) {
spinner.setValue(value);
}
}
public static final class ObjectWrapper {
private Object value;
public ObjectWrapper(Object value, Object visualValue) {
this.value = value;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (value == o || (value != null && value.equals(o))) {
return true;
}
return false;
}
@Override
public int hashCode() {
return value == null ? 0 : value.hashCode();
}
}
}