use of com.codename1.ui.validation.Constraint in project CodenameOne by codenameone.
the class BorderLayout method addLayoutComponent.
/**
* {@inheritDoc}
*/
public void addLayoutComponent(Object name, Component comp, Container c) {
// helper check for a common mistake...
if (name == null) {
throw new IllegalArgumentException("Cannot add component to BorderLayout Container without constraint parameter");
}
// allows us to work with Component constraints too which makes some code simpler
if (name instanceof Integer) {
switch(((Integer) name).intValue()) {
case Component.TOP:
name = NORTH;
break;
case Component.BOTTOM:
name = SOUTH;
break;
case Component.LEFT:
name = WEST;
break;
case Component.RIGHT:
name = EAST;
break;
case Component.CENTER:
name = CENTER;
break;
default:
throw new IllegalArgumentException("BorderLayout Container expects one of the constraints BorderLayout.NORTH/SOUTH/EAST/WEST/CENTER");
}
}
Component previous = null;
/* Assign the component to one of the known regions of the layout.
*/
if (CENTER.equals(name)) {
previous = portraitCenter;
portraitCenter = comp;
} else if (NORTH.equals(name)) {
previous = portraitNorth;
portraitNorth = comp;
} else if (SOUTH.equals(name)) {
previous = portraitSouth;
portraitSouth = comp;
} else if (EAST.equals(name)) {
previous = portraitEast;
portraitEast = comp;
} else if (WEST.equals(name)) {
previous = portraitWest;
portraitWest = comp;
} else if (OVERLAY.equals(name)) {
previous = overlay;
overlay = comp;
} else {
throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
}
if (previous != null && previous != comp) {
c.removeComponent(previous);
}
}
use of com.codename1.ui.validation.Constraint in project CodenameOne by codenameone.
the class Container method wrapInLayeredPane.
/**
* An atomic operation that wraps the current component in a Container with
* a layered layout. This prevents us from having to initialize and deinitialize
* all of the components in a sub-tree because we want to re-root it. In particular
* Form.getLayeredPane() re-roots the entire content pane the first time it is
* called on a form. If the form contains native peers there is a flicker which
* is quite annoying. Providing a way to do this atomically results in a better
* user experience.
* @return The Container that is the new parent of this component.
*/
Container wrapInLayeredPane() {
final Container oldParent = getParent();
final Container newParent = new Container(new LayeredLayout());
final Layout parentLayout = oldParent != null && oldParent.layout != null ? oldParent.layout : null;
final Object constraint = parentLayout != null ? parentLayout.getComponentConstraint(this) : null;
newParent.setParent(oldParent);
newParent.components.add(this);
final Runnable r = new Runnable() {
public void run() {
if (parentLayout != null) {
parentLayout.removeLayoutComponent(Container.this);
parentLayout.addLayoutComponent(constraint, newParent, oldParent);
}
newParent.initComponentImpl();
if (oldParent != null) {
int cmpIndex = -1;
for (int i = 0; i < oldParent.getComponentCount(); i++) {
Component c = oldParent.getComponentAt(i);
if (c.equals(Container.this)) {
cmpIndex = i;
break;
}
}
// int cmpIndex = oldParent.getComponentIndex(Container.this); <--- WTF... this always returns -1!!
if (cmpIndex == -1) {
throw new RuntimeException("WTF we have parent but no index!!!!");
}
oldParent.components.set(cmpIndex, newParent);
}
Container.this.setParent(newParent);
newParent.revalidate();
}
};
AnimationManager a = getAnimationManager();
if (a != null && a.isAnimating()) {
a.addAnimation(new ComponentAnimation() {
@Override
public boolean isInProgress() {
return false;
}
@Override
protected void updateState() {
r.run();
}
});
return newParent;
} else {
r.run();
return newParent;
}
}
use of com.codename1.ui.validation.Constraint in project CodenameOne by codenameone.
the class UIFragmentSample method testUIFragment.
private void testUIFragment() {
Form f = new Form("Test Fragments", BoxLayout.y());
TextArea ta = new TextArea();
ta.setMaxSize(5000);
String[] examples = new String[] { "<borderAbs><$button1 constraint='center'/><xng constraint='south'><$button2/><$button3/><$button4/></xng></borderAbs>", "{centerAbs:$button1, south:{xng:[$button2, $button3, $button4]}}", "{cs:$button1, south:{xng:[$button2, $button3, $button4]}}", "{ca:$button1, south:{xng:[$button2, $button3, $button4]}}", "{centerScale:$button1, south:{xng:[$button2, $button3, $button4]}}", "{ctb:$button1, south:{xng:[$button2, $button3, $button4]}}", "{centerTotalBelow:$button1, south:{xng:[$button2, $button3, $button4]}}", "{s:$button1, c:{xng:[$button2, $button3, $button4]}}", "{s:$button1, c:{x:[$button2, $button3, $button4]}}", "{s:$button1, c:{y:[$button2, $button3, $button4]}}", "{s:$button1, c:{yBottomLast:[$button2, $button3, $button4]}}", "{s:$button1, c:{ybl:[$button2, $button3, $button4]}}" };
ComboBox cb = new ComboBox(examples);
cb.addActionListener(e -> {
ta.setText(examples[cb.getSelectedIndex()]);
});
ta.setText("<borderAbs><$button1 constraint='center'/><xng constraint='south'><$button2/><$button3/><$button4/></xng></borderAbs>");
Button b = new Button("Compile");
b.addActionListener(e -> {
Form f2 = new Form("Result", new BorderLayout());
f2.setToolbar(new Toolbar());
f2.setTitle("Result");
f2.setBackCommand("Back", null, evt -> {
f.showBack();
});
f2.getToolbar().addCommandToLeftBar("Back", null, evt -> {
f.showBack();
});
Button b1 = new Button("Button 1");
Button b2 = new Button("Button 2");
Button b3 = new Button("Button 3");
Button b4 = new Button("Button 4");
$(b1, b2, b3, b4).selectAllStyles().setBorder(RoundRectBorder.create().cornerRadius(2)).setBgColor(0x003399).setBgTransparency(0xff);
UIFragment frag;
if (ta.getText().charAt(0) == '<') {
frag = UIFragment.parseXML(ta.getText());
} else {
System.out.println("Parsing " + ta.getText());
frag = UIFragment.parseJSON(ta.getText());
}
f2.add(BorderLayout.CENTER, frag.set("button1", b1).set("button2", b2).set("button3", b3).set("button4", b4).getView());
f2.show();
});
ta.setRows(5);
f.addAll(cb, ta, b);
f.show();
}
use of com.codename1.ui.validation.Constraint in project CodenameOne by codenameone.
the class Table method createCell.
/**
* Creates a cell based on the given value
*
* @param value the new value object
* @param row row number, -1 for the header rows
* @param column column number
* @param editable true if the cell is editable
* @return cell component instance
*/
protected Component createCell(Object value, int row, final int column, boolean editable) {
if (row == -1) {
Button header = new Button((String) value, getUIID() + "Header");
header.getAllStyles().setAlignment(titleAlignment);
header.setTextPosition(LEFT);
if (isSortSupported()) {
header.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
Comparator cmp = createColumnSortComparator(column);
if (cmp == null) {
return;
}
if (column == sortedColumn) {
ascending = !ascending;
} else {
sortedColumn = column;
ascending = false;
}
if (model instanceof SortableTableModel) {
model = ((SortableTableModel) model).getUnderlying();
}
setModel(new SortableTableModel(sortedColumn, ascending, model, cmp));
}
});
if (sortedColumn == column) {
if (ascending) {
FontImage.setMaterialIcon(header, FontImage.MATERIAL_ARROW_DROP_UP);
} else {
FontImage.setMaterialIcon(header, FontImage.MATERIAL_ARROW_DROP_DOWN);
}
}
}
return header;
}
int constraint = TextArea.ANY;
Constraint validation = null;
if (isAbstractTableModel()) {
Class type = ((AbstractTableModel) model).getCellType(row, column);
if (type == Boolean.class) {
CheckBox cell = new CheckBox();
cell.setSelected(Util.toBooleanValue(value));
cell.setUIID(getUIID() + "Cell");
cell.setEnabled(editable);
return cell;
}
if (editable && (type == null || type == String.class)) {
String[] multiChoice = ((AbstractTableModel) model).getMultipleChoiceOptions(row, column);
if (multiChoice != null) {
Picker cell = new Picker();
cell.setStrings(multiChoice);
if (value != null) {
cell.setSelectedString((String) value);
}
cell.setUIID(getUIID() + "Cell");
return cell;
}
}
if (editable && type == Date.class) {
Picker cell = new Picker();
cell.setType(Display.PICKER_TYPE_DATE);
if (value != null) {
cell.setDate((Date) value);
}
cell.setUIID(getUIID() + "Cell");
return cell;
}
if (type == Integer.class || type == Long.class || type == Short.class || type == Byte.class) {
constraint = TextArea.NUMERIC;
} else {
if (type == Float.class || type == Double.class) {
constraint = TextArea.DECIMAL;
}
}
if (((AbstractTableModel) model).getValidator() != null) {
validation = ((AbstractTableModel) model).getValidationConstraint(row, column);
}
}
if (editable) {
TextField cell = new TextField(value == null ? "" : "" + value, -1);
cell.setConstraint(constraint);
cell.setLeftAndRightEditingTrigger(false);
cell.setUIID(getUIID() + "Cell");
if (validation != null) {
Validator v = ((AbstractTableModel) model).getValidator();
v.addConstraint(cell, validation);
}
return cell;
}
Label cell = new Label(value == null ? "" : "" + value);
cell.setUIID(getUIID() + "Cell");
cell.getUnselectedStyle().setAlignment(cellAlignment);
cell.getSelectedStyle().setAlignment(cellAlignment);
cell.setFocusable(true);
return cell;
}
use of com.codename1.ui.validation.Constraint in project CodenameOne by codenameone.
the class Validator method addConstraint.
/**
* Places a constraint on the validator, returns this object so constraint
* additions can be chained. Shows validation errors messages even when the
* TextModeLayout is not {@code onTopMode} (it's possible to disable this
* functionality setting to false the theme constant
* {@code showValidationErrorsIfNotOnTopMode}: basically, the error
* message is shown for two second in place of the label on the left of the
* InputComponent (or on right of the InputComponent for RTL languages);
* this solution never breaks the layout, because the error message is
* trimmed to fit the available space. The error message UIID is
* "ErrorLabel" when it's not onTopMode.
*
* @param cmp the component to validate
* @param c the constraint or constraints
* @return this object so we can write code like v.addConstraint(cmp1,
* cons).addConstraint(cmp2, otherConstraint);
*/
public Validator addConstraint(Component cmp, Constraint... c) {
Constraint constraint = null;
if (c.length == 1) {
constraint = c[0];
constraintList.put(cmp, constraint);
} else if (c.length > 1) {
constraint = new GroupConstraint(c);
constraintList.put(cmp, constraint);
}
if (constraint == null) {
throw new IllegalArgumentException("addConstraint needs at least a Constraint, but the Constraint array in empty");
}
bindDataListener(cmp);
boolean isV = isValid();
for (Component btn : submitButtons) {
btn.setEnabled(isV);
}
// Show validation error on iPhone
if (UIManager.getInstance().isThemeConstant("showValidationErrorsIfNotOnTopMode", true) && cmp instanceof InputComponent) {
final InputComponent inputComponent = (InputComponent) cmp;
if (!inputComponent.isOnTopMode()) {
Label labelForComponent = null;
if (inputComponent instanceof TextComponent) {
labelForComponent = ((TextComponent) inputComponent).getField().getLabelForComponent();
} else if (inputComponent instanceof PickerComponent) {
labelForComponent = ((PickerComponent) inputComponent).getPicker().getLabelForComponent();
}
if (labelForComponent != null) {
final Label myLabel = labelForComponent;
final String originalText = myLabel.getText();
final String originalUIID = myLabel.getUIID();
final Constraint myConstraint = constraint;
final Runnable showError = new Runnable() {
@Override
public void run() {
boolean isValid = false;
if (inputComponent instanceof TextComponent) {
isValid = myConstraint.isValid(((TextComponent) inputComponent).getField().getText());
} else if (inputComponent instanceof PickerComponent) {
isValid = myConstraint.isValid(((PickerComponent) inputComponent).getPicker().getValue());
}
String errorMessage = trimLongString(UIManager.getInstance().localize(myConstraint.getDefaultFailMessage(), myConstraint.getDefaultFailMessage()), "ErrorLabel", myLabel.getWidth());
if (errorMessage != null && errorMessage.length() > 0 && !isValid) {
// show the error in place of the label for component
myLabel.setUIID("ErrorLabel");
myLabel.setText(errorMessage);
UITimer.timer(2000, false, Display.getInstance().getCurrent(), new Runnable() {
@Override
public void run() {
myLabel.setUIID(originalUIID);
myLabel.setText(originalText);
}
});
} else {
// show the label for component without the error
myLabel.setUIID(originalUIID);
myLabel.setText(originalText);
}
}
};
FocusListener myFocusListener = new FocusListener() {
@Override
public void focusLost(Component cmp) {
showError.run();
}
@Override
public void focusGained(Component cmp) {
// no code here
}
};
if (inputComponent instanceof TextComponent) {
((TextComponent) inputComponent).getField().addFocusListener(myFocusListener);
} else if (inputComponent instanceof PickerComponent) {
((PickerComponent) inputComponent).getPicker().addFocusListener(myFocusListener);
}
}
}
}
return this;
}
Aggregations