D20Sheet.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. package org.leumasjaffe.charsheet.view;
  2. import javax.swing.JFileChooser;
  3. import javax.swing.JFrame;
  4. import javax.swing.JTabbedPane;
  5. import com.fasterxml.jackson.databind.ObjectMapper;
  6. import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
  7. import lombok.AccessLevel;
  8. import lombok.NonNull;
  9. import lombok.SneakyThrows;
  10. import lombok.experimental.FieldDefaults;
  11. import lombok.experimental.NonFinal;
  12. import java.awt.BorderLayout;
  13. import javax.swing.JPanel;
  14. import javax.swing.JMenuBar;
  15. import javax.swing.JMenu;
  16. import javax.swing.JMenuItem;
  17. import javax.swing.KeyStroke;
  18. import javax.swing.UIManager;
  19. import org.leumasjaffe.charsheet.model.DDCharacter;
  20. import org.leumasjaffe.charsheet.view.dev.DeveloperMenu;
  21. import java.awt.event.KeyEvent;
  22. import java.awt.event.WindowEvent;
  23. import java.io.File;
  24. import java.util.ArrayList;
  25. import java.util.List;
  26. import java.awt.event.InputEvent;
  27. @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
  28. public class D20Sheet extends JFrame {
  29. /**
  30. *
  31. */
  32. private static final long serialVersionUID = 1L;
  33. ObjectMapper mapper = new ObjectMapper();
  34. @NonFinal File currentlyOpenFile = null;
  35. @NonFinal @NonNull DDCharacter model = new DDCharacter();
  36. JTabbedPane tabbedPane;
  37. SummaryTab summaryTab;
  38. List<ClassTab> classTabs = new ArrayList<>();
  39. JPanel abilitiesTab;
  40. SkillTab skillTab;
  41. EquipmentTab equipmentTab;
  42. private DeveloperMenu developerMenu;
  43. public D20Sheet() {
  44. UIManager.put("CheckBox.disabledText", UIManager.get("CheckBox.foreground"));
  45. // Set up local state variables
  46. final JFileChooser fc = new JFileChooser("resources");
  47. mapper.registerModule(new Jdk8Module());
  48. // Set up GUI Data (WindowBuilder)
  49. tabbedPane = new JTabbedPane(JTabbedPane.TOP);
  50. getContentPane().add(tabbedPane, BorderLayout.CENTER);
  51. summaryTab = new SummaryTab();
  52. abilitiesTab = new JPanel();
  53. skillTab = new SkillTab();
  54. equipmentTab = new EquipmentTab();
  55. JMenuBar menuBar = new JMenuBar();
  56. setJMenuBar(menuBar);
  57. JMenu mnFile = new JMenu("File");
  58. menuBar.add(mnFile);
  59. JMenuItem mntmNew = new JMenuItem("New");
  60. mntmNew.addActionListener(e -> { setModel(new DDCharacter()); });
  61. mntmNew.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
  62. mnFile.add(mntmNew);
  63. JMenuItem mntmOpen = new JMenuItem("Open");
  64. mntmOpen.addActionListener(e -> {
  65. int rv = fc.showOpenDialog(this);
  66. if ( rv == JFileChooser.APPROVE_OPTION ) {
  67. loadModelResource( fc.getSelectedFile() );
  68. tabbedPane.setSelectedIndex(0);
  69. }
  70. });
  71. mntmOpen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
  72. mnFile.add(mntmOpen);
  73. JMenuItem mntmSave = new JMenuItem("Save");
  74. mntmSave.addActionListener( e -> {
  75. if ( currentlyOpenFile == null ) { saveAs(fc); }
  76. else { saveModelResource(); }
  77. } );
  78. mntmSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
  79. mnFile.add(mntmSave);
  80. JMenuItem mntmSaveAs = new JMenuItem("Save As");
  81. mntmSaveAs.addActionListener( e -> saveAs(fc) );
  82. mntmSaveAs.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK));
  83. mnFile.add(mntmSaveAs);
  84. JMenuItem mntmExit = new JMenuItem("Exit");
  85. mntmExit.addActionListener( e -> { this.dispatchEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING)); } );
  86. mntmExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_MASK));
  87. mnFile.add(mntmExit);
  88. developerMenu = new DeveloperMenu();
  89. menuBar.add(developerMenu);
  90. // Set up post-GUI dependencies
  91. setModel(model);
  92. }
  93. public D20Sheet(final String initialFile) {
  94. this();
  95. loadModelResource(new File(initialFile));
  96. }
  97. private void reorderTabs() {
  98. this.tabbedPane.removeAll();
  99. tabbedPane.addTab("Summary", null, summaryTab, null);
  100. classTabs.forEach( t -> tabbedPane.addTab(t.getName(), null, t, null) );
  101. tabbedPane.addTab("Abilities", null, abilitiesTab, "Racial and Class Abilities, Feats, etc.");
  102. tabbedPane.addTab("Skills", null, skillTab, null);
  103. tabbedPane.addTab("Gear & Items", null, equipmentTab, null);
  104. }
  105. private void saveAs(final JFileChooser fc) {
  106. int rv = fc.showSaveDialog(this);
  107. if ( rv == JFileChooser.APPROVE_OPTION ) {
  108. currentlyOpenFile = fc.getSelectedFile();
  109. saveModelResource();
  110. }
  111. }
  112. @SneakyThrows
  113. private void loadModelResource(File selectedFile) {
  114. currentlyOpenFile = selectedFile;
  115. setModel(mapper.readValue(selectedFile, DDCharacter.class));
  116. }
  117. @SneakyThrows
  118. private void saveModelResource() {
  119. if ( currentlyOpenFile != null ) {
  120. mapper.writeValue(currentlyOpenFile, model);
  121. }
  122. }
  123. private void setModel(DDCharacter model) {
  124. classTabs.clear();
  125. this.model = model;
  126. summaryTab.setModel(model);
  127. model.getClasses().stream().forEach(cc -> classTabs.add(new ClassTab(model, cc)));
  128. equipmentTab.setModel(model);
  129. skillTab.setModel(model);
  130. developerMenu.setModel(model);
  131. reorderTabs();
  132. }
  133. }