| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- package org.leumasjaffe.recipe.view;
- import java.awt.Component;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.function.Consumer;
- import java.util.function.Function;
- import java.util.function.IntConsumer;
- import java.util.function.IntFunction;
- import java.util.function.Supplier;
- import javax.swing.JPanel;
- import javax.swing.event.DocumentEvent;
- import javax.swing.event.DocumentListener;
- import org.jdesktop.swingx.VerticalLayout;
- import org.leumasjaffe.event.AnyActionDocumentListener;
- import lombok.AllArgsConstructor;
- @SuppressWarnings("serial")
- public class AutoGrowPanel extends JPanel {
- public static interface DocumentListenable {
- void addDocumentListener(DocumentListener dl);
- void removeDocumentListener(DocumentListener dl);
- default void setListPosition(int zeroIndex) {}
- }
-
- @AllArgsConstructor
- private class DeleteOnEmpty implements AnyActionDocumentListener {
- DocumentListenable content;
- @Override public void update(DocumentEvent e) {
- if (e.getDocument().getLength() == 0) {
- content.removeDocumentListener(this);
- int index = members.indexOf(content);
- onDelete.accept(index);
- for (final int size = members.size(); index < size; ++index) {
- members.get(index).setListPosition(index);
- }
- remove((Component) content);
- validateNthParent(4);
- }
- }
- }
-
- @AllArgsConstructor
- private class ExtendAction<T, C extends Component & DocumentListenable> implements AnyActionDocumentListener {
- final Function<T, C> factory;
- final Consumer<? super T> previous;
- final Supplier<? extends T> next;
- T current = null;
- @Override
- public void update(DocumentEvent e) {
- previous.accept(current);
-
- final C object = factory.apply(current = next.get());
- final DocumentListenable back = getBack();
-
- back.removeDocumentListener(this);
- back.addDocumentListener(new DeleteOnEmpty(back));
- object.addDocumentListener(this);
-
- members.add(object);
- add(object);
- validateNthParent(4);
- }
-
- }
-
- IntFunction<DocumentListenable> prod;
- AnyActionDocumentListener grow;
- IntConsumer onDelete;
- List<DocumentListenable> members = new ArrayList<>();
-
- @SafeVarargs
- public <T, C extends Component & DocumentListenable> AutoGrowPanel(Function<T, C> function,
- Supplier<T> newItem, Consumer<? super T> onData, IntConsumer onDelete, T...ts) {
- setLayout(new VerticalLayout(5));
-
- T next = newItem.get();
- this.onDelete = onDelete;
- this.grow = new ExtendAction<T, C>(function, onData, newItem, next);
-
- for (T value : ts) {
- C listen = function.apply(value);
- members.add(listen);
- add(listen);
- listen.addDocumentListener(new DeleteOnEmpty(listen));
- }
-
- C empty = function.apply(next);
- members.add(empty);
- add(empty);
- empty.addDocumentListener(this.grow);
- }
- private DocumentListenable getBack() {
- return members.get(members.size() - 1);
- }
-
- private void validateNthParent(int i) {
- Component current = getParent();
- Component next = current;
- while (i --> 0 && next != null) {
- current = next;
- next = current.getParent();
- }
- current.validate();
- }
-
- }
|