AutoGrowPanel.java 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package org.leumasjaffe.recipe.view;
  2. import java.awt.Component;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import java.util.function.Function;
  6. import java.util.function.IntFunction;
  7. import java.util.function.Supplier;
  8. import javax.swing.JPanel;
  9. import javax.swing.event.DocumentEvent;
  10. import javax.swing.event.DocumentListener;
  11. import org.jdesktop.swingx.VerticalLayout;
  12. import org.leumasjaffe.event.AnyActionDocumentListener;
  13. import lombok.AllArgsConstructor;
  14. @SuppressWarnings("serial")
  15. public class AutoGrowPanel extends JPanel {
  16. public static interface DocumentListenable {
  17. void addDocumentListener(DocumentListener dl);
  18. void removeDocumentListener(DocumentListener dl);
  19. default void setListPosition(int zeroIndex) {}
  20. }
  21. @AllArgsConstructor
  22. private class DeleteOnEmpty implements AnyActionDocumentListener {
  23. DocumentListenable content;
  24. @Override public void update(DocumentEvent e) {
  25. if (e.getDocument().getLength() == 0) {
  26. content.removeDocumentListener(this);
  27. int index = members.indexOf(content);
  28. members.remove(index);
  29. for (final int size = members.size(); index < size; ++index) {
  30. members.get(index).setListPosition(index);
  31. }
  32. remove((Component) content);
  33. getParent().getParent().validate();
  34. }
  35. }
  36. }
  37. IntFunction<DocumentListenable> prod;
  38. AnyActionDocumentListener grow;
  39. List<DocumentListenable> members = new ArrayList<>();
  40. /**
  41. * @wbp.parser.constructor
  42. */
  43. public AutoGrowPanel(Supplier<DocumentListenable> prod) {
  44. this(i -> prod.get(), 1);
  45. }
  46. public AutoGrowPanel(IntFunction<DocumentListenable> prod, int create) {
  47. this.prod = prod;
  48. this.grow = new AnyActionDocumentListener() {
  49. @Override public void update(DocumentEvent e) {
  50. getBack().removeDocumentListener(this);
  51. getBack().addDocumentListener(new DeleteOnEmpty(getBack()));
  52. extend();
  53. getParent().getParent().validate();
  54. }
  55. };
  56. setLayout(new VerticalLayout(5));
  57. while (create-- > 0) {
  58. extend();
  59. }
  60. }
  61. public <T> AutoGrowPanel(Function<T, DocumentListenable> function, List<T> ingredients) {
  62. this(i -> function.apply(ingredients.get(i)), ingredients.size());
  63. }
  64. private void extend() {
  65. members.add(prod.apply(members.size()));
  66. add((Component) getBack());
  67. getBack().addDocumentListener(grow);
  68. }
  69. private DocumentListenable getBack() {
  70. return members.get(members.size() - 1);
  71. }
  72. }