package org.leumasjaffe.charsheet.view.magic; import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.SwingConstants; import java.awt.GridBagLayout; import java.awt.Component; import javax.swing.Box; import java.awt.GridBagConstraints; import java.awt.Insets; import java.util.Collection; import java.util.function.BiFunction; import org.jdesktop.swingx.VerticalLayout; import org.leumasjaffe.charsheet.model.Ability; import org.leumasjaffe.charsheet.model.DDCharacter; import org.leumasjaffe.charsheet.model.DDCharacterClass; import org.leumasjaffe.charsheet.model.DDCharacterClass.DDSpellbookWrapper; import org.leumasjaffe.charsheet.model.magic.DDSpell; import org.leumasjaffe.charsheet.model.magic.DDSpellbook; import org.leumasjaffe.observer.IndirectObservableListener; import org.leumasjaffe.observer.ObserverDispatch; import lombok.AccessLevel; import lombok.experimental.FieldDefaults; @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true) class SpellLevelPanel extends JPanel { /** * */ private static final long serialVersionUID = 1L; IndirectObservableListener listener; protected SpellLevelPanel(JPanel header, DDCharacter chara, DDCharacterClass dclass, int level, BiFunction> getSpells) { GridBagLayout gridBagLayout = new GridBagLayout(); gridBagLayout.columnWidths = new int[]{0, 0, 0}; gridBagLayout.rowHeights = new int[]{0, 0, 0, 0}; gridBagLayout.columnWeights = new double[]{0.0, 0.0, Double.MIN_VALUE}; gridBagLayout.rowWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE}; setLayout(gridBagLayout); GridBagConstraints gbc_panel_1 = new GridBagConstraints(); gbc_panel_1.gridwidth = 2; gbc_panel_1.insets = new Insets(0, 0, 5, 0); gbc_panel_1.fill = GridBagConstraints.BOTH; gbc_panel_1.gridx = 0; gbc_panel_1.gridy = 0; add(header, gbc_panel_1); JPanel panel = new JPanel(new VerticalLayout()); GridBagConstraints gbc_panel = new GridBagConstraints(); gbc_panel.insets = new Insets(0, 0, 5, 0); gbc_panel.fill = GridBagConstraints.BOTH; gbc_panel.gridx = 1; gbc_panel.gridy = 1; add(panel, gbc_panel); Component horizontalStrut = Box.createHorizontalStrut(20); GridBagConstraints gbc_horizontalStrut = new GridBagConstraints(); gbc_horizontalStrut.insets = new Insets(0, 0, 0, 5); gbc_horizontalStrut.gridx = 0; gbc_horizontalStrut.gridy = 2; add(horizontalStrut, gbc_horizontalStrut); final DDSpellbookWrapper wrap = dclass.getSpellBook().get(); listener = new IndirectObservableListener<>(panel, (c, v) -> { c.removeAll(); { final DDSpellbook sb = wrap.getMain(); final Collection spells = getSpells.apply(sb, level); spells.forEach(spell -> c.add(new SpellLine(chara, v, sb, spell, isCastableFromHere()))); } wrap.getSecondary().ifPresent(sb -> { final Collection spells = getSpells.apply(sb, level); if (!spells.isEmpty()) c.add(new JSeparator(SwingConstants.HORIZONTAL)); spells.forEach(spell -> c.add(new SpellLine(chara, v, sb, spell, isCastableFromHere()))); }); c.repaint(); c.validate(); }); if (wrap.getSecondary().isPresent()) { listener.setObserved(dclass, wrap.getMain(), wrap.getSecondary().get()); } else { listener.setObserved(dclass, wrap.getMain()); } } public SpellLevelPanel(DDCharacter chara, DDCharacterClass dclass, int level, Ability.Scores ability) { this(new SpellsKnownHeader(level, dclass.getSpellBook().get().getMain(), ability), chara, dclass, level, DDSpellbook::spellsKnownAtLevel); } public boolean isCastableFromHere() { return false; } @Override public void removeNotify() { super.removeNotify(); ObserverDispatch.unsubscribeAll(listener); } }