|
|
@@ -10,15 +10,14 @@ import javax.swing.JPopupMenu;
|
|
|
import javax.swing.JTable;
|
|
|
import javax.swing.ListSelectionModel;
|
|
|
|
|
|
-import org.leumasjaffe.charsheet.model.DDCharacter;
|
|
|
-import org.leumasjaffe.charsheet.model.DDCharacterClass;
|
|
|
+import org.leumasjaffe.charsheet.controller.magic.SpellPicker;
|
|
|
import org.leumasjaffe.charsheet.model.magic.DDSpell;
|
|
|
-import org.leumasjaffe.charsheet.model.magic.DDSpellbook;
|
|
|
import org.leumasjaffe.charsheet.model.observable.BoolGate;
|
|
|
import org.leumasjaffe.charsheet.model.observable.IntValue;
|
|
|
-import org.leumasjaffe.charsheet.util.AbilityHelper;
|
|
|
import org.leumasjaffe.event.SelectTableRowPopupMenuListener;
|
|
|
import org.leumasjaffe.format.StringHelper;
|
|
|
+import org.leumasjaffe.observer.ObservableListener;
|
|
|
+import org.leumasjaffe.observer.ObserverDispatch;
|
|
|
|
|
|
import lombok.AccessLevel;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
@@ -42,7 +41,7 @@ import javax.swing.JScrollPane;
|
|
|
@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
|
|
|
public class SelectSpellsPanel extends JPanel {
|
|
|
|
|
|
- private static final String NONE = "<none>";
|
|
|
+ static String NONE = "<none>";
|
|
|
|
|
|
@AllArgsConstructor
|
|
|
private static class SelectSpellModel extends AbstractTableModel {
|
|
|
@@ -51,7 +50,7 @@ public class SelectSpellsPanel extends JPanel {
|
|
|
*/
|
|
|
private static final long serialVersionUID = 1L;
|
|
|
|
|
|
- final Object[] data;
|
|
|
+ Object[] data;
|
|
|
|
|
|
@Override
|
|
|
public int getRowCount() {
|
|
|
@@ -76,31 +75,29 @@ public class SelectSpellsPanel extends JPanel {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- @AllArgsConstructor
|
|
|
- @FieldDefaults(level=AccessLevel.PUBLIC, makeFinal=true)
|
|
|
- public static class Info {
|
|
|
- DDCharacter chara;
|
|
|
- DDCharacterClass dclass;
|
|
|
- }
|
|
|
-
|
|
|
public static final String READY = "Is Filled Out";
|
|
|
|
|
|
@Getter Collection<DDSpell> prepared;
|
|
|
- boolean allowsDuplicates;
|
|
|
+ List<DDSpell> known = new ArrayList<>();
|
|
|
+ SpellPicker pick;
|
|
|
IntValue sharedValue;
|
|
|
SelectSpellModel modelPrepared, modelKnown;
|
|
|
+
|
|
|
+ BoolGate.Handle gate;
|
|
|
+ JTable tablePrepared, tableKnown;
|
|
|
|
|
|
- public SelectSpellsPanel(Info info, BoolGate.Handle gate, int level, Collection<DDSpell> prepared, int toPrepare,
|
|
|
- Collection<DDSpell> avail, boolean allowsDuplicates, IntValue sharedValue) {
|
|
|
- this.allowsDuplicates = allowsDuplicates;
|
|
|
- this.sharedValue = sharedValue;
|
|
|
- final DDSpellbook spellBook = info.dclass.getSpellBook().get();
|
|
|
+ ObservableListener<JTable, SpellPicker> listener;
|
|
|
+
|
|
|
+ public SelectSpellsPanel(SpellPicker pick, BoolGate.Handle gate, int level,
|
|
|
+ Collection<DDSpell> prepared, IntValue sharedValue) {
|
|
|
+ this.pick = pick;
|
|
|
+ this.gate = gate;
|
|
|
+ this.sharedValue = sharedValue == null ? new IntValue(-1) : sharedValue;
|
|
|
this.prepared = new ArrayList<>(prepared);
|
|
|
- final List<DDSpell> known = new ArrayList<>(avail);
|
|
|
- this.modelPrepared = new SelectSpellModel(createPrepareModel(prepared, toPrepare));
|
|
|
- this.modelKnown = new SelectSpellModel(known.stream().map(DDSpell::getName).toArray());
|
|
|
- putClientProperty(READY, countNone() == 0);
|
|
|
- sharedValue.value(sharedValue.value() - this.modelPrepared.data.length + countNone());
|
|
|
+ this.modelPrepared = new SelectSpellModel(createModel(prepared));
|
|
|
+ this.modelKnown = new SelectSpellModel(null);
|
|
|
+ gate.set(countNone() == 0);
|
|
|
+ this.sharedValue.value(this.sharedValue.value() - this.modelPrepared.data.length + countNone());
|
|
|
|
|
|
GridBagLayout gridBagLayout = new GridBagLayout();
|
|
|
gridBagLayout.columnWidths = new int[]{0, 40, 0, 0};
|
|
|
@@ -109,7 +106,7 @@ public class SelectSpellsPanel extends JPanel {
|
|
|
gridBagLayout.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
|
|
|
setLayout(gridBagLayout);
|
|
|
|
|
|
- JPanel panel = new ChooseSpellsPerDayHeader(level, spellBook, AbilityHelper.get(info.chara, info.dclass));
|
|
|
+ JPanel panel = new ChooseSpellsPerDayHeader(level, pick.getInfo().spellBook, pick.getInfo().ability());
|
|
|
GridBagConstraints gbc_panel = new GridBagConstraints();
|
|
|
gbc_panel.gridwidth = 3;
|
|
|
gbc_panel.insets = new Insets(0, 0, 5, 5);
|
|
|
@@ -128,7 +125,7 @@ public class SelectSpellsPanel extends JPanel {
|
|
|
gbc_scrollPane_1.gridy = 1;
|
|
|
add(scrollPane_1, gbc_scrollPane_1);
|
|
|
|
|
|
- JTable tablePrepared = new JTable(modelPrepared);
|
|
|
+ tablePrepared = new JTable(modelPrepared);
|
|
|
tablePrepared.setTableHeader(null);
|
|
|
scrollPane_1.setViewportView(tablePrepared);
|
|
|
tablePrepared.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
|
|
@@ -157,7 +154,7 @@ public class SelectSpellsPanel extends JPanel {
|
|
|
gbc_scrollPane.gridy = 1;
|
|
|
add(scrollPane, gbc_scrollPane);
|
|
|
|
|
|
- JTable tableKnown = new JTable(modelKnown);
|
|
|
+ tableKnown = new JTable(modelKnown);
|
|
|
tableKnown.setTableHeader(null);
|
|
|
scrollPane.setViewportView(tableKnown);
|
|
|
tableKnown.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
|
|
@@ -167,8 +164,8 @@ public class SelectSpellsPanel extends JPanel {
|
|
|
JMenuItem mntmInfo = new JMenuItem("Info");
|
|
|
mntmInfo.addActionListener( e -> {
|
|
|
DDSpell spell = known.get(tableKnown.getSelectedRow());
|
|
|
- JFrame frame = new JFrame(spell.getName() + " (" + info.dclass.getName() + " " + level + ")");
|
|
|
- frame.add(new SpellInfoPanel(info.chara, info.dclass, spell));
|
|
|
+ JFrame frame = new JFrame(spell.getName() + " (" + pick.getInfo().dclass.getName() + " " + level + ")");
|
|
|
+ frame.add(new SpellInfoPanel(pick.getInfo().chara, pick.getInfo().dclass, spell));
|
|
|
frame.pack();
|
|
|
frame.setVisible(true);
|
|
|
});
|
|
|
@@ -182,18 +179,7 @@ public class SelectSpellsPanel extends JPanel {
|
|
|
gbc_button.gridx = 0;
|
|
|
gbc_button.gridy = 1;
|
|
|
panelDivider.add(button, gbc_button);
|
|
|
- button.addActionListener(e -> {
|
|
|
- final int row = tablePrepared.getSelectedRow();
|
|
|
- if (row != -1 && !modelPrepared.data[row].equals(NONE)) {
|
|
|
- sharedValue.value(sharedValue.value() + 1);
|
|
|
- modelPrepared.setValueAt(NONE, row, 0);
|
|
|
- }
|
|
|
- tablePrepared.getSelectionModel().clearSelection();
|
|
|
- tablePrepared.repaint();
|
|
|
- if ((Boolean) getClientProperty(READY)) {
|
|
|
- putClientProperty(READY, false);
|
|
|
- }
|
|
|
- });
|
|
|
+ button.addActionListener(e -> removeSpell());
|
|
|
|
|
|
JButton button_1 = new JButton("<<");
|
|
|
button_1.setMargin(new Insets(2, 8, 2, 8));
|
|
|
@@ -203,63 +189,65 @@ public class SelectSpellsPanel extends JPanel {
|
|
|
gbc_button_1.gridy = 2;
|
|
|
panelDivider.add(button_1, gbc_button_1);
|
|
|
|
|
|
- button_1.addActionListener(e -> {
|
|
|
- final int[] rows = tableKnown.getSelectedRows();
|
|
|
- final int[] orows = tablePrepared.getSelectedRows();
|
|
|
- if (sharedValue.value() == 0) {
|
|
|
- JOptionPane.showMessageDialog(this, "You have exceeded the shared limit on new spells",
|
|
|
- "Error", JOptionPane.ERROR_MESSAGE);
|
|
|
- } else if (orows.length >= rows.length) {
|
|
|
- for (int i = 0; i < rows.length; ++i) {
|
|
|
- if (wouldHaveIllegalDuplicate(rows[i])) continue;
|
|
|
- modelPrepared.data[orows[i]] = modelKnown.data[rows[i]];
|
|
|
- sharedValue.value(sharedValue.value() - 1);
|
|
|
- }
|
|
|
- } else if (orows.length == 0 && countNone() >= rows.length) {
|
|
|
- replace(rows);
|
|
|
- } else {
|
|
|
- final String message = StringHelper.format(
|
|
|
- "Unable to assign new spells, more spells were selected ({}) than were avaliable ({})",
|
|
|
- rows.length, orows.length == 0 ? countNone() : orows.length);
|
|
|
- JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE);
|
|
|
- }
|
|
|
- tableKnown.getSelectionModel().clearSelection();
|
|
|
- tablePrepared.getSelectionModel().clearSelection();
|
|
|
- tablePrepared.repaint();
|
|
|
-
|
|
|
- if (!gate.get() && !Arrays.asList(modelPrepared.data).contains(NONE)) {
|
|
|
- this.prepared.clear();
|
|
|
- for (Object o : modelPrepared.data) {
|
|
|
- this.prepared.add(DDSpell.fromString((String) o)); // TODO
|
|
|
- }
|
|
|
- gate.set(true);
|
|
|
- }
|
|
|
+ button_1.addActionListener(e -> insertSpell());
|
|
|
+
|
|
|
+ listener = new ObservableListener<>(tableKnown, (c, v) -> {
|
|
|
+ known.clear();
|
|
|
+ known.addAll(v.getAvailableSpells(level));
|
|
|
+ this.modelKnown.data = createModel(known);
|
|
|
});
|
|
|
+ listener.setObserved(pick);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void removeSpell() {
|
|
|
+ final int row = tablePrepared.getSelectedRow();
|
|
|
+ if (row != -1 && !modelPrepared.data[row].equals(NONE)) {
|
|
|
+ this.sharedValue.value(this.sharedValue.value() + 1);
|
|
|
+ modelPrepared.setValueAt(NONE, row, 0);
|
|
|
+ }
|
|
|
+ tablePrepared.getSelectionModel().clearSelection();
|
|
|
+ tablePrepared.repaint();
|
|
|
+ this.gate.set(false);
|
|
|
}
|
|
|
|
|
|
- public SelectSpellsPanel(Info info, BoolGate.Handle gate, int level,
|
|
|
- Collection<DDSpell> prepared, Collection<DDSpell> avail) {
|
|
|
- this(info, gate, level, prepared, 0, avail, true, new IntValue(-1));
|
|
|
+ private void insertSpell() {
|
|
|
+ final int[] rows = tableKnown.getSelectedRows();
|
|
|
+ final int[] orows = tablePrepared.getSelectedRows();
|
|
|
+ if (this.sharedValue.value() == 0) {
|
|
|
+ JOptionPane.showMessageDialog(this, "You have exceeded the shared limit on new spells",
|
|
|
+ "Error", JOptionPane.ERROR_MESSAGE);
|
|
|
+ } else if (orows.length >= rows.length) {
|
|
|
+ for (int i = 0; i < rows.length; ++i) {
|
|
|
+ if (wouldHaveIllegalDuplicate(rows[i])) continue;
|
|
|
+ modelPrepared.data[orows[i]] = modelKnown.data[rows[i]];
|
|
|
+ this.sharedValue.value(this.sharedValue.value() - 1);
|
|
|
+ }
|
|
|
+ } else if (orows.length == 0 && countNone() >= rows.length) {
|
|
|
+ replace(rows);
|
|
|
+ } else {
|
|
|
+ final String message = StringHelper.format(
|
|
|
+ "Unable to assign new spells, more spells were selected ({}) than were avaliable ({})",
|
|
|
+ rows.length, orows.length == 0 ? countNone() : orows.length);
|
|
|
+ JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE);
|
|
|
+ }
|
|
|
+ tableKnown.getSelectionModel().clearSelection();
|
|
|
+ tablePrepared.getSelectionModel().clearSelection();
|
|
|
+ tablePrepared.repaint();
|
|
|
+
|
|
|
+ this.prepared.clear();
|
|
|
+ for (Object o : modelPrepared.data) {
|
|
|
+ this.prepared.add(DDSpell.fromString((String) o)); // TODO
|
|
|
+ }
|
|
|
+ gate.set(countNone() == 0);
|
|
|
+ ObserverDispatch.notifySubscribers(pick);
|
|
|
}
|
|
|
|
|
|
private boolean wouldHaveIllegalDuplicate(int row) {
|
|
|
- return !this.allowsDuplicates && Arrays.asList(modelPrepared.data).contains(modelKnown.data[row]);
|
|
|
+ return !pick.allowsDuplicates() && Arrays.asList(modelPrepared.data).contains(modelKnown.data[row]);
|
|
|
}
|
|
|
|
|
|
- private String[] createPrepareModel(Collection<DDSpell> prepared, int toPrepare) {
|
|
|
- if (toPrepare <= prepared.size()) {
|
|
|
- return prepared.stream().map(DDSpell::getName).toArray(String[]::new);
|
|
|
- } else {
|
|
|
- String[] data = new String[toPrepare];
|
|
|
- int i = 0;
|
|
|
- for (DDSpell sp : prepared) {
|
|
|
- data[i++] = sp.getName();
|
|
|
- }
|
|
|
- for (; i < toPrepare; ++i) {
|
|
|
- data[i] = NONE;
|
|
|
- }
|
|
|
- return data;
|
|
|
- }
|
|
|
+ private String[] createModel(Collection<DDSpell> prepared) {
|
|
|
+ return prepared.stream().map(s -> s == null ? NONE : s.getName()).toArray(String[]::new);
|
|
|
}
|
|
|
|
|
|
private void replace(int[] rows) {
|
|
|
@@ -281,4 +269,10 @@ public class SelectSpellsPanel extends JPanel {
|
|
|
}
|
|
|
return cnt;
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void removeNotify() {
|
|
|
+ super.removeNotify();
|
|
|
+ ObserverDispatch.unsubscribeAll(listener);
|
|
|
+ }
|
|
|
}
|