package com.aratana.ui.fields;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.ActionEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import com.aratana.MVCUnit;
import com.aratana.annotation.BeforeAction;
import com.aratana.ui.FormBuilder;
import com.aratana.ui.InputChangeListener;
import com.aratana.ui.ValueChangeListener;
import com.aratana.ui.ViewField;
import com.aratana.util.IconManager;
import com.sun.awt.AWTUtilities;
@SuppressWarnings({ "serial", "restriction" })
public class LookupField<T, F> extends JPanel implements ViewField<T> {
private final BasicField<F> field;
private final Class<T> fieldClass;
private final LookupSelector<T> selector;
private T value;
private final List<ValueChangeListener<T>> listeners = new ArrayList<ValueChangeListener<T>>();
private final List<InputChangeListener> input = new ArrayList<InputChangeListener>();
public LookupField(final Class<T> fieldClass, final BasicField<F> field, LookupSelector<T> selector) {
super(new BorderLayout(0, 0));
this.fieldClass = fieldClass;
this.selector = selector;
this.field = field;
this.field.addInputChangeListener(new InputChangeListener() {
@Override
public void inputChange(ViewField<?> field) {
fireInputChanged();
}
});
add(this.field);
this.field.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(final KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_DELETE:
case KeyEvent.VK_BACK_SPACE:
setValue(null);
break;
}
}
});
this.field.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
if (getValue() == null && !LookupField.this.field.getText().isEmpty()) {
select();
}
}
});
(this.field).addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
if (e.getClickCount() == 2) {
select();
}
}
});
add(new JButton(new AbstractAction(null, IconManager.getIcon("/icons/16x16/search.png")) {
@Override
public void actionPerformed(final ActionEvent e) {
select();
}
}) {
{
setMargin(new Insets(0, 0, 0, 0));
final int prefered = ((Component) LookupField.this.field).getPreferredSize().height;
setPreferredSize(new Dimension(prefered, prefered));
}
}, BorderLayout.EAST);
}
@Override
public synchronized void addFocusListener(final FocusListener l) {
field.addFocusListener(l);
}
private void select() {
new LookupDialog();
// field.requestFocusInWindow();
}
@Override
public void addValueChangeListener(final ValueChangeListener<T> listener) {
listeners.add(listener);
}
@Override
public void addInputChangeListener(InputChangeListener listener) {
input.add(listener);
}
public boolean removeInputChangeListener(final InputChangeListener listener) {
return input.remove(listener);
}
public void removeAllInputChangeListener() {
input.clear();
}
protected void fireInputChanged() {
for (InputChangeListener l : input) {
l.inputChange(this);
}
}
@Override
public Class<T> getFieldClass() {
return fieldClass;
}
@Override
public int getMax() {
return field.getMax();
}
@Override
public int getMin() {
return field.getMin();
}
@Override
public T getValue() {
return value;
}
@Override
public boolean isObrigatory() {
return field.isObrigatory();
}
@Override
public T setValue(final T value) {
boolean update = this.value != value;
if (update) {
for (final ValueChangeListener<T> l : listeners) {
if (l.validateValue(value)) {
update = false;
break;
}
}
if (update) {
T oldValue = this.value;
this.value = value;
field.setText(value == null ? null : value.toString());
this.field.setEditable(value == null);
for (final ValueChangeListener<T> l : listeners) {
l.valueChanged(value, oldValue);
}
}
}
return this.value;
}
@Override
public T getStringValue(String str) throws Exception {
// TODO Auto-generated method stub
return null;
}
@Override
public String getValueString(T value) {
// TODO Auto-generated method stub
return null;
}
public final class LookupDialog extends JDialog {
JComponent panel;
private LookupDialog() {
super(SwingUtilities.getWindowAncestor(LookupField.this), "");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.NONE);
AWTUtilities.setWindowOpaque(this, false);
getRootPane().putClientProperty("apple.awt.draggableWindowBackground", false);
setContentPane(new JPanel(null) {
{
enableEvents(MouseEvent.MOUSE_EVENT_MASK);
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(BLUE);
Point fieldPoint = field.getLocationOnScreen();
SwingUtilities.convertPointFromScreen(fieldPoint, this);
Point panelPoint = panel.getLocation();
Polygon p = new Polygon();
// top
p.addPoint(fieldPoint.x, fieldPoint.y);
p.addPoint(fieldPoint.x + field.getWidth(), fieldPoint.y);
p.addPoint(panelPoint.x + panel.getWidth(), panelPoint.y);
p.addPoint(panelPoint.x, panelPoint.y);
g.fillPolygon(p);
// bottom
p = new Polygon();
p.addPoint(fieldPoint.x, fieldPoint.y + field.getHeight());
p.addPoint(fieldPoint.x + field.getWidth(), fieldPoint.y + field.getHeight());
p.addPoint(panelPoint.x + panel.getWidth(), panelPoint.y + panel.getHeight());
p.addPoint(panelPoint.x, panelPoint.y + panel.getHeight());
g.fillPolygon(p);
// left
p = new Polygon();
p.addPoint(fieldPoint.x, fieldPoint.y);
p.addPoint(fieldPoint.x, fieldPoint.y + field.getHeight());
p.addPoint(panelPoint.x, panelPoint.y + panel.getHeight());
p.addPoint(panelPoint.x, panelPoint.y);
g.fillPolygon(p);
// right
p = new Polygon();
p.addPoint(fieldPoint.x + field.getWidth(), fieldPoint.y);
p.addPoint(fieldPoint.x + field.getWidth(), fieldPoint.y + field.getHeight());
p.addPoint(panelPoint.x + panel.getWidth(), panelPoint.y + panel.getHeight());
p.addPoint(panelPoint.x + panel.getWidth(), panelPoint.y);
g.fillPolygon(p);
super.paintComponent(g);
}
@Override
protected void processMouseEvent(MouseEvent e) {
super.processMouseEvent(e);
if (e.getID() == MouseEvent.MOUSE_PRESSED) {
cancel();
}
}
});
FormBuilder formBuilder = new FormBuilder();
formBuilder.label("Filtro :").alloc(2).width(200).name("filter").string("%%").name("search").action("Pesquisar").down()//
.alloc(4).span(true).size(250, 300).name("table").table(getFieldClass(), selector.columnsSpecs()).down()//
.label("").span().label("").action("Selecionar").name("cancel").action("Cancelar").down();
add(panel = formBuilder.getPanel());
TableField<T> table = formBuilder.getTable("table");
for (T t : selector.lookup(null, null)) {
table.addRow(t);
}
addWindowFocusListener(new WindowAdapter() {
@Override
public void windowDeactivated(WindowEvent e) {
cancel();
}
@Override
public void windowLostFocus(WindowEvent e) {
cancel();
}
});
// pack();
// setLocationRelativeTo(LookupField.this);
// setLocation(getX() + (getWidth()/2), getY() + (getHeight()/2));
setBounds(GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds());
panel.setBounds(getWidth() - 400, getHeight() - 500, 310, 400);
MVCUnit.create("LookupDialog", this);
setVisible(true);
}
private final Color BLUE = new Color(0.3f, 0.3f, 0.9f, 0.4f);
@BeforeAction
public void cancel() {
dispose();
}
}
}
|