utybo.branchingstorytree.swing.editor.StoryEditor.java Source code

Java tutorial

Introduction

Here is the source code for utybo.branchingstorytree.swing.editor.StoryEditor.java

Source

/**
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This Source Code Form is "Incompatible With Secondary Licenses", as
 * defined by the Mozilla Public License, v. 2.0.
 */
package utybo.branchingstorytree.swing.editor;

import java.awt.Component;
import java.awt.Dialog.ModalityType;
import java.awt.FileDialog;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;

import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;

import org.apache.commons.io.IOUtils;

import net.miginfocom.swing.MigLayout;
import utybo.branchingstorytree.api.BSTException;
import utybo.branchingstorytree.api.story.BranchingStory;
import utybo.branchingstorytree.swing.Icons;
import utybo.branchingstorytree.swing.Messagers;
import utybo.branchingstorytree.swing.OpenBST;
import utybo.branchingstorytree.swing.OpenBSTGUI;
import utybo.branchingstorytree.swing.utils.Lang;

@SuppressWarnings("serial")
public class StoryEditor extends JPanel implements EditorControl<BranchingStory> {
    private StoryDetailsEditor details;
    private StoryNodesEditor nodesEditor;
    private File lastFileLocation;

    public StoryEditor(BranchingStory baseStory) throws BSTException {
        setLayout(new MigLayout("hidemode 3", "[grow]", "[][grow]"));

        JToolBar toolBar = new JToolBar();
        toolBar.setBorder(null);
        toolBar.setFloatable(false);
        add(toolBar, "cell 0 0,growx");

        JButton btnSaveAs = new JButton(Lang.get("saveas"), new ImageIcon(Icons.getImage("Save As", 16)));
        btnSaveAs.addActionListener(e -> {
            saveAs();
        });
        toolBar.add(btnSaveAs);

        JButton btnSave = new JButton(Lang.get("save"), new ImageIcon(Icons.getImage("Save", 16)));
        btnSave.addActionListener(e -> {
            save();
        });
        toolBar.add(btnSave);

        JButton btnPlay = new JButton(Lang.get("play"), new ImageIcon(Icons.getImage("Circled Play", 16)));
        btnPlay.addActionListener(ev -> {
            try {
                String s = exportToString();
                File f = Files.createTempDirectory("openbst").toFile();
                File bstFile = new File(f, "expoted.bst");
                try (FileOutputStream fos = new FileOutputStream(bstFile);) {
                    IOUtils.write(s, fos, StandardCharsets.UTF_8);
                }
                OpenBSTGUI.getInstance().openStory(bstFile);
            } catch (Exception e) {
                OpenBST.LOG.error("Export failed", e);
                Messagers.showException(OpenBSTGUI.getInstance(), Lang.get("editor.exportfail"), e);
            }
        });
        toolBar.add(btnPlay);

        JButton btnFilePreview = new JButton(Lang.get("editor.exportpreview"),
                new ImageIcon(Icons.getImage("PreviewText", 16)));
        btnFilePreview.addActionListener(e -> {
            try {
                String s = exportToString();
                JDialog dialog = new JDialog(OpenBSTGUI.getInstance(), Lang.get("editor.exportpreview"));
                JTextArea jta = new JTextArea(s);
                jta.setLineWrap(true);
                jta.setWrapStyleWord(true);
                dialog.add(new JScrollPane(jta));

                dialog.setModalityType(ModalityType.APPLICATION_MODAL);
                dialog.setSize((int) (Icons.getScale() * 350), (int) (Icons.getScale() * 300));
                dialog.setLocationRelativeTo(OpenBSTGUI.getInstance());
                dialog.setVisible(true);
            } catch (Exception x) {
                OpenBST.LOG.error("Failed to preview", x);
                Messagers.showException(OpenBSTGUI.getInstance(), Lang.get("editor.previewerror"), x);
            }
        });
        toolBar.add(btnFilePreview);

        Component horizontalGlue = Box.createHorizontalGlue();
        toolBar.add(horizontalGlue);

        JButton btnClose = new JButton(Lang.get("close"), new ImageIcon(Icons.getImage("Cancel", 16)));
        btnClose.addActionListener(e -> {
            askClose();
        });
        toolBar.add(btnClose);

        for (final Component component : toolBar.getComponents()) {
            if (component instanceof JButton) {
                ((JButton) component).setHideActionText(false);
                ((JButton) component).setToolTipText(((JButton) component).getText());
                ((JButton) component).setText("");
            }
        }

        JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
        tabbedPane.setTabPlacement(JTabbedPane.LEFT);
        add(tabbedPane, "cell 0 1,grow");

        tabbedPane.addTab("Beta Warning", new StoryEditorWelcomeScreen());

        details = new StoryDetailsEditor(this);
        tabbedPane.addTab(Lang.get("editor.details"), details);

        nodesEditor = new StoryNodesEditor();
        tabbedPane.addTab(Lang.get("editor.nodes"), nodesEditor);

        this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("control S"),
                "doSave");
        this.getActionMap().put("doSave", new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                save();
            }
        });

        importFrom(baseStory);
    }

    public boolean askClose() {
        int i = Messagers.showConfirm(OpenBSTGUI.getInstance(), Lang.get("editor.asksave"),
                Messagers.OPTIONS_YES_NO_CANCEL, Messagers.TYPE_WARNING, Lang.get("editor.asksave.title"));
        if (i == Messagers.OPTION_YES) {
            if (save()) {
                OpenBSTGUI.getInstance().removeTab(this);
                return true;
            }
        } else if (i == Messagers.OPTION_NO) {
            OpenBSTGUI.getInstance().removeTab(this);
            return true;
        } else
            return false;
        return false;
    }

    @Override
    public void importFrom(BranchingStory from) throws BSTException {
        details.importFrom(from.getTagMap());
        nodesEditor.importFrom(from.getAllNodes());
    }

    @Override
    public BranchingStory exportToObject() {
        return null;
    }

    @Override
    public String exportToString() throws BSTException {
        StringBuilder sb = new StringBuilder();
        sb.append("# OpenBST Editor Export\n");
        sb.append(details.exportToString());
        sb.append("\n\n");
        sb.append(nodesEditor.exportToString());

        return sb.toString();
    }

    public boolean save() {
        if (lastFileLocation == null) {
            return saveAs();
        } else {
            try {
                return doSave(lastFileLocation);
            } catch (IOException | BSTException e1) {
                OpenBST.LOG.error("Failed saving a file", e1);
                Messagers.showException(OpenBSTGUI.getInstance(), Lang.get("editor.savefail"), e1);
            }
        }
        return false;
    }

    private boolean doSave(File f) throws IOException, BSTException {
        try (FileOutputStream fos = new FileOutputStream(f)) {
            IOUtils.write(exportToString(), fos, StandardCharsets.UTF_8);
            return true;
        }
    }

    public boolean saveAs() {
        FileDialog fd = new FileDialog(OpenBSTGUI.getInstance(), Lang.get("editor.saveloc"), FileDialog.SAVE);
        fd.setLocationRelativeTo(OpenBSTGUI.getInstance());
        fd.setVisible(true);
        if (fd.getFile() != null) {
            final File file = new File(fd.getFile().endsWith(".bst") ? fd.getDirectory() + fd.getFile()
                    : fd.getDirectory() + fd.getFile() + ".bst");
            try {
                doSave(file);
                lastFileLocation = file;
                return true;
            } catch (IOException | BSTException e1) {
                OpenBST.LOG.error("Failed saving a file", e1);
                Messagers.showException(OpenBSTGUI.getInstance(), Lang.get("editor.savefail"), e1);
            }
        }
        return false;
    }

    public void updateTabTitle() {
        OpenBSTGUI.getInstance().setTabName(this, getTitle());
    }

    public String getTitle() {
        return Lang.get("editor.title").replace("$t", details.getTitle()).replace("$a", details.getAuthor());
    }
}