forked from Coded/SIPRP
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
677 lines
16 KiB
677 lines
16 KiB
package leaf.ui;
|
|
|
|
import info.clearthought.layout.TableLayout;
|
|
import info.clearthought.layout.TableLayoutConstraints;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Container;
|
|
import java.awt.Dimension;
|
|
import java.awt.GradientPaint;
|
|
import java.awt.Graphics;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.event.FocusEvent;
|
|
import java.awt.event.FocusListener;
|
|
import java.awt.event.MouseEvent;
|
|
import java.awt.event.MouseListener;
|
|
import java.beans.PropertyChangeEvent;
|
|
import java.beans.PropertyChangeListener;
|
|
import java.text.DateFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Map;
|
|
|
|
import javax.swing.BorderFactory;
|
|
import javax.swing.JComponent;
|
|
import javax.swing.JLabel;
|
|
import javax.swing.JPanel;
|
|
import javax.swing.JSeparator;
|
|
import javax.swing.JTextArea;
|
|
import javax.swing.JTextField;
|
|
import javax.swing.SwingUtilities;
|
|
|
|
import leaf.data.OrderedMap;
|
|
|
|
|
|
public class LeafInputField<ObjClass extends Object> extends JPanel implements FocusListener, MouseListener, PropertyChangeListener
|
|
{
|
|
|
|
public static final String PROPERTY_CHANGED_CONSTANT = "LEAF_INPUT_PROPERTY_CHANGED";
|
|
public static final String PROPERTY_CHANGED_CLICK = "LEAF_PROPERTY_CHANGED_CLICK";
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
private static final DateFormat sdf = DateFormat.getDateInstance( DateFormat.SHORT, new Locale( "pt", "PT" ) );
|
|
|
|
private static final int defaultColorDec = 20;
|
|
|
|
private int colorDec = defaultColorDec;
|
|
|
|
public Dimension size = null;
|
|
|
|
private Color hot = null;
|
|
private Color cold = null;
|
|
private Color background = null;
|
|
private Color startColor = null;
|
|
private Color endColor = null;
|
|
private Color highLightColor = new Color( 180, 255, 180 );
|
|
|
|
private Object selectedOption = null;
|
|
|
|
private boolean isError = false;
|
|
|
|
private boolean isEditable = false;
|
|
|
|
private boolean isClickable = false;
|
|
|
|
private boolean highLighted = false;
|
|
|
|
private boolean collapseOptions = true;
|
|
|
|
private ObjClass object = null;
|
|
|
|
private GradientPaint outerContour = null;
|
|
private GradientPaint outerReversedContour = null;
|
|
private GradientPaint innerContour = null;
|
|
private GradientPaint innerReversedContour = null;
|
|
private GradientPaint gradient = null;
|
|
private TableLayout layout = null;
|
|
|
|
private JComponent thiz = null;
|
|
|
|
private List<JComponent> theeze = null;
|
|
|
|
public LeafInputField()
|
|
{
|
|
super();
|
|
setOpaque( false );
|
|
setBorder( BorderFactory.createEmptyBorder( 3, 10, 3, 10 ) );
|
|
setBackground( Color.WHITE );
|
|
hot = getBackground();
|
|
cold = new Color( hot.getRed() > colorDec ? hot.getRed() - colorDec : 0, hot.getGreen() > colorDec ? hot.getGreen() - colorDec : 0, hot.getBlue() > colorDec ? hot.getBlue() - colorDec : 0, hot.getAlpha() );
|
|
background = cold;
|
|
setObject( null );
|
|
}
|
|
|
|
public boolean isCollapseOptions()
|
|
{
|
|
return collapseOptions;
|
|
}
|
|
|
|
public void setCollapseOptions( boolean collapse )
|
|
{
|
|
collapseOptions = collapse;
|
|
}
|
|
|
|
public void setText( String text )
|
|
{
|
|
try
|
|
{
|
|
setObject( (ObjClass) text );
|
|
} catch( ClassCastException ex )
|
|
{
|
|
ex.printStackTrace();
|
|
}
|
|
}
|
|
|
|
private String getStringFromUser()
|
|
{
|
|
LeafTextDialog textDialog = new LeafTextDialog( getParentWindow(), this, (String) object, true );
|
|
return textDialog.getText();
|
|
}
|
|
|
|
private Object getOptionFromUser()
|
|
{
|
|
if( object instanceof Map )
|
|
{
|
|
if(((Map) object).size() > 0)
|
|
{
|
|
LeafOptionDialog<Object> optionDialog = new LeafOptionDialog<Object>( getParentWindow(), (Map) object, null );
|
|
return optionDialog.getOption();
|
|
}
|
|
}
|
|
else if( object instanceof OrderedMap )
|
|
{
|
|
if(((OrderedMap) object).rows() > 0)
|
|
{
|
|
LeafOptionDialog<Object> optionDialog = new LeafOptionDialog<Object>( getParentWindow(), (OrderedMap<Object>) object, null, null, null, null );
|
|
return optionDialog.getOption();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private Date getDateFromUser()
|
|
{
|
|
LeafCalendarDialog calendarDialog = new LeafCalendarDialog( getParentWindow(), this );
|
|
return calendarDialog.getDate();
|
|
}
|
|
|
|
private LeafWindow getParentWindow()
|
|
{
|
|
LeafWindow result = null;
|
|
for( Container parent = this.getParent(); parent != null; parent = parent.getParent() )
|
|
{
|
|
if( parent instanceof LeafWindow )
|
|
{
|
|
result = (LeafWindow) parent;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
protected void paintComponent( Graphics g )
|
|
{
|
|
Graphics2D g2d = (Graphics2D) g;
|
|
int width = getWidth();
|
|
int height = getHeight();
|
|
setColors( width, height );
|
|
|
|
g2d.setPaint( outerReversedContour );
|
|
g2d.fillRect( 15, 0, width / 4, height );
|
|
g2d.setPaint( outerContour );
|
|
g2d.fillRect( width / 4, 0, width, height );
|
|
g2d.setPaint( innerReversedContour );
|
|
g2d.fillRect( 15, 0, width / 4, height - 1 );
|
|
g2d.setPaint( innerContour );
|
|
g2d.fillRect( width / 4, 0, width, height - 1 );
|
|
g2d.setPaint( gradient );
|
|
g2d.fillRoundRect( 0, 2, width, height - 5, 15, 15 );
|
|
super.paintComponent( g );
|
|
}
|
|
|
|
private void setColors( int width, int height )
|
|
{
|
|
startColor = getGradientStartColor();
|
|
endColor = getGradientEndColor( startColor );
|
|
outerContour = new GradientPaint( width / 4, 0, Color.GRAY, width, 0, this.getParent().getBackground() );
|
|
outerReversedContour = new GradientPaint( 15, 0, this.getParent().getBackground(), width / 4, 0, Color.GRAY );
|
|
innerContour = new GradientPaint( width / 4, 0, Color.LIGHT_GRAY, width, 0, this.getParent().getBackground() );
|
|
innerReversedContour = new GradientPaint( 15, 0, this.getParent().getBackground(), width / 4, 0, Color.LIGHT_GRAY );
|
|
gradient = new GradientPaint( 0, 0, startColor, width, height, endColor );
|
|
}
|
|
|
|
private Color getGradientStartColor()
|
|
{
|
|
Color result = background;
|
|
/*
|
|
* int red = result.getRed(), green = result.getGreen(), blue =
|
|
* result.getBlue(), alpha = result.getAlpha(); if( isError() ) { result =
|
|
* new Color( red, green > colorDec ? (green - colorDec) : 0, (blue >
|
|
* colorDec) ? (blue - colorDec) : 0, alpha ); } else if( isEditable() ) {
|
|
* result = new Color( red > colorDec ? (red - colorDec) : 0, green,
|
|
* blue > colorDec ? (blue - colorDec) : 0, alpha ); }
|
|
*/
|
|
return result;
|
|
}
|
|
|
|
private Color getGradientEndColor( Color startColor )
|
|
{
|
|
return getParent() != null ? getParent().getBackground() : startColor;
|
|
}
|
|
|
|
/**
|
|
* Sets the component to an error state appearance
|
|
*
|
|
* @param error
|
|
*/
|
|
public void setError( boolean error )
|
|
{
|
|
isError = error;
|
|
repaint();
|
|
}
|
|
|
|
public boolean isError()
|
|
{
|
|
return isError;
|
|
}
|
|
|
|
public boolean getSelected()
|
|
{
|
|
return highLighted;
|
|
}
|
|
|
|
public void setSelected( boolean selected )
|
|
{
|
|
highLighted = selected;
|
|
background = selected ? highLightColor : cold;
|
|
repaint();
|
|
}
|
|
|
|
public void setEditable( boolean editable )
|
|
{
|
|
isEditable = editable;
|
|
if( !editable )
|
|
{
|
|
setMouseOver( false );
|
|
removeBold();
|
|
}
|
|
repaint();
|
|
}
|
|
|
|
private void removeBold()
|
|
{
|
|
|
|
}
|
|
|
|
public boolean isEditable()
|
|
{
|
|
return isEditable;
|
|
}
|
|
|
|
public void setClickable( boolean clickable )
|
|
{
|
|
isClickable = clickable;
|
|
if( !clickable )
|
|
{
|
|
setMouseOver( false );
|
|
}
|
|
repaint();
|
|
}
|
|
|
|
public boolean isClickable()
|
|
{
|
|
return isClickable;
|
|
}
|
|
|
|
private void setupCollapsedPanel()
|
|
{
|
|
List<Object> values = ((OrderedMap) object).getValues( selectedOption );
|
|
theeze = new ArrayList<JComponent>();
|
|
if( values != null )
|
|
{
|
|
double[] rows = new double[] {
|
|
TableLayout.MINIMUM
|
|
};
|
|
double[] cols = new double[values.size() > 0 ? (values.size() * 2 - 1) : 0];
|
|
for( int i = 0; i < cols.length; ++i )
|
|
{
|
|
cols[i] = (i % 2 == 0) ? TableLayout.FILL : TableLayout.MINIMUM;
|
|
}
|
|
TableLayout layout = new TableLayout( cols, rows );
|
|
layout.setHGap( 5 );
|
|
thiz.setLayout( layout );
|
|
for( int i = 0, a = 0; i < cols.length; ++i )
|
|
{
|
|
JComponent comp = null;
|
|
if( i % 2 == 0 )
|
|
{
|
|
Object value = values.get( a++ );
|
|
comp = new JLabel( value == null ? " " : value.toString() );
|
|
theeze.add( comp );
|
|
}
|
|
else
|
|
{
|
|
comp = new JSeparator( JSeparator.VERTICAL );
|
|
}
|
|
thiz.add( comp, new TableLayoutConstraints( i, 0 ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
private void setupUncollapsedPanel()
|
|
{
|
|
theeze = new ArrayList<JComponent>();
|
|
OrderedMap<Object> map = (OrderedMap<Object>) object;
|
|
double[] rows = new double[map.rows() > 0 ? (map.rows() * 2 - 1) : 0];
|
|
double[] cols = new double[map.columns() > 0 ? (map.columns() * 2 - 1) : 0];
|
|
for( int i = 0; i < rows.length; ++i )
|
|
{
|
|
rows[i] = (i % 2 == 0) ? TableLayout.MINIMUM : TableLayout.MINIMUM;
|
|
}
|
|
for( int i = 0; i < cols.length; ++i )
|
|
{
|
|
cols[i] = (i % 2 == 0) ? TableLayout.FILL : TableLayout.MINIMUM;
|
|
}
|
|
TableLayout layout = new TableLayout( cols, rows );
|
|
layout.setHGap( 5 );
|
|
thiz.setLayout( layout );
|
|
|
|
for( int i = 0, a = 0; i < rows.length; ++i )
|
|
{
|
|
if( i % 2 == 0 )
|
|
{
|
|
List<Object> values = map.getRow( a++ );
|
|
for( int j = 0, b = 0; j < cols.length; ++j )
|
|
{
|
|
JComponent comp = null;
|
|
if( j % 2 == 0 )
|
|
{
|
|
Object value = values.get( b++ );
|
|
|
|
LeafInputField<Object> leaf;
|
|
if( value instanceof LeafInputField )
|
|
{
|
|
leaf = (LeafInputField<Object>) value;
|
|
}
|
|
else
|
|
{
|
|
leaf = new LeafInputField<Object>();
|
|
leaf.setObject( value );
|
|
if( j > 1 )
|
|
{
|
|
leaf.setEditable( isEditable );
|
|
}
|
|
}
|
|
|
|
comp = leaf;
|
|
theeze.add( comp );
|
|
}
|
|
else
|
|
{
|
|
JSeparator sep = new JSeparator( JSeparator.VERTICAL );
|
|
sep.setForeground( cold );
|
|
comp = sep;
|
|
}
|
|
thiz.add( comp, new TableLayoutConstraints( j, i ) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
JSeparator sep = new JSeparator();
|
|
sep.setForeground( cold );
|
|
thiz.add( sep, new TableLayoutConstraints( 0, i, cols.length - 1, i ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
private void setSelectedObject( Object key )
|
|
{
|
|
selectedOption = key;
|
|
if( object != null && thiz != null /*&& selectedOption != null */)
|
|
{
|
|
if( object instanceof Map )
|
|
{
|
|
Object value = null;
|
|
value = ((Map) object).get( selectedOption );
|
|
if( thiz instanceof JTextArea )
|
|
{
|
|
((JTextArea) thiz).setText( value == null ? " " : value.toString() );
|
|
}
|
|
else if( thiz instanceof JTextField )
|
|
{
|
|
((JTextField) thiz).setText( value == null ? " " : value.toString() );
|
|
}
|
|
else if( thiz instanceof JLabel )
|
|
{
|
|
((JLabel) thiz).setText( value == null ? " " : value.toString() );
|
|
}
|
|
}
|
|
else if( object instanceof OrderedMap )
|
|
{
|
|
if( thiz instanceof JPanel && collapseOptions )
|
|
{
|
|
setupCollapsedPanel();
|
|
}
|
|
else if( thiz instanceof JPanel && !collapseOptions )
|
|
{
|
|
setupUncollapsedPanel();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public Object getSelectedObject()
|
|
{
|
|
return selectedOption;
|
|
}
|
|
|
|
public void setObject( ObjClass object, Object selected )
|
|
{
|
|
this.selectedOption = selected;
|
|
setObject( object );
|
|
}
|
|
|
|
public void setObject( ObjClass object )
|
|
{
|
|
this.object = object;
|
|
if( object != null )
|
|
{
|
|
if( object instanceof Date )
|
|
{
|
|
Date date = (Date) object;
|
|
thiz = new JTextArea( date.getTime() == 0 ? "" : sdf.format( object ) );
|
|
}
|
|
else if( object instanceof Map )
|
|
{
|
|
thiz = new JTextArea( " " );
|
|
setSelectedObject( selectedOption );
|
|
}
|
|
else if( object instanceof OrderedMap && collapseOptions )
|
|
{
|
|
thiz = new JPanel();
|
|
setSelectedObject( selectedOption );
|
|
}
|
|
else if( object instanceof OrderedMap && !collapseOptions )
|
|
{
|
|
thiz = new JPanel();
|
|
setSelectedObject( selectedOption );
|
|
}
|
|
else if( object instanceof LeafInputField )
|
|
{
|
|
setObject( (ObjClass) ((LeafInputField) object).getObject(), ((LeafInputField) object).getSelectedObject() );
|
|
}
|
|
else if( object instanceof String )
|
|
{
|
|
JTextArea textArea = new JTextArea();
|
|
textArea.setEditable( false );
|
|
textArea.setText( object == null ? "" : object.toString() );
|
|
thiz = textArea;
|
|
}
|
|
else
|
|
{
|
|
String toString = object.toString();
|
|
if( "".equals( toString ) )
|
|
{
|
|
toString = " ";
|
|
}
|
|
thiz = new JTextArea( toString );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
thiz = new JLabel( " " );
|
|
}
|
|
reListen();
|
|
reLayout();
|
|
}
|
|
|
|
public ObjClass getObject()
|
|
{
|
|
return this.object;
|
|
}
|
|
|
|
private void reListen()
|
|
{
|
|
removeListeners();
|
|
if( theeze != null && !collapseOptions && !theeze.isEmpty() )
|
|
{
|
|
for( JComponent current : theeze )
|
|
{
|
|
if( current instanceof LeafInputField )
|
|
{
|
|
current.addFocusListener( (LeafInputField) current );
|
|
current.addMouseListener( (LeafInputField) current );
|
|
current.addPropertyChangeListener( PROPERTY_CHANGED_CONSTANT, this );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
thiz.addFocusListener( this );
|
|
thiz.addMouseListener( this );
|
|
}
|
|
}
|
|
|
|
private void removeListeners()
|
|
{
|
|
removeListerensFrom( thiz );
|
|
if( theeze != null )
|
|
{
|
|
for( JComponent comp : theeze )
|
|
{
|
|
removeListerensFrom( comp );
|
|
}
|
|
}
|
|
}
|
|
|
|
private void removeListerensFrom( JComponent comp )
|
|
{
|
|
if( comp != null )
|
|
{
|
|
FocusListener[] allFocus = thiz.getFocusListeners();
|
|
if( allFocus != null )
|
|
{
|
|
for( FocusListener focusListener : allFocus )
|
|
{
|
|
comp.removeFocusListener( focusListener );
|
|
}
|
|
}
|
|
MouseListener[] allMouse = thiz.getMouseListeners();
|
|
if( allMouse != null )
|
|
{
|
|
for( MouseListener mouseListener : allMouse )
|
|
{
|
|
comp.removeMouseListener( mouseListener );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void reLayout()
|
|
{
|
|
if( thiz != null )
|
|
{
|
|
SwingUtilities.invokeLater( new Runnable()
|
|
{
|
|
@Override
|
|
public void run()
|
|
{
|
|
if( layout == null )
|
|
{
|
|
layout = new TableLayout( new double[] {
|
|
TableLayout.FILL
|
|
}, new double[] {
|
|
TableLayout.FILL
|
|
} );
|
|
LeafInputField.this.setLayout( layout );
|
|
}
|
|
else
|
|
{
|
|
removeAll();
|
|
}
|
|
LeafInputField.this.add( thiz, new TableLayoutConstraints( 0, 0 ) );
|
|
revalidate();
|
|
repaint();
|
|
}
|
|
} );
|
|
size = thiz.getPreferredSize();
|
|
thiz.setOpaque( false );
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void focusLost( FocusEvent e )
|
|
{
|
|
repaint();
|
|
}
|
|
|
|
@Override
|
|
public void focusGained( FocusEvent e )
|
|
{
|
|
repaint();
|
|
}
|
|
|
|
@Override
|
|
public void mouseReleased( MouseEvent e )
|
|
{
|
|
}
|
|
|
|
@Override
|
|
public void mousePressed( MouseEvent e )
|
|
{
|
|
Object old = null;
|
|
if( object != null && isEditable )
|
|
{
|
|
if( object instanceof Date )
|
|
{
|
|
old = object;
|
|
ObjClass newDate = (ObjClass) getDateFromUser();
|
|
if( newDate != null )
|
|
{
|
|
setObject( newDate );
|
|
firePropertyChange( PROPERTY_CHANGED_CONSTANT, old, object );
|
|
}
|
|
}
|
|
else if( object instanceof Map && collapseOptions )
|
|
{
|
|
old = selectedOption;
|
|
ObjClass out = (ObjClass) getOptionFromUser();
|
|
setObject( object, out );
|
|
firePropertyChange( PROPERTY_CHANGED_CONSTANT, old, selectedOption );
|
|
}
|
|
else if( object instanceof OrderedMap && collapseOptions )
|
|
{
|
|
old = selectedOption;
|
|
ObjClass out = (ObjClass) getOptionFromUser();
|
|
setObject( object, out );
|
|
firePropertyChange( PROPERTY_CHANGED_CONSTANT, old, object );
|
|
}
|
|
else if( object instanceof OrderedMap && !collapseOptions )
|
|
{
|
|
// old = selectedOption;
|
|
// ObjClass out = (ObjClass) getOptionFromUser();
|
|
// setObject( object, out );
|
|
// firePropertyChange( PROPERTY_CHANGED_CONSTANT, old, object );
|
|
}
|
|
else if( object instanceof String )
|
|
{
|
|
old = object;
|
|
setObject( (ObjClass) getStringFromUser() );
|
|
firePropertyChange( PROPERTY_CHANGED_CONSTANT, old, object );
|
|
}
|
|
}
|
|
if( isClickable )
|
|
{
|
|
firePropertyChange( PROPERTY_CHANGED_CLICK, false, true );
|
|
}
|
|
// setObject( object, selectedOption );
|
|
}
|
|
|
|
@Override
|
|
public void mouseExited( MouseEvent e )
|
|
{
|
|
setMouseOver( false );
|
|
repaint();
|
|
}
|
|
|
|
@Override
|
|
public void mouseEntered( MouseEvent e )
|
|
{
|
|
setMouseOver( true );
|
|
repaint();
|
|
}
|
|
|
|
@Override
|
|
public void mouseClicked( MouseEvent e )
|
|
{
|
|
}
|
|
|
|
private void setMouseOver( boolean mouseOver )
|
|
{
|
|
if( mouseOver )
|
|
{
|
|
background = (!highLighted && (isEditable || isClickable)) ? hot : background;
|
|
}
|
|
else
|
|
{
|
|
background = (!highLighted && (isEditable || isClickable)) ? cold : background;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void propertyChange( PropertyChangeEvent evt )
|
|
{
|
|
firePropertyChange( PROPERTY_CHANGED_CONSTANT, evt.getOldValue(), evt.getNewValue() );
|
|
}
|
|
} |