| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- package org.leumasjaffe.charsheet.view;
- import javax.swing.JFileChooser;
- import javax.swing.JFrame;
- import javax.swing.JTabbedPane;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
- import lombok.AccessLevel;
- import lombok.NonNull;
- import lombok.SneakyThrows;
- import lombok.experimental.FieldDefaults;
- import lombok.experimental.NonFinal;
- import java.awt.BorderLayout;
- import javax.swing.JPanel;
- import javax.swing.JMenuBar;
- import javax.swing.JMenu;
- import javax.swing.JMenuItem;
- import javax.swing.JOptionPane;
- import javax.swing.KeyStroke;
- import javax.swing.UIManager;
- import org.leumasjaffe.charsheet.model.DDCharacter;
- import org.leumasjaffe.charsheet.model.DDCharacterClass;
- import org.leumasjaffe.charsheet.model.observable.IntValue;
- import org.leumasjaffe.charsheet.observer.ObserverHelper;
- import org.leumasjaffe.observer.ObserverDispatch;
- import java.awt.event.KeyEvent;
- import java.awt.event.WindowEvent;
- import java.io.File;
- import java.util.ArrayList;
- import java.util.List;
- import java.awt.event.InputEvent;
- @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
- public class D20Sheet extends JFrame {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- ObjectMapper mapper = new ObjectMapper();
- @NonFinal File currentlyOpenFile = null;
- @NonFinal @NonNull DDCharacter model = new DDCharacter();
- JTabbedPane tabbedPane;
- SummaryTab summaryTab;
- List<ClassTab> classTabs = new ArrayList<>();
- JPanel abilitiesTab;
- SkillTab skillTab;
- EquipmentTab equipmentTab;
- private DeveloperMenu developerMenu;
-
- public D20Sheet() {
- UIManager.put("CheckBox.disabledText", UIManager.get("CheckBox.foreground"));
- // Set up local state variables
- final JFileChooser fc = new JFileChooser("resources");
- mapper.registerModule(new Jdk8Module());
- // Set up GUI Data (WindowBuilder)
- tabbedPane = new JTabbedPane(JTabbedPane.TOP);
- getContentPane().add(tabbedPane, BorderLayout.CENTER);
-
- summaryTab = new SummaryTab();
- abilitiesTab = new JPanel();
- skillTab = new SkillTab();
- equipmentTab = new EquipmentTab();
-
- JMenuBar menuBar = new JMenuBar();
- setJMenuBar(menuBar);
-
- JMenu mnFile = new JMenu("File");
- menuBar.add(mnFile);
-
- JMenuItem mntmNew = new JMenuItem("New");
- mntmNew.addActionListener(e -> { setModel(new DDCharacter()); });
- mntmNew.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
- mnFile.add(mntmNew);
-
- JMenuItem mntmOpen = new JMenuItem("Open");
- mntmOpen.addActionListener(e -> {
- int rv = fc.showOpenDialog(this);
- if ( rv == JFileChooser.APPROVE_OPTION ) {
- loadModelResource( fc.getSelectedFile() );
- tabbedPane.setSelectedIndex(0);
- }
- });
- mntmOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
- mnFile.add(mntmOpen);
-
- JMenuItem mntmSave = new JMenuItem("Save");
- mntmSave.addActionListener( e -> {
- if ( currentlyOpenFile == null ) { saveAs(fc); }
- else { saveModelResource(); }
- } );
- mntmSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
- mnFile.add(mntmSave);
-
- JMenuItem mntmSaveAs = new JMenuItem("Save As");
- mntmSaveAs.addActionListener( e -> saveAs(fc) );
- mntmSaveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
- mnFile.add(mntmSaveAs);
-
- JMenuItem mntmConfig = new JMenuItem("Config");
- mntmConfig.addActionListener( e -> DialogBuilder.showConfigDialog(this) );
- mntmConfig.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.ALT_DOWN_MASK));
- mnFile.add(mntmConfig);
-
- JMenuItem mntmExit = new JMenuItem("Exit");
- mntmExit.addActionListener( e -> { this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING)); } );
- mntmExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_MASK));
- mnFile.add(mntmExit);
-
- JMenu mnSession = new JMenu("Session");
- menuBar.add(mnSession);
-
- JMenuItem mntmGainExperience = new JMenuItem("Gain Experience");
- mntmGainExperience.addActionListener(e -> {
- // TODO move to own thing?
- final String input = JOptionPane.showInputDialog("How much experience");
- if (input == null || input.isEmpty()) return;
- final int exp = Integer.parseInt(input);
- if (exp <= 0) return;
- final IntValue mdlExp = this.model.getExperience();
- mdlExp.value(mdlExp.value()+exp);
- ObserverDispatch.notifySubscribers(mdlExp, this);
- DialogBuilder.showLevelUpDialog(this, this.model, 0);
- });
- mnSession.add(mntmGainExperience);
-
- JMenuItem mntmTakeRest = new JMenuItem("Take Rest");
- mntmTakeRest.addActionListener(e -> {
- // Step 0: Gather information about the rest
- // Step 0.1: Check if 8-hour or full day
- // Step 0.2: Check if Long-Term-Care
- // Step 1: Heal Character according to info
- // Step 1.1: Heal non-lethal damage
- // Step 1.2: Heal ability damage
- // Step 2: Regenerate spells prepared
- // Step 2.1: If Spontaneous, skip (2)
- for (DDCharacterClass dclass : model.getClasses()) {
- dclass.getSpellBook().ifPresent(sb -> {
- if (sb.preparesSpells()) {
- DialogBuilder.createPrepareSpellsDialog(this, model, dclass);
- } else {
- for (int i = 0; i < dclass.getHighestSpellLevel(); ++i) {
- sb.prepareSpells(i, null);
- }
- }
- });
- }
- // Step N: regenerate spellbooks
- for (DDCharacterClass dclass : model.getClasses()) {
- ObserverHelper.notifyObservableHierarchy(dclass, this);
- }
- });
- mnSession.add(mntmTakeRest);
-
- developerMenu = new DeveloperMenu(this);
- menuBar.add(developerMenu);
-
- // Set up post-GUI dependencies
- setModel(model);
- }
- public D20Sheet(final String initialFile) {
- this();
- loadModelResource(new File(initialFile));
- }
-
- private void reorderTabs() {
- this.tabbedPane.removeAll();
- tabbedPane.addTab("Summary", null, summaryTab, null);
- classTabs.forEach( t -> tabbedPane.addTab(t.getName(), null, t, null) );
- tabbedPane.addTab("Abilities", null, abilitiesTab, "Racial and Class Abilities, Feats, etc.");
- tabbedPane.addTab("Skills", null, skillTab, null);
- tabbedPane.addTab("Gear & Items", null, equipmentTab, null);
- }
- private void saveAs(final JFileChooser fc) {
- int rv = fc.showSaveDialog(this);
- if ( rv == JFileChooser.APPROVE_OPTION ) {
- currentlyOpenFile = fc.getSelectedFile();
- saveModelResource();
- }
- }
- @SneakyThrows
- private void loadModelResource(File selectedFile) {
- currentlyOpenFile = selectedFile;
- setModel(mapper.readValue(selectedFile, DDCharacter.class));
- }
-
- @SneakyThrows
- private void saveModelResource() {
- if ( currentlyOpenFile != null ) {
- mapper.writeValue(currentlyOpenFile, model);
- }
- }
-
- private void setModel(DDCharacter model) {
- classTabs.clear();
- this.model = model;
- summaryTab.setModel(model);
- model.getClasses().stream().forEach(cc -> classTabs.add(new ClassTab(model, cc)));
- equipmentTab.setModel(model);
- skillTab.setModel(model);
- developerMenu.setModel(model);
-
- reorderTabs();
- }
- }
|