|
@@ -0,0 +1,234 @@
|
|
|
|
|
+package org.leumasjaffe.charsheet.view.skills;
|
|
|
|
|
+
|
|
|
|
|
+import javax.swing.JPanel;
|
|
|
|
|
+
|
|
|
|
|
+import org.leumasjaffe.charsheet.model.Ability;
|
|
|
|
|
+import org.leumasjaffe.charsheet.model.DDCharacter;
|
|
|
|
|
+import org.leumasjaffe.charsheet.model.DDCharacterClass;
|
|
|
|
|
+import org.leumasjaffe.charsheet.model.observable.IntValue;
|
|
|
|
|
+import org.leumasjaffe.charsheet.model.skill.DDSkill;
|
|
|
|
|
+import org.leumasjaffe.charsheet.util.StringHelper;
|
|
|
|
|
+import org.leumasjaffe.observer.IndirectObservableListener;
|
|
|
|
|
+import org.leumasjaffe.observer.ObserverDispatch;
|
|
|
|
|
+
|
|
|
|
|
+import lombok.AccessLevel;
|
|
|
|
|
+import lombok.experimental.FieldDefaults;
|
|
|
|
|
+
|
|
|
|
|
+import java.awt.GridBagLayout;
|
|
|
|
|
+import javax.swing.JCheckBox;
|
|
|
|
|
+import java.awt.GridBagConstraints;
|
|
|
|
|
+import javax.swing.JLabel;
|
|
|
|
|
+import java.awt.Insets;
|
|
|
|
|
+import java.util.function.IntFunction;
|
|
|
|
|
+import java.awt.Dimension;
|
|
|
|
|
+import javax.swing.JTextField;
|
|
|
|
|
+import java.awt.Color;
|
|
|
|
|
+import javax.swing.border.MatteBorder;
|
|
|
|
|
+import javax.swing.SwingConstants;
|
|
|
|
|
+import java.awt.Component;
|
|
|
|
|
+import javax.swing.Box;
|
|
|
|
|
+import javax.swing.JButton;
|
|
|
|
|
+import java.awt.Font;
|
|
|
|
|
+
|
|
|
|
|
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
|
|
|
|
|
+public class SkillLevelUpLine extends JPanel {
|
|
|
|
|
+ /**
|
|
|
|
|
+ *
|
|
|
|
|
+ */
|
|
|
|
|
+ private static final long serialVersionUID = 1L;
|
|
|
|
|
+ boolean isClassSkill;
|
|
|
|
|
+ DDSkill skill;
|
|
|
|
|
+ IntValue current;
|
|
|
|
|
+ IndirectObservableListener<JTextField, DDCharacter> totalListener;
|
|
|
|
|
+
|
|
|
|
|
+ public SkillLevelUpLine(final DDCharacter chara, final DDCharacterClass cclass, final DDSkill skill, IntValue pointsAvaliable) {
|
|
|
|
|
+ isClassSkill = cclass.isClassSkill(skill.getName());
|
|
|
|
|
+ this.skill = skill;
|
|
|
|
|
+ current = new IntValue(0);
|
|
|
|
|
+ final int pointsPerRank = isClassSkill ? 1 : 2;
|
|
|
|
|
+ final int maxPoints = (chara.getLevel() + 3) / pointsPerRank - skill.getRanks().value();
|
|
|
|
|
+
|
|
|
|
|
+ setBorder(new MatteBorder(0, 0, 1, 0, (Color) new Color(0, 0, 0)));
|
|
|
|
|
+ setPreferredSize(new Dimension(475, 22));
|
|
|
|
|
+ GridBagLayout gridBagLayout = new GridBagLayout();
|
|
|
|
|
+ gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
|
+ gridBagLayout.rowHeights = new int[]{0, 0};
|
|
|
|
|
+ gridBagLayout.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
|
|
|
|
|
+ gridBagLayout.rowWeights = new double[]{0.0, Double.MIN_VALUE};
|
|
|
|
|
+ setLayout(gridBagLayout);
|
|
|
|
|
+
|
|
|
|
|
+ JCheckBox checkBoxIsClassSkill = new JCheckBox("");
|
|
|
|
|
+ checkBoxIsClassSkill.setToolTipText("Class Skill?");
|
|
|
|
|
+ checkBoxIsClassSkill.setSelected(cclass.isClassSkill(skill.getName()));
|
|
|
|
|
+ checkBoxIsClassSkill.setEnabled(false);
|
|
|
|
|
+ GridBagConstraints gbc_checkBoxIsClassSkill = new GridBagConstraints();
|
|
|
|
|
+ gbc_checkBoxIsClassSkill.insets = new Insets(1, 0, 0, 5);
|
|
|
|
|
+ gbc_checkBoxIsClassSkill.gridx = 0;
|
|
|
|
|
+ gbc_checkBoxIsClassSkill.gridy = 0;
|
|
|
|
|
+ add(checkBoxIsClassSkill, gbc_checkBoxIsClassSkill);
|
|
|
|
|
+
|
|
|
|
|
+ JLabel lblName = new JLabel(skill.getName());
|
|
|
|
|
+ lblName.setMaximumSize(new Dimension(150, 14));
|
|
|
|
|
+ lblName.setMinimumSize(new Dimension(150, 14));
|
|
|
|
|
+ lblName.setPreferredSize(new Dimension(150, 14));
|
|
|
|
|
+ GridBagConstraints gbc_lblName = new GridBagConstraints();
|
|
|
|
|
+ gbc_lblName.fill = GridBagConstraints.HORIZONTAL;
|
|
|
|
|
+ gbc_lblName.insets = new Insets(1, 0, 0, 5);
|
|
|
|
|
+ gbc_lblName.gridx = 1;
|
|
|
|
|
+ gbc_lblName.gridy = 0;
|
|
|
|
|
+ add(lblName, gbc_lblName);
|
|
|
|
|
+
|
|
|
|
|
+ JLabel lblAbil = new JLabel(skill.getAbility());
|
|
|
|
|
+ lblAbil.setMaximumSize(new Dimension(30, 14));
|
|
|
|
|
+ lblAbil.setMinimumSize(new Dimension(30, 14));
|
|
|
|
|
+ lblAbil.setPreferredSize(new Dimension(30, 14));
|
|
|
|
|
+ GridBagConstraints gbc_lblAbil = new GridBagConstraints();
|
|
|
|
|
+ gbc_lblAbil.insets = new Insets(1, 0, 0, 5);
|
|
|
|
|
+ gbc_lblAbil.anchor = GridBagConstraints.EAST;
|
|
|
|
|
+ gbc_lblAbil.gridx = 2;
|
|
|
|
|
+ gbc_lblAbil.gridy = 0;
|
|
|
|
|
+ add(lblAbil, gbc_lblAbil);
|
|
|
|
|
+
|
|
|
|
|
+ JTextField total = new JTextField();
|
|
|
|
|
+ total.setToolTipText("Skill Modifier");
|
|
|
|
|
+ total.setHorizontalAlignment(SwingConstants.CENTER);
|
|
|
|
|
+ total.setEditable(false);
|
|
|
|
|
+ total.setMinimumSize(new Dimension(30, 20));
|
|
|
|
|
+ total.setMaximumSize(new Dimension(30, 20));
|
|
|
|
|
+ total.setPreferredSize(new Dimension(30, 20));
|
|
|
|
|
+ GridBagConstraints gbc_total = new GridBagConstraints();
|
|
|
|
|
+ gbc_total.insets = new Insets(1, 0, 0, 5);
|
|
|
|
|
+ gbc_total.fill = GridBagConstraints.HORIZONTAL;
|
|
|
|
|
+ gbc_total.gridx = 3;
|
|
|
|
|
+ gbc_total.gridy = 0;
|
|
|
|
|
+ add(total, gbc_total);
|
|
|
|
|
+ total.setColumns(10);
|
|
|
|
|
+
|
|
|
|
|
+ JLabel label = new JLabel("=");
|
|
|
|
|
+ GridBagConstraints gbc_label = new GridBagConstraints();
|
|
|
|
|
+ gbc_label.anchor = GridBagConstraints.EAST;
|
|
|
|
|
+ gbc_label.insets = new Insets(1, 0, 0, 5);
|
|
|
|
|
+ gbc_label.gridx = 4;
|
|
|
|
|
+ gbc_label.gridy = 0;
|
|
|
|
|
+ add(label, gbc_label);
|
|
|
|
|
+
|
|
|
|
|
+ JTextField modifier = new JTextField();
|
|
|
|
|
+ modifier.setToolTipText("Ability Modifier");
|
|
|
|
|
+ modifier.setHorizontalAlignment(SwingConstants.CENTER);
|
|
|
|
|
+ modifier.setEditable(false);
|
|
|
|
|
+ modifier.setMinimumSize(new Dimension(30, 20));
|
|
|
|
|
+ modifier.setMaximumSize(new Dimension(30, 20));
|
|
|
|
|
+ modifier.setPreferredSize(new Dimension(30, 20));
|
|
|
|
|
+ GridBagConstraints gbc_modifier = new GridBagConstraints();
|
|
|
|
|
+ gbc_modifier.insets = new Insets(1, 0, 0, 5);
|
|
|
|
|
+ gbc_modifier.fill = GridBagConstraints.HORIZONTAL;
|
|
|
|
|
+ gbc_modifier.gridx = 5;
|
|
|
|
|
+ gbc_modifier.gridy = 0;
|
|
|
|
|
+ add(modifier, gbc_modifier);
|
|
|
|
|
+ modifier.setColumns(10);
|
|
|
|
|
+
|
|
|
|
|
+ JLabel label_1 = new JLabel("+");
|
|
|
|
|
+ GridBagConstraints gbc_label_1 = new GridBagConstraints();
|
|
|
|
|
+ gbc_label_1.anchor = GridBagConstraints.EAST;
|
|
|
|
|
+ gbc_label_1.insets = new Insets(1, 0, 0, 5);
|
|
|
|
|
+ gbc_label_1.gridx = 6;
|
|
|
|
|
+ gbc_label_1.gridy = 0;
|
|
|
|
|
+ add(label_1, gbc_label_1);
|
|
|
|
|
+
|
|
|
|
|
+ JTextField ranks = new JTextField(StringHelper.toString(skill.getRanks()));
|
|
|
|
|
+ ranks.setToolTipText("Ranks");
|
|
|
|
|
+ ranks.setHorizontalAlignment(SwingConstants.CENTER);
|
|
|
|
|
+ ranks.setEditable(false);
|
|
|
|
|
+ ranks.setMinimumSize(new Dimension(30, 20));
|
|
|
|
|
+ ranks.setMaximumSize(new Dimension(30, 20));
|
|
|
|
|
+ ranks.setPreferredSize(new Dimension(30, 20));
|
|
|
|
|
+ GridBagConstraints gbc_ranks = new GridBagConstraints();
|
|
|
|
|
+ gbc_ranks.insets = new Insets(1, 0, 0, 5);
|
|
|
|
|
+ gbc_ranks.fill = GridBagConstraints.HORIZONTAL;
|
|
|
|
|
+ gbc_ranks.gridx = 7;
|
|
|
|
|
+ gbc_ranks.gridy = 0;
|
|
|
|
|
+ add(ranks, gbc_ranks);
|
|
|
|
|
+ ranks.setColumns(10);
|
|
|
|
|
+
|
|
|
|
|
+ Component horizontalStrut = Box.createHorizontalStrut(20);
|
|
|
|
|
+ GridBagConstraints gbc_horizontalStrut = new GridBagConstraints();
|
|
|
|
|
+ gbc_horizontalStrut.insets = new Insets(0, 0, 0, 5);
|
|
|
|
|
+ gbc_horizontalStrut.gridx = 8;
|
|
|
|
|
+ gbc_horizontalStrut.gridy = 0;
|
|
|
|
|
+ add(horizontalStrut, gbc_horizontalStrut);
|
|
|
|
|
+
|
|
|
|
|
+ JButton plus = new JButton("+");
|
|
|
|
|
+ plus.setMargin(new Insets(2, 2, 2, 2));
|
|
|
|
|
+ plus.setFont(new Font("Tahoma", Font.PLAIN, 8));
|
|
|
|
|
+ plus.setPreferredSize(new Dimension(30, 19));
|
|
|
|
|
+ plus.setMinimumSize(new Dimension(30, 19));
|
|
|
|
|
+ GridBagConstraints gbc_plus = new GridBagConstraints();
|
|
|
|
|
+ gbc_plus.insets = new Insets(0, 0, 1, 5);
|
|
|
|
|
+ gbc_plus.gridx = 9;
|
|
|
|
|
+ gbc_plus.gridy = 0;
|
|
|
|
|
+ add(plus, gbc_plus);
|
|
|
|
|
+
|
|
|
|
|
+ JButton minus = new JButton("-");
|
|
|
|
|
+ minus.setMargin(new Insets(2, 2, 2, 2));
|
|
|
|
|
+ minus.setFont(new Font("Tahoma", Font.PLAIN, 8));
|
|
|
|
|
+ minus.setMinimumSize(new Dimension(30, 19));
|
|
|
|
|
+ minus.setPreferredSize(new Dimension(30, 19));
|
|
|
|
|
+ GridBagConstraints gbc_minus = new GridBagConstraints();
|
|
|
|
|
+ gbc_minus.insets = new Insets(0, 0, 1, 5);
|
|
|
|
|
+ gbc_minus.gridx = 10;
|
|
|
|
|
+ gbc_minus.gridy = 0;
|
|
|
|
|
+ add(minus, gbc_minus);
|
|
|
|
|
+
|
|
|
|
|
+ JTextField points = new JTextField();
|
|
|
|
|
+ points.setMinimumSize(new Dimension(30, 20));
|
|
|
|
|
+ points.setText("0");
|
|
|
|
|
+ points.setEditable(false);
|
|
|
|
|
+ GridBagConstraints gbc_points = new GridBagConstraints();
|
|
|
|
|
+ gbc_points.gridx = 11;
|
|
|
|
|
+ gbc_points.gridy = 0;
|
|
|
|
|
+ add(points, gbc_points);
|
|
|
|
|
+ points.setColumns(10);
|
|
|
|
|
+
|
|
|
|
|
+ IntFunction<Void> lambda = (value) -> {
|
|
|
|
|
+ pointsAvaliable.value(pointsAvaliable.value() - (value * pointsPerRank));
|
|
|
|
|
+ current.value(current.value() + value);
|
|
|
|
|
+ points.setText(Integer.toString(current.value()));
|
|
|
|
|
+ ObserverDispatch.notifySubscribers(pointsAvaliable, this);
|
|
|
|
|
+ ObserverDispatch.notifySubscribers(current, this);
|
|
|
|
|
+ return null;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ plus.addActionListener((e) -> {
|
|
|
|
|
+ if (pointsAvaliable.value() >= pointsPerRank && current.value() < maxPoints) { lambda.apply(1); }
|
|
|
|
|
+ });
|
|
|
|
|
+ minus.addActionListener((e) -> {
|
|
|
|
|
+ if (current.value() > 0) { lambda.apply(-1); }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ if ( skill.getAbility().isEmpty() ) {
|
|
|
|
|
+ totalListener = new IndirectObservableListener<>(total,
|
|
|
|
|
+ (c, v) -> {
|
|
|
|
|
+ c.setText(StringHelper.toString(skill.getRanks().value() + current.value()));
|
|
|
|
|
+ });
|
|
|
|
|
+ totalListener.setObserved(chara, current);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ totalListener = new IndirectObservableListener<>(total,
|
|
|
|
|
+ (c, v) -> {
|
|
|
|
|
+ final int skillRanks = skill.getRanks().value();
|
|
|
|
|
+ final int mod = Ability.modifier(Ability.fields.get(skill.getAbility())
|
|
|
|
|
+ .apply(chara.getAbilities().getBase()).value());
|
|
|
|
|
+ c.setText(StringHelper.toString(skillRanks + mod + current.value()));
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ final IntValue abilScore = Ability.fields.get(skill.getAbility())
|
|
|
|
|
+ .apply(chara.getAbilities().getBase());
|
|
|
|
|
+ modifier.setText(StringHelper.toString(Ability.modifier(abilScore.value())));
|
|
|
|
|
+ totalListener.setObserved(chara, current);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ void applyChange() {
|
|
|
|
|
+ skill.spendPoints(current.value(), !isClassSkill);
|
|
|
|
|
+ ObserverDispatch.notifySubscribers(skill.getRanks(), this);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|