Demonstrates basic input component usage.
1. Application Model
Holds value instances which are bound to input components in the panel below.
Show code
demos/manual/src/main/java/is/codion/framework/demos/manual/common/demo/ApplicationModel.java
import static is.codion.common.value.Value.value;
public final class ApplicationModel {
private final Value<String> shortStringValue = value();
private final Value<String> longStringValue = value();
private final Value<String> textValue = value();
private final Value<LocalDate> localDateValue = value();
private final Value<LocalDateTime> localDateTimeValue = value();
private final Value<String> formattedStringValue = value();
private final Value<Integer> integerValue = value();
private final Value<Double> doubleValue = value();
private final Value<Boolean> booleanValue = value();
private final Value<Boolean> booleanSelectionValue = value();
private final Value<Integer> integerItemValue = value();
private final Value<String> stringSelectionValue = value();
private final Value<Integer> integerSlideValue = value();
private final Value<Integer> integerSpinValue = value();
private final Value<Integer> integerSelectionValue = value();
private final Value<String> itemSpinValue = value();
private final ValueSet<String> stringListValue = valueSet();
private final Value<String> messageValue = value();
private final Collection<Value<?>> values = asList(
shortStringValue,
longStringValue,
textValue,
localDateValue,
localDateTimeValue,
formattedStringValue,
integerValue,
doubleValue,
booleanValue,
booleanSelectionValue,
integerItemValue,
stringSelectionValue,
integerSlideValue,
integerSpinValue,
integerSelectionValue,
itemSpinValue,
stringListValue
);
public ApplicationModel() {
setDefaultUncaughtExceptionHandler(this::exceptionHandler);
values.forEach(value -> value.addDataListener(this::setMessage));
}
public void clear() {
values.forEach(value -> value.set(null));
}
public Value<String> shortStringValue() {
return shortStringValue;
}
public Value<String> longStringValue() {
return longStringValue;
}
public Value<String> textValue() {
return textValue;
}
public Value<LocalDate> localDateValue() {
return localDateValue;
}
public Value<LocalDateTime> localDateTimeValue() {
return localDateTimeValue;
}
public Value<Integer> integerValue() {
return integerValue;
}
public Value<Double> doubleValue() {
return doubleValue;
}
public Value<String> formattedStringValue() {
return formattedStringValue;
}
public Value<Boolean> booleanValue() {
return booleanValue;
}
public Value<Boolean> booleanSelectionValue() {
return booleanSelectionValue;
}
public Value<Integer> integerItemValue() {
return integerItemValue;
}
public Value<Integer> integerSlideValue() {
return integerSlideValue;
}
public Value<Integer> integerSpinValue() {
return integerSpinValue;
}
public Value<Integer> integerSelectionValue() {
return integerSelectionValue;
}
public Value<String> itemSpinnerValue() {
return itemSpinValue;
}
public Value<String> stringSelectionValue() {
return stringSelectionValue;
}
public ValueSet<String> stringListValueSet() {
return stringListValue;
}
public ValueObserver<String> messageObserver() {
return messageValue.observer();
}
public ComboBoxModel<String> createStringComboBoxModel() {
return new DefaultComboBoxModel<>(new String[] {"Hello", "Everybody", "How", "Are", "You"});
}
public ItemComboBoxModel<Integer> createIntegerItemComboBoxModel() {
return itemComboBoxModel(asList(
Item.item(1, "One"), Item.item(2, "Two"), Item.item(3, "Three"),
Item.item(4, "Four"), Item.item(5, "Five"), Item.item(6, "Six"),
Item.item(7, "Seven"), Item.item(8, "Eight"), Item.item(9, "Nine")
));
}
public DefaultBoundedRangeModel createIntegerSliderModel() {
return new DefaultBoundedRangeModel(0, 0, 0, 100);
}
public SpinnerNumberModel createIntegerSpinnerModel() {
return new SpinnerNumberModel(0, 0, 100, 10);
}
public ComboBoxModel<Integer> createIntegerComboBoxModel() {
return new DefaultComboBoxModel<>(new Integer[] {101, 202, 303, 404});
}
public SpinnerListModel createItemSpinnerModel() {
return new SpinnerListModel(Arrays.asList(
Item.item("Hello"),
Item.item("Everybody"),
Item.item("How"),
Item.item("Are"),
Item.item("You")
));
}
public ListModel<String> createStringListModel() {
DefaultListModel<String> listModel = new DefaultListModel<>();
listModel.addElement("Here");
listModel.addElement("Are");
listModel.addElement("A");
listModel.addElement("Few");
listModel.addElement("Elements");
listModel.addElement("To");
listModel.addElement("Select");
listModel.addElement("From");
return listModel;
}
private void exceptionHandler(Thread thread, Throwable exception) {
messageValue.set(exception.getMessage());
}
private <T> void setMessage(T value) {
messageValue.set(value == null ? " " : value.toString());
}
}
2. Application Panel
Show code
demos/manual/src/main/java/is/codion/framework/demos/manual/common/demo/ApplicationPanel.java
import static is.codion.swing.common.ui.component.Components.*;
public final class ApplicationPanel extends JPanel {
public ApplicationPanel(ApplicationModel model) {
super(borderLayout());
setBorder(emptyBorder());
JPanel settingsPanel = new JPanel(borderLayout());
State inputEnabledState = State.state(true);
checkBox(inputEnabledState)
.text("Enabled")
.mnemonic('N')
.transferFocusOnEnter(true)
.build(checkBox -> settingsPanel.add(checkBox, BorderLayout.WEST));
button(Control.builder(model::clear)
.enabled(inputEnabledState)
.name("Clear")
.mnemonic('L'))
.transferFocusOnEnter(true)
.build(button -> settingsPanel.add(button, BorderLayout.EAST));
JPanel inputPanel = flexibleGridLayoutPanel(0, 2).build();
Components.stringField(model.shortStringValue())
.columns(20)
.lowerCase(true)
.maximumLength(20)
.selectAllOnFocusGained(true)
.transferFocusOnEnter(true)
.validator(new PGValidator())
.selector(new StringSelector())
.label(label("Short String (1)")
.displayedMnemonic('1')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
textFieldPanel(model.longStringValue())
.columns(20)
.maximumLength(400)
.buttonFocusable(true)
.selectAllOnFocusGained(true)
.transferFocusOnEnter(true)
.label(label("Long String (2)")
.displayedMnemonic('2')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
textArea(model.textValue())
.rowsColumns(4, 20)
.lineWrap(true)
.wrapStyleWord(true)
.transferFocusOnEnter(true)
.dragEnabled(true)
.transferHandler(new FilePathTransferHandler())
.keyEvent(KeyEvents.builder(VK_SPACE)
.modifiers(CTRL_DOWN_MASK)
.action(Control.actionControl(actionEvent ->
((JTextArea) actionEvent.getSource()).append("SPACE"))))
.label(label("Text (3)")
.displayedMnemonic('3')
.build(inputPanel::add))
.enabled(inputEnabledState)
.scrollPane()
.build(inputPanel::add);
maskedTextField(model.formattedStringValue())
.mask("(##) ##-##")
.placeholderCharacter('_')
.placeholder("(00) 00-00")
.emptyStringToNullValue(true)
.invalidStringToNullValue(true)
.valueContainsLiteralCharacters(true)
.commitsOnValidEdit(true)
.focusLostBehaviour(JFormattedTextField.COMMIT)
.transferFocusOnEnter(true)
.label(label("Formatted String (4)")
.displayedMnemonic('4')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
comboBox(model.createStringComboBoxModel(), model.stringSelectionValue())
.editable(true)
.mouseWheelScrolling(true)
.transferFocusOnEnter(true)
.label(label("String Selection (5)")
.displayedMnemonic('5')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
localDateField(LocaleDateTimePattern.builder()
.delimiterDash()
.yearFourDigits()
.build()
.dateTimePattern(), model.localDateValue())
.transferFocusOnEnter(true)
.label(label("Date (6)")
.displayedMnemonic('6')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
localDateTimeFieldPanel(LocaleDateTimePattern.builder()
.delimiterDot()
.yearTwoDigits()
.hoursMinutes()
.build()
.dateTimePattern(), model.localDateTimeValue())
.transferFocusOnEnter(true)
.label(label("Date Time (7)")
.displayedMnemonic('7')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
integerField(model.integerValue())
.valueRange(0, 10_000)
.groupingUsed(true)
.groupingSeparator('.')
.transferFocusOnEnter(true)
.label(label("Integer (8)")
.displayedMnemonic('8')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
doubleField(model.doubleValue())
.nullable(false)
.valueRange(0, 1_000_000)
.groupingUsed(true)
.maximumFractionDigits(2)
.decimalSeparator(',')
.groupingSeparator('.')
.convertGroupingToDecimalSeparator(true)
.transferFocusOnEnter(true)
.label(label("Double (9)")
.displayedMnemonic('9')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
ItemComboBoxModel<Integer> integerItemComboBoxModel = model.createIntegerItemComboBoxModel();
Value<Integer> integerItemSelectorValue = integerItemComboBoxModel.createSelectorValue(new IntegerItemFinder());
NumberField<Integer> integerItemSelectorField = integerField(integerItemSelectorValue)
.columns(2)
.horizontalAlignment(SwingConstants.CENTER)
.selectAllOnFocusGained(true)
.transferFocusOnEnter(true)
.label(label("Integer Item (A)")
.displayedMnemonic('A')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build();
JComboBox<Item<Integer>> integerItemComboBox = itemComboBox(integerItemComboBoxModel, model.integerItemValue())
.completionMode(Completion.Mode.AUTOCOMPLETE)
.popupMenuControl(comboBox -> createSelectRandomItemControl(integerItemComboBoxModel))
.mouseWheelScrollingWithWrapAround(true)
.transferFocusOnEnter(true)
.enabled(inputEnabledState)
.build();
borderLayoutPanel()
.westComponent(integerItemSelectorField)
.centerComponent(integerItemComboBox)
.build(inputPanel::add);
slider(model.createIntegerSliderModel(), model.integerSlideValue())
.paintTicks(true)
.paintTrack(true)
.minorTickSpacing(5)
.majorTickSpacing(20)
.mouseWheelScrolling(true)
.transferFocusOnEnter(true)
.label(label("Integer Slide (B)")
.displayedMnemonic('B')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
integerSpinner(model.createIntegerSpinnerModel(), model.integerSpinValue())
.columns(4)
.mouseWheelScrolling(true)
.transferFocusOnEnter(true)
.label(label("Integer Spin (C)")
.displayedMnemonic('C')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
comboBox(model.createIntegerComboBoxModel(), model.integerSelectionValue())
.editable(true)
.mouseWheelScrolling(true)
.transferFocusOnEnter(true)
.label(label("Integer Selection (D)")
.displayedMnemonic('D')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
itemSpinner(model.createItemSpinnerModel(), model.itemSpinnerValue())
.columns(20)
.horizontalAlignment(SwingConstants.CENTER)
.mouseWheelScrolling(true)
.transferFocusOnEnter(true)
.label(label("Item Spin (E)")
.displayedMnemonic('E')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
checkBox(model.booleanValue())
.horizontalAlignment(SwingConstants.CENTER)
.transferFocusOnEnter(true)
.label(label("Boolean (F)")
.displayedMnemonic('F')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
booleanComboBox(model.booleanSelectionValue())
.mouseWheelScrolling(true)
.transferFocusOnEnter(true)
.enabled(inputEnabledState)
.label(label("Boolean Selection (G)")
.displayedMnemonic('G')
.build(inputPanel::add))
.build(inputPanel::add);
Components.list(model.createStringListModel(), model.stringListValueSet())
.visibleRowCount(4)
.layoutOrientation(JList.HORIZONTAL_WRAP)
.transferFocusOnEnter(true)
.label(label("Text List Selection (H)")
.displayedMnemonic('H')
.build(inputPanel::add))
.enabled(inputEnabledState)
.build(inputPanel::add);
add(settingsPanel, BorderLayout.NORTH);
add(inputPanel, BorderLayout.CENTER);
flexibleGridLayoutPanel(2, 1)
.add(stringField()
.columns(20)
.editable(false)
.focusable(false)
.border(createTitledBorder("Message"))
.enabled(inputEnabledState)
.linkedValue(model.messageObserver())
.build(component -> add(component, BorderLayout.SOUTH)))
.add(lookAndFeelComboBox(true))
.build(southPanel -> add(southPanel, BorderLayout.SOUTH));
Sizes.setPreferredWidth(this, 400);
}
private static class PGValidator implements Value.Validator<String> {
private final List<String> swearWords = asList("fuck", "shit");
@Override
public void validate(String value) {
if (value != null) {
String lowerCaseValue = value.toLowerCase();
swearWords.forEach(swearWord -> {
if (lowerCaseValue.contains(swearWord)) {
throw new IllegalArgumentException("No swearing please");
}
});
}
}
}
private static class StringSelector implements SingleSelector<String> {
private static final String DEFAULT_SELECTION = "strings";
private final List<String> stringsToSelectFrom = Arrays.asList("a", "few", "short", "strings", "to", "choose", "from");
@Override
public Optional<String> select(JComponent dialogOwner) {
return Dialogs.selectionDialog(stringsToSelectFrom)
.owner(dialogOwner)
.defaultSelection(DEFAULT_SELECTION)
.selectSingle();
}
}
private static class FilePathTransferHandler extends TransferHandler {
@Override
public boolean canImport(TransferSupport support) {
return Arrays.stream(support.getDataFlavors())
.anyMatch(DataFlavor::isFlavorJavaFileListType);
}
@Override
public boolean importData(TransferSupport support) {
try {
((JTextArea) support.getComponent()).setText(support.getTransferable()
.getTransferData(DataFlavor.javaFileListFlavor).toString());
return true;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
private static final class IntegerItemFinder implements ItemFinder<Item<Integer>, Integer> {
@Override
public Integer value(Item<Integer> item) {
return item.get();
}
@Override
public Predicate<Item<Integer>> createPredicate(Integer value) {
return item -> Objects.equals(item.get(), value);
}
}
private static Control createSelectRandomItemControl(ItemComboBoxModel<Integer> integerItemComboBoxModel) {
Random random = new Random();
return Control.builder(() ->
integerItemComboBoxModel.setSelectedItem(random.nextInt(integerItemComboBoxModel.getSize()) + 1))
.name("Select Random Item")
.build();
}
public static void main(String[] args) {
Arrays.stream(FlatAllIJThemes.INFOS)
.forEach(LookAndFeelProvider::addLookAndFeelProvider);
findLookAndFeelProvider("com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMonokaiProIJTheme")
.ifPresent(LookAndFeelProvider::enable);
ApplicationModel applicationModel = new ApplicationModel();
ApplicationPanel applicationPanel = new ApplicationPanel(applicationModel);
Dialogs.componentDialog(applicationPanel)
.title("Codion Input Components Demo")
.icon(Logos.logoTransparent())
.show();
}
}