diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..519c3ac
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+/target/
+/ffmpeg/
+/release/
+
+nbactions.xml
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..7a99caf
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,75 @@
+
+
+ 4.0.0
+ club.tmworks
+ telopeditor
+ 1.0
+ jar
+
+
+ javax.json
+ javax.json-api
+ 1.1
+
+
+ com.tmworks
+ lyricsmovie
+ 1.0.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.6
+
+
+ jar-with-dependencies
+
+
+
+ club.tmworks.telopeditor.EditorFrame
+
+
+
+
+
+ package
+
+ single
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.4
+
+
+
+ club.tmworks.telopeditor.EditorFrame
+
+
+
+
+
+
+
+ UTF-8
+ 11
+ 11
+
+
+
+ gitbucket-maven-repository-releases
+ https://gitbucket.tmworks.club/maven/releases/
+
+
+ gitbucket-maven-repository-snapshots
+ https://gitbucket.tmworks.club/maven/snapshots
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/club/tmworks/io/JsonIO.java b/src/main/java/club/tmworks/io/JsonIO.java
new file mode 100644
index 0000000..5fd7bad
--- /dev/null
+++ b/src/main/java/club/tmworks/io/JsonIO.java
@@ -0,0 +1,80 @@
+package club.tmworks.io;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+import org.json.JSONObject;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class JsonIO {
+
+ public static JsonObject loadJson(String loadFileName) {
+ JsonObject rvalue = null;
+ try {
+ File f = new File(loadFileName);
+ FileInputStream fis = new FileInputStream(f);
+ InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
+ BufferedReader br = new BufferedReader(isr);
+
+ String jsonSrc = "";
+ String line = "";
+ while ((line = br.readLine()) != null) {
+ jsonSrc += line;
+ }
+
+ JsonReader jsonReader = Json.createReader(new StringReader(jsonSrc));
+ rvalue = jsonReader.readObject();
+ return rvalue;
+ } catch (FileNotFoundException ex) {
+ Logger.getLogger(JsonIO.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (UnsupportedEncodingException ex) {
+ Logger.getLogger(JsonIO.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (IOException ex) {
+ Logger.getLogger(JsonIO.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ return rvalue;
+ }
+
+ public static void saveJsonFile(String fielFullPath, JsonObject src) {
+ JSONObject jobj = new JSONObject(src.toString());
+ String midStr = jobj.toString(4);
+
+ String mediafilepath = fielFullPath;
+ try (PrintWriter pw = new PrintWriter(
+ new BufferedWriter(
+ new OutputStreamWriter(
+ new FileOutputStream(mediafilepath), "UTF-8")
+ )
+ )) {
+ pw.print(midStr);
+ pw.flush();
+ } catch (UnsupportedEncodingException | FileNotFoundException ex) {
+ Logger.getLogger(JsonIO.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ }
+
+ public static String getString(JsonObject src) {
+ JSONObject jobj = new JSONObject(src.toString());
+ String midStr = jobj.toString(4);
+ return midStr;
+ }
+
+}
diff --git a/src/main/java/club/tmworks/io/TextFile.java b/src/main/java/club/tmworks/io/TextFile.java
new file mode 100644
index 0000000..1ef44f9
--- /dev/null
+++ b/src/main/java/club/tmworks/io/TextFile.java
@@ -0,0 +1,80 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.io;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class TextFile {
+
+ public static String load(String path) {
+ String rvalue = "";
+ FileInputStream fis = null;
+ try {
+ File f = new File(path);
+ fis = new FileInputStream(f);
+ InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
+ BufferedReader br = new BufferedReader(isr);
+ String line;
+ while ((line = br.readLine()) != null) {
+ rvalue += line + "\n";
+ }
+ } catch (FileNotFoundException ex) {
+ Logger.getLogger(TextFile.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (IOException ex) {
+ Logger.getLogger(TextFile.class.getName()).log(Level.SEVERE, null, ex);
+ } finally {
+ try {
+ if (fis != null) {
+ fis.close();
+ }
+ } catch (IOException ex) {
+ Logger.getLogger(TextFile.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ }
+ return rvalue;
+ }
+
+ public static void save(String path, String data) {
+ OutputStreamWriter osw = null;
+ try {
+ File f = new File(path);
+ FileOutputStream fos = new FileOutputStream(f);
+ osw = new OutputStreamWriter(fos, "UTF-8");
+ BufferedWriter bw = new BufferedWriter(osw);
+ bw.write(data);
+ bw.flush();
+ } catch (UnsupportedEncodingException | FileNotFoundException ex) {
+ Logger.getLogger(TextFile.class.getName()).log(Level.SEVERE, null, ex);
+ } catch (IOException ex) {
+ Logger.getLogger(TextFile.class.getName()).log(Level.SEVERE, null, ex);
+ } finally {
+ try {
+ if (osw != null) {
+ osw.close();
+ }
+ } catch (IOException ex) {
+ Logger.getLogger(TextFile.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ }
+}
diff --git a/src/main/java/club/tmworks/telopeditor/EditorFrame.form b/src/main/java/club/tmworks/telopeditor/EditorFrame.form
new file mode 100644
index 0000000..02dbab0
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/EditorFrame.form
@@ -0,0 +1,551 @@
+
+
+
diff --git a/src/main/java/club/tmworks/telopeditor/EditorFrame.java b/src/main/java/club/tmworks/telopeditor/EditorFrame.java
new file mode 100644
index 0000000..407ecfa
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/EditorFrame.java
@@ -0,0 +1,812 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor;
+
+import club.tmworks.io.JsonIO;
+import club.tmworks.io.TextFile;
+import club.tmworks.lyricsmovie.Generator;
+import club.tmworks.telopeditor.generators.SimpleMkvGenerator;
+import club.tmworks.telopeditor.model.ApplicationSetting;
+import club.tmworks.telopeditor.model.DialogCodes;
+import club.tmworks.telopeditor.model.FlexibleFileFilter;
+import club.tmworks.telopeditor.model.ProjectInfo;
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.swing.ImageIcon;
+import javax.swing.JFileChooser;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class EditorFrame extends javax.swing.JFrame {
+
+ private ProjectInfo currentProject;
+
+ private ApplicationSetting applicationSetting = new ApplicationSetting();
+
+ private String applicationName = "Telop Editor";
+
+ private String applicationSettingFile = "appsetting.json";
+
+ private Generator main;
+
+ /**
+ * Creates new form EditorFrame
+ */
+ public EditorFrame() {
+ initComponents();
+ this.loadApplicationSetting();
+ this.setIconImage(new ImageIcon(this.getClass().getResource("/icons8-カチンコ-16.png")).getImage());
+ this.setTitle();
+
+ // 一旦開発対象から外す
+ this.jPanel8.setVisible(false);
+
+ this.phoneticEditor.setCaption("MusicXml抽出");
+ this.telopEditor.setCaption("歌詞");
+
+ this.setLocationRelativeTo(null);
+
+ this.main = new Generator();
+ }
+
+ private void loadApplicationSetting() {
+ File f = new File(this.applicationSettingFile);
+ if (f.exists()) {
+ JsonObject setting = JsonIO.loadJson(this.applicationSettingFile);
+ this.applicationSetting.getRoot(setting);
+ this.applicationSetting.set(ApplicationSetting.CURRENT_PROJECT, "");
+ }
+ }
+
+ private void saveApplicationSetting() {
+ JsonIO.saveJsonFile(this.applicationSettingFile, this.applicationSetting.getRoot());
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jPanel7 = new javax.swing.JPanel();
+ jPanel2 = new javax.swing.JPanel();
+ jPanel3 = new javax.swing.JPanel();
+ phoneticEditor = new club.tmworks.telopeditor.EitPane();
+ jPanel4 = new javax.swing.JPanel();
+ telopEditor = new club.tmworks.telopeditor.EitPane();
+ jPanel8 = new javax.swing.JPanel();
+ jPanel10 = new javax.swing.JPanel();
+ jSplitPane1 = new javax.swing.JSplitPane();
+ jPanel9 = new javax.swing.JPanel();
+ jSplitPane2 = new javax.swing.JSplitPane();
+ imageView2 = new club.tmworks.telopeditor.ImageView();
+ jToolBar1 = new javax.swing.JToolBar();
+ btnNewProject = new javax.swing.JButton();
+ jButton2 = new javax.swing.JButton();
+ btnOverWrite = new javax.swing.JButton();
+ jSeparator1 = new javax.swing.JToolBar.Separator();
+ jButton4 = new javax.swing.JButton();
+ btnRegenerate = new javax.swing.JButton();
+ jSeparator2 = new javax.swing.JToolBar.Separator();
+ btnBuildMkv = new javax.swing.JButton();
+ jSeparator4 = new javax.swing.JToolBar.Separator();
+ btnSetting = new javax.swing.JButton();
+ jPanel1 = new javax.swing.JPanel();
+ jPanel5 = new javax.swing.JPanel();
+ jLabel2 = new javax.swing.JLabel();
+ lblProjectName = new javax.swing.JLabel();
+ jPanel6 = new javax.swing.JPanel();
+ jLabel3 = new javax.swing.JLabel();
+ progress = new javax.swing.JProgressBar();
+ msgLabel = new javax.swing.JLabel();
+ jMenuBar1 = new javax.swing.JMenuBar();
+ jMenu1 = new javax.swing.JMenu();
+ menuNewProject = new javax.swing.JMenuItem();
+ jMenu3 = new javax.swing.JMenu();
+ mnuOpenProject = new javax.swing.JMenuItem();
+ mnuLoadLyrics = new javax.swing.JMenuItem();
+ mnuOverwriteProject = new javax.swing.JMenuItem();
+ mnuSaveAs = new javax.swing.JMenuItem();
+ mnuQuit = new javax.swing.JMenuItem();
+ jMenu2 = new javax.swing.JMenu();
+ mnuGetPhonetics = new javax.swing.JMenuItem();
+ mnuRegenerate = new javax.swing.JMenuItem();
+ mnuBuildMkv = new javax.swing.JMenuItem();
+ jSeparator3 = new javax.swing.JPopupMenu.Separator();
+ mnuEditProject = new javax.swing.JMenuItem();
+ jMenuItem10 = new javax.swing.JMenuItem();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ setTitle("Lyrics Movie");
+ setPreferredSize(new java.awt.Dimension(880, 720));
+
+ jPanel7.setLayout(new javax.swing.BoxLayout(jPanel7, javax.swing.BoxLayout.LINE_AXIS));
+
+ jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.LINE_AXIS));
+
+ jPanel3.setLayout(new javax.swing.BoxLayout(jPanel3, javax.swing.BoxLayout.PAGE_AXIS));
+
+ phoneticEditor.setCaption(new java.io.File("C:\\ide\\NetBeans-11.2\\\"CAPTION\""));
+ phoneticEditor.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jPanel3.add(phoneticEditor);
+
+ jPanel2.add(jPanel3);
+
+ jPanel4.setLayout(new javax.swing.BoxLayout(jPanel4, javax.swing.BoxLayout.PAGE_AXIS));
+
+ telopEditor.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jPanel4.add(telopEditor);
+
+ jPanel2.add(jPanel4);
+
+ jPanel8.setLayout(new java.awt.BorderLayout());
+
+ jPanel10.setLayout(new java.awt.BorderLayout());
+ jPanel8.add(jPanel10, java.awt.BorderLayout.NORTH);
+
+ jSplitPane1.setBorder(null);
+ jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
+
+ jPanel9.setLayout(new java.awt.BorderLayout());
+
+ jSplitPane2.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
+
+ imageView2.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jSplitPane2.setTopComponent(imageView2);
+
+ jPanel9.add(jSplitPane2, java.awt.BorderLayout.PAGE_END);
+
+ jSplitPane1.setTopComponent(jPanel9);
+
+ jPanel8.add(jSplitPane1, java.awt.BorderLayout.CENTER);
+
+ jPanel2.add(jPanel8);
+
+ jPanel7.add(jPanel2);
+
+ getContentPane().add(jPanel7, java.awt.BorderLayout.CENTER);
+
+ jToolBar1.setRollover(true);
+
+ btnNewProject.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnNewProject.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-新規作成-32.png"))); // NOI18N
+ btnNewProject.setText("新規作成");
+ btnNewProject.setToolTipText("");
+ btnNewProject.setFocusable(false);
+ btnNewProject.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnNewProject.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnNewProject.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ menuNewProjectActionPerformed(evt);
+ }
+ });
+ jToolBar1.add(btnNewProject);
+
+ jButton2.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jButton2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-フォルダーを開く-32.png"))); // NOI18N
+ jButton2.setText("開く");
+ jButton2.setFocusable(false);
+ jButton2.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ jButton2.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ jButton2.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuOpenProjectActionPerformed(evt);
+ }
+ });
+ jToolBar1.add(jButton2);
+
+ btnOverWrite.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnOverWrite.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-セーブ-32.png"))); // NOI18N
+ btnOverWrite.setText("上書保存");
+ btnOverWrite.setFocusable(false);
+ btnOverWrite.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnOverWrite.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnOverWrite.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuOverwriteProjectActionPerformed(evt);
+ }
+ });
+ jToolBar1.add(btnOverWrite);
+ jToolBar1.add(jSeparator1);
+
+ jButton4.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jButton4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-空フィルター-32.png"))); // NOI18N
+ jButton4.setText("抽出");
+ jButton4.setFocusable(false);
+ jButton4.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ jButton4.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ jButton4.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuGetPhoneticsActionPerformed(evt);
+ }
+ });
+ jToolBar1.add(jButton4);
+
+ btnRegenerate.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnRegenerate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-スナイパー-32.png"))); // NOI18N
+ btnRegenerate.setText("照合");
+ btnRegenerate.setToolTipText("ひらがなと歌詞を照合します。");
+ btnRegenerate.setFocusable(false);
+ btnRegenerate.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnRegenerate.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnRegenerate.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuRegenerateActionPerformed(evt);
+ }
+ });
+ jToolBar1.add(btnRegenerate);
+ jToolBar1.add(jSeparator2);
+
+ btnBuildMkv.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnBuildMkv.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-再生-32.png"))); // NOI18N
+ btnBuildMkv.setText("MKV生成");
+ btnBuildMkv.setFocusable(false);
+ btnBuildMkv.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnBuildMkv.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnBuildMkv.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuBuildMkvActionPerformed(evt);
+ }
+ });
+ jToolBar1.add(btnBuildMkv);
+ jToolBar1.add(jSeparator4);
+
+ btnSetting.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnSetting.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-設定-32.png"))); // NOI18N
+ btnSetting.setText("設定");
+ btnSetting.setFocusable(false);
+ btnSetting.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ btnSetting.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
+ btnSetting.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ jMenuItem10ActionPerformed(evt);
+ }
+ });
+ jToolBar1.add(btnSetting);
+
+ getContentPane().add(jToolBar1, java.awt.BorderLayout.PAGE_START);
+
+ jPanel1.setLayout(new java.awt.BorderLayout());
+
+ jLabel2.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jLabel2.setText("プロジェクト");
+ jPanel5.add(jLabel2);
+
+ lblProjectName.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ lblProjectName.setText("未設定");
+ jPanel5.add(lblProjectName);
+
+ jPanel1.add(jPanel5, java.awt.BorderLayout.WEST);
+
+ jLabel3.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jLabel3.setText("進行");
+ jPanel6.add(jLabel3);
+ jPanel6.add(progress);
+
+ jPanel1.add(jPanel6, java.awt.BorderLayout.EAST);
+
+ msgLabel.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ msgLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ msgLabel.setToolTipText("");
+ msgLabel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
+ jPanel1.add(msgLabel, java.awt.BorderLayout.CENTER);
+
+ getContentPane().add(jPanel1, java.awt.BorderLayout.PAGE_END);
+
+ jMenu1.setMnemonic('F');
+ jMenu1.setText("ファイル(F)");
+ jMenu1.setToolTipText("");
+ jMenu1.setFont(new java.awt.Font("Yu Gothic UI", 0, 14)); // NOI18N
+
+ menuNewProject.setFont(new java.awt.Font("Yu Gothic UI", 0, 14)); // NOI18N
+ menuNewProject.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-新規作成-16.png"))); // NOI18N
+ menuNewProject.setMnemonic('N');
+ menuNewProject.setText("新規プロジェクト(N)");
+ menuNewProject.setToolTipText("");
+ menuNewProject.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ menuNewProjectActionPerformed(evt);
+ }
+ });
+ jMenu1.add(menuNewProject);
+
+ jMenu3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-フォルダーを開く-16.png"))); // NOI18N
+ jMenu3.setMnemonic('O');
+ jMenu3.setText("開く(O)");
+
+ mnuOpenProject.setFont(new java.awt.Font("Yu Gothic UI", 0, 14)); // NOI18N
+ mnuOpenProject.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-フォルダーを開く-16.png"))); // NOI18N
+ mnuOpenProject.setMnemonic('O');
+ mnuOpenProject.setText("プロジェクトを開く(O)");
+ mnuOpenProject.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuOpenProjectActionPerformed(evt);
+ }
+ });
+ jMenu3.add(mnuOpenProject);
+
+ mnuLoadLyrics.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-フォルダーを開く-16.png"))); // NOI18N
+ mnuLoadLyrics.setMnemonic('L');
+ mnuLoadLyrics.setText("歌詞を読み込む(L)");
+ mnuLoadLyrics.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuLoadLyricsActionPerformed(evt);
+ }
+ });
+ jMenu3.add(mnuLoadLyrics);
+
+ jMenu1.add(jMenu3);
+
+ mnuOverwriteProject.setFont(new java.awt.Font("Yu Gothic UI", 0, 14)); // NOI18N
+ mnuOverwriteProject.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-セーブ-16.png"))); // NOI18N
+ mnuOverwriteProject.setMnemonic('W');
+ mnuOverwriteProject.setText("上書き保存(W)");
+ mnuOverwriteProject.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuOverwriteProjectActionPerformed(evt);
+ }
+ });
+ jMenu1.add(mnuOverwriteProject);
+
+ mnuSaveAs.setFont(new java.awt.Font("Yu Gothic UI", 0, 14)); // NOI18N
+ mnuSaveAs.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-名前を付けて保存-16.png"))); // NOI18N
+ mnuSaveAs.setMnemonic('S');
+ mnuSaveAs.setText("名前を付けて保存(S)");
+ mnuSaveAs.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuSaveAsActionPerformed(evt);
+ }
+ });
+ jMenu1.add(mnuSaveAs);
+
+ mnuQuit.setFont(new java.awt.Font("Yu Gothic UI", 0, 14)); // NOI18N
+ mnuQuit.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-シャットダウン-16.png"))); // NOI18N
+ mnuQuit.setMnemonic('X');
+ mnuQuit.setText("終了(X)");
+ mnuQuit.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuQuitActionPerformed(evt);
+ }
+ });
+ jMenu1.add(mnuQuit);
+
+ jMenuBar1.add(jMenu1);
+
+ jMenu2.setMnemonic('E');
+ jMenu2.setText("編集(E)");
+ jMenu2.setFont(new java.awt.Font("Yu Gothic UI", 0, 14)); // NOI18N
+
+ mnuGetPhonetics.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-空フィルター-16.png"))); // NOI18N
+ mnuGetPhonetics.setText("ひらがなを抽出");
+ mnuGetPhonetics.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuGetPhoneticsActionPerformed(evt);
+ }
+ });
+ jMenu2.add(mnuGetPhonetics);
+
+ mnuRegenerate.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-スナイパー-16.png"))); // NOI18N
+ mnuRegenerate.setText("歌詞と照合");
+ mnuRegenerate.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuRegenerateActionPerformed(evt);
+ }
+ });
+ jMenu2.add(mnuRegenerate);
+
+ mnuBuildMkv.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-再生-16.png"))); // NOI18N
+ mnuBuildMkv.setText("MKV生成");
+ mnuBuildMkv.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuBuildMkvActionPerformed(evt);
+ }
+ });
+ jMenu2.add(mnuBuildMkv);
+ jMenu2.add(jSeparator3);
+
+ mnuEditProject.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-映画-16.png"))); // NOI18N
+ mnuEditProject.setText("プロジェクト");
+ mnuEditProject.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ mnuEditProjectActionPerformed(evt);
+ }
+ });
+ jMenu2.add(mnuEditProject);
+
+ jMenuItem10.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-設定-16.png"))); // NOI18N
+ jMenuItem10.setText("設定");
+ jMenuItem10.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ jMenuItem10ActionPerformed(evt);
+ }
+ });
+ jMenu2.add(jMenuItem10);
+
+ jMenuBar1.add(jMenu2);
+
+ setJMenuBar(jMenuBar1);
+
+ pack();
+ }// //GEN-END:initComponents
+
+ private void mnuBuildMkvActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuBuildMkvActionPerformed
+
+ if (this.currentProject == null) {
+ return;
+ }
+
+ if (this.currentProject.getJsonObject(ProjectInfo.TELOP_INFO) == null) {
+ return;
+ }
+
+ SimpleMkvGenerator thread = new SimpleMkvGenerator(
+ this.applicationSetting,
+ this.currentProject,
+ this.msgLabel,
+ this.progress,
+ this.btnBuildMkv,
+ this.mnuBuildMkv
+ );
+ thread.start();
+
+ }//GEN-LAST:event_mnuBuildMkvActionPerformed
+
+ private void menuNewProjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuNewProjectActionPerformed
+
+ ProjectInfoEditor piEditor = new ProjectInfoEditor(this, true);
+
+ piEditor.setVisible(true);
+ if (piEditor.getDialogResult() == DialogCodes.DIALOG_OK) {
+ ProjectInfo pi = piEditor.getProjectInfo();
+ System.out.println(JsonIO.getString(pi.getRoot()));
+ this.currentProject = pi;
+ if (this.applicationSetting.getString(ApplicationSetting.CURRENT_PROJECT) != null) {
+ this.applicationSetting.set(
+ ApplicationSetting.LAST_PROJECT,
+ this.applicationSetting.getString(ApplicationSetting.CURRENT_PROJECT)
+ );
+ }
+ this.applicationSetting.set(ApplicationSetting.CURRENT_PROJECT, "");
+ this.phoneticEditor.setText("");
+ this.telopEditor.setText("");
+ this.showProjectInfo();
+
+ this.mnuSaveAsActionPerformed(evt);
+
+ this.msgLabel.setText("プロジェクトを作成しました");
+ }
+
+ }//GEN-LAST:event_menuNewProjectActionPerformed
+
+ private void jMenuItem10ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem10ActionPerformed
+
+ Setting setting = new Setting(this, true);
+ setting.setApplicationSetting(this.applicationSetting);
+ setting.setVisible(true);
+ if (setting.getDialogResult() == DialogCodes.DIALOG_OK) {
+ this.applicationSetting = setting.getApplicationSetting();
+ this.saveApplicationSetting();
+ }
+
+ }//GEN-LAST:event_jMenuItem10ActionPerformed
+
+ private void mnuOverwriteProjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuOverwriteProjectActionPerformed
+
+ if (this.currentProject == null) {
+ this.msgLabel.setText("まだプロジェクトが作られていません。");
+ return;
+ }
+
+ this.savePhonetic();
+ String currentPath = this.applicationSetting.getString(ApplicationSetting.CURRENT_PROJECT);
+ if (currentPath.equals("")) {
+ this.mnuSaveAsActionPerformed(evt);
+ } else {
+ this.saveProjectFile();
+ this.msgLabel.setText("保存完了");
+ }
+
+ }//GEN-LAST:event_mnuOverwriteProjectActionPerformed
+
+ private void mnuSaveAsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuSaveAsActionPerformed
+
+ if (this.currentProject == null) {
+ return;
+ }
+
+ String fileName = "";
+ if (!this.applicationSetting.getString(ApplicationSetting.CURRENT_PROJECT).equals("")) {
+ fileName = this.applicationSetting.getString(ApplicationSetting.CURRENT_PROJECT);
+ } else {
+ Path path = Paths.get("");
+ fileName = path.toAbsolutePath().toString();
+ }
+ JFileChooser fc = new JFileChooser();
+ fc.setCurrentDirectory(new File(fileName));
+ fc.setFileFilter(new FlexibleFileFilter(new String[]{".project.json"}, "プロジェクトファイル"));
+ fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ if (fc.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
+ String path = fc.getSelectedFile().getAbsolutePath();
+ if (!path.endsWith(".project.json")) {
+ path += ".project.json";
+ }
+ this.applicationSetting.set(ApplicationSetting.CURRENT_PROJECT, path);
+ this.saveProjectFile();
+ this.msgLabel.setText("保存完了");
+ }
+
+ }//GEN-LAST:event_mnuSaveAsActionPerformed
+
+ /**
+ * プロジェクトファイルの保存
+ */
+ private void saveProjectFile() {
+ // 歌詞をJsonに格納する
+ String lyrics = this.telopEditor.getText();
+ if (lyrics.trim().length() > 0) {
+ JsonArray lyricsArray = Json.createArrayBuilder().build();
+ String[] lines = lyrics.split("\n");
+ for (String line : lines) {
+ lyricsArray = Json.createArrayBuilder(lyricsArray)
+ .add(line).build();
+ }
+ this.currentProject.set(ProjectInfo.LYRICS, lyricsArray);
+ }
+ String currentPath = this.applicationSetting.getString(ApplicationSetting.CURRENT_PROJECT);
+ JsonIO.saveJsonFile(currentPath, this.currentProject.getRoot());
+ }
+
+ private void mnuEditProjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuEditProjectActionPerformed
+
+ if (this.currentProject != null) {
+ ProjectInfoEditor pinfo = new ProjectInfoEditor(this, true);
+ pinfo.setProjectInfo(this.currentProject);
+ pinfo.setVisible(true);
+ if (pinfo.getDialogResult() == DialogCodes.DIALOG_OK) {
+ this.currentProject = pinfo.getProjectInfo();
+ this.showProjectInfo();
+ }
+ }
+
+ }//GEN-LAST:event_mnuEditProjectActionPerformed
+
+ private void mnuOpenProjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuOpenProjectActionPerformed
+ String fileName;
+ if (!this.applicationSetting.getString(ApplicationSetting.CURRENT_PROJECT).equals("")) {
+ fileName = this.applicationSetting.getString(ApplicationSetting.CURRENT_PROJECT);
+ } else {
+ Path path = Paths.get("");
+ fileName = path.toAbsolutePath().toString();
+ }
+
+ JFileChooser fc = new JFileChooser();
+ fc.setFileFilter(new FlexibleFileFilter(new String[]{".project.json"}, "プロジェクトファイル"));
+ fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ fc.setCurrentDirectory(new File(fileName));
+ if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
+ String path = fc.getSelectedFile().getAbsolutePath();
+ JsonObject data = JsonIO.loadJson(path);
+ if (this.currentProject == null) {
+ this.currentProject = new ProjectInfo();
+ }
+ this.currentProject.getRoot(data);
+ this.applicationSetting.set(ApplicationSetting.CURRENT_PROJECT, path);
+ this.showProjectInfo();
+
+ String workdir = this.currentProject.getString(ProjectInfo.PROJECT_WORKING_DIR);
+ if (!(new File(workdir)).exists()) {
+ this.msgLabel.setText("作業フォルダが存在しません。");
+ this.mnuEditProjectActionPerformed(null);
+ }
+ }
+
+ }//GEN-LAST:event_mnuOpenProjectActionPerformed
+
+ private void mnuQuitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuQuitActionPerformed
+
+ String currentProjectFile = this.applicationSetting.getString(ApplicationSetting.CURRENT_PROJECT);
+ if (currentProjectFile.length() > 0) {
+ this.applicationSetting.set(ApplicationSetting.LAST_PROJECT, currentProjectFile);
+ this.saveApplicationSetting();
+ }
+ System.exit(0);
+ }//GEN-LAST:event_mnuQuitActionPerformed
+
+ private void mnuGetPhoneticsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuGetPhoneticsActionPerformed
+
+ if (this.currentProject != null) {
+ String targetSrc = this.currentProject.getMusicXmlFile(0);
+ String workingDir = this.currentProject.getString(ProjectInfo.PROJECT_WORKING_DIR);
+ String cmd = "-w %WORKDIR% -i %SRC% %FFMPEG% %BIND% -smart";
+ cmd = cmd.replace("%WORKDIR%", this.currentProject.getString(ProjectInfo.PROJECT_WORKING_DIR));
+ cmd = cmd.replace("%SRC%", targetSrc);
+ cmd = cmd.replace("%FFMPEG%", "-ffmpeg png2mov.cmd");
+ cmd = cmd.replace("%BIND%", "-bind bindmov.cmd");
+
+ main.loadArgs(cmd.split(" "));
+ main.execute();
+
+ String jsonmid02 = targetSrc.replace(".musicxml", ".json");
+ JsonArray arraymid02 = JsonIO.loadJson(workingDir + File.separator + jsonmid02).getJsonArray("NOTES");
+ String lyric = "";
+ for (int i = 0; i < arraymid02.size(); i++) {
+ String line = arraymid02.getJsonObject(i).getString("lyric");
+ if (line.length() < 1) {
+ line = "{空白}";
+ }
+ lyric += line + "\n";
+ }
+ this.savePhonetic();
+ this.phoneticEditor.setText(lyric);
+ this.msgLabel.setText("抽出完了");
+ }
+
+ }//GEN-LAST:event_mnuGetPhoneticsActionPerformed
+
+ private void mnuLoadLyricsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuLoadLyricsActionPerformed
+
+ JFileChooser fc = new JFileChooser();
+ fc.setFileFilter(new FlexibleFileFilter(new String[]{".txt"}, "歌詞データ"));
+ fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ fc.setCurrentDirectory(Paths.get("").toAbsolutePath().toFile());
+ if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
+ String text = TextFile.load(fc.getSelectedFile().getAbsolutePath());
+ this.telopEditor.setText(text);
+ }
+ }//GEN-LAST:event_mnuLoadLyricsActionPerformed
+
+ private void mnuRegenerateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuRegenerateActionPerformed
+
+ // assert
+ if (this.phoneticEditor.getText().trim().length() < 1
+ || this.telopEditor.getText().trim().length() < 1) {
+ return;
+ }
+ if (this.phoneticEditor.getText().trim().split("\n").length != this.telopEditor.getText().trim().split("\n").length) {
+ this.msgLabel.setText("左右の行数が異なるので、照合出来ません。");
+ return;
+ }
+
+ MoviePlan moviePlan = new MoviePlan(this.currentProject);
+ this.currentProject = moviePlan.reGenerate();
+ this.msgLabel.setText("照合完了");
+
+ }//GEN-LAST:event_mnuRegenerateActionPerformed
+
+ private void savePhonetic() {
+ String ptext = this.phoneticEditor.getText();
+ String[] plines = ptext.split("\n");
+ JsonArray arrayPhonetic = Json.createArrayBuilder().build();
+ for (int i = 0; i < plines.length; i++) {
+ String line = plines[i];
+ arrayPhonetic = Json.createArrayBuilder(arrayPhonetic).add(i, line).build();
+ }
+ this.currentProject.set(ProjectInfo.PHONETIC, arrayPhonetic);
+ }
+
+ private void showProjectInfo() {
+ this.lblProjectName.setText(this.currentProject.getString(ProjectInfo.PROJECT_NAME));
+ this.setTitle();
+ JsonArray phonetic = this.currentProject.getJsonArray(ProjectInfo.PHONETIC);
+ if (phonetic != null) {
+ this.phoneticEditor.setText(this.getJsonArrayToText(phonetic));
+ }
+ JsonArray lyrics = this.currentProject.getJsonArray(ProjectInfo.LYRICS);
+ if (lyrics != null) {
+ this.telopEditor.setText(this.getJsonArrayToText(lyrics));
+ }
+ }
+
+ private String getJsonArrayToText(JsonArray array) {
+ String rvalue = "";
+ for (int i = 0; i < array.size(); i++) {
+ String line = array.getString(i);
+ rvalue += line + "\n";
+ }
+ return rvalue;
+ }
+
+ private void setTitle() {
+ String title = this.applicationName;
+ if (this.currentProject != null) {
+ title += " - " + this.currentProject.getString(ProjectInfo.PROJECT_NAME);
+ }
+ this.setTitle(title);
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String args[]) {
+ /* Set the Nimbus look and feel */
+ //
+ /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
+ * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
+ */
+ try {
+ for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
+ if ("Windows".equals(info.getName())) {
+ javax.swing.UIManager.setLookAndFeel(info.getClassName());
+ break;
+ }
+ }
+ } catch (ClassNotFoundException
+ | InstantiationException
+ | IllegalAccessException
+ | javax.swing.UnsupportedLookAndFeelException ex) {
+ java.util.logging.Logger.getLogger(EditorFrame.class
+ .getName()).log(java.util.logging.Level.SEVERE, null, ex);
+ }
+ //
+
+
+ /* Create and display the form */
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ new EditorFrame().setVisible(true);
+ }
+ });
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnBuildMkv;
+ private javax.swing.JButton btnNewProject;
+ private javax.swing.JButton btnOverWrite;
+ private javax.swing.JButton btnRegenerate;
+ private javax.swing.JButton btnSetting;
+ private club.tmworks.telopeditor.ImageView imageView2;
+ private javax.swing.JButton jButton2;
+ private javax.swing.JButton jButton4;
+ private javax.swing.JLabel jLabel2;
+ private javax.swing.JLabel jLabel3;
+ private javax.swing.JMenu jMenu1;
+ private javax.swing.JMenu jMenu2;
+ private javax.swing.JMenu jMenu3;
+ private javax.swing.JMenuBar jMenuBar1;
+ private javax.swing.JMenuItem jMenuItem10;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel10;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JPanel jPanel3;
+ private javax.swing.JPanel jPanel4;
+ private javax.swing.JPanel jPanel5;
+ private javax.swing.JPanel jPanel6;
+ private javax.swing.JPanel jPanel7;
+ private javax.swing.JPanel jPanel8;
+ private javax.swing.JPanel jPanel9;
+ private javax.swing.JToolBar.Separator jSeparator1;
+ private javax.swing.JToolBar.Separator jSeparator2;
+ private javax.swing.JPopupMenu.Separator jSeparator3;
+ private javax.swing.JToolBar.Separator jSeparator4;
+ private javax.swing.JSplitPane jSplitPane1;
+ private javax.swing.JSplitPane jSplitPane2;
+ private javax.swing.JToolBar jToolBar1;
+ private javax.swing.JLabel lblProjectName;
+ private javax.swing.JMenuItem menuNewProject;
+ private javax.swing.JMenuItem mnuBuildMkv;
+ private javax.swing.JMenuItem mnuEditProject;
+ private javax.swing.JMenuItem mnuGetPhonetics;
+ private javax.swing.JMenuItem mnuLoadLyrics;
+ private javax.swing.JMenuItem mnuOpenProject;
+ private javax.swing.JMenuItem mnuOverwriteProject;
+ private javax.swing.JMenuItem mnuQuit;
+ private javax.swing.JMenuItem mnuRegenerate;
+ private javax.swing.JMenuItem mnuSaveAs;
+ private javax.swing.JLabel msgLabel;
+ private club.tmworks.telopeditor.EitPane phoneticEditor;
+ private javax.swing.JProgressBar progress;
+ private club.tmworks.telopeditor.EitPane telopEditor;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/src/main/java/club/tmworks/telopeditor/EitPane.form b/src/main/java/club/tmworks/telopeditor/EitPane.form
new file mode 100644
index 0000000..81d1c13
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/EitPane.form
@@ -0,0 +1,74 @@
+
+
+
diff --git a/src/main/java/club/tmworks/telopeditor/EitPane.java b/src/main/java/club/tmworks/telopeditor/EitPane.java
new file mode 100644
index 0000000..17792f0
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/EitPane.java
@@ -0,0 +1,96 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor;
+
+import club.tmworks.io.TextFile;
+import java.io.File;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class EitPane extends javax.swing.JPanel {
+
+ String filePath = "";
+
+ /**
+ * Creates new form EitPane
+ */
+ public EitPane() {
+ initComponents();
+ this.setCaption("EDIT PANE");
+ }
+
+ public void loadFile(String filePath) {
+ this.filePath = filePath;
+ String data = TextFile.load(this.filePath);
+ this.setText(data);
+
+ File f = new File(this.filePath);
+ String name = f.getName();
+ this.lblCaption.setText(name);
+ }
+
+ public void setCaption(File file) {
+ String name = file.getName();
+ this.setCaption(filePath);
+ }
+
+ public void setCaption(String caption) {
+ this.lblCaption.setText(caption);
+ }
+
+ public void setText(String data) {
+ this.jTextArea1.setText(data);
+ }
+
+ public String getText() {
+ return this.jTextArea1.getText();
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jPanel1 = new javax.swing.JPanel();
+ lblCaption = new javax.swing.JLabel();
+ jScrollPane1 = new javax.swing.JScrollPane();
+ jTextArea1 = new javax.swing.JTextArea();
+
+ setLayout(new java.awt.BorderLayout());
+
+ jPanel1.setBackground(java.awt.SystemColor.windowBorder);
+ jPanel1.setForeground(java.awt.SystemColor.text);
+
+ lblCaption.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ lblCaption.setForeground(new java.awt.Color(255, 255, 255));
+ lblCaption.setText("jLabel1");
+ jPanel1.add(lblCaption);
+ lblCaption.getAccessibleContext().setAccessibleName("caption");
+
+ add(jPanel1, java.awt.BorderLayout.NORTH);
+
+ jTextArea1.setColumns(20);
+ jTextArea1.setFont(new java.awt.Font("Monospaced", 0, 14)); // NOI18N
+ jTextArea1.setLineWrap(true);
+ jTextArea1.setRows(5);
+ jScrollPane1.setViewportView(jTextArea1);
+
+ add(jScrollPane1, java.awt.BorderLayout.CENTER);
+ }// //GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JTextArea jTextArea1;
+ private javax.swing.JLabel lblCaption;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/src/main/java/club/tmworks/telopeditor/ImageView.form b/src/main/java/club/tmworks/telopeditor/ImageView.form
new file mode 100644
index 0000000..8424edb
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/ImageView.form
@@ -0,0 +1,69 @@
+
+
+
diff --git a/src/main/java/club/tmworks/telopeditor/ImageView.java b/src/main/java/club/tmworks/telopeditor/ImageView.java
new file mode 100644
index 0000000..68c8a20
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/ImageView.java
@@ -0,0 +1,69 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class ImageView extends javax.swing.JPanel {
+
+ /**
+ * Creates new form ImageView
+ */
+ public ImageView() {
+ initComponents();
+ }
+
+ public void setCaption(String caption) {
+
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jPanel1 = new javax.swing.JPanel();
+ lblCaption = new javax.swing.JLabel();
+ jPanel2 = new javax.swing.JPanel();
+
+ setLayout(new java.awt.BorderLayout());
+
+ jPanel1.setBackground(java.awt.SystemColor.windowBorder);
+
+ lblCaption.setForeground(new java.awt.Color(255, 255, 255));
+ lblCaption.setText("イメージビュー");
+ jPanel1.add(lblCaption);
+
+ add(jPanel1, java.awt.BorderLayout.NORTH);
+
+ jPanel2.setPreferredSize(new java.awt.Dimension(300, 200));
+
+ javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
+ jPanel2.setLayout(jPanel2Layout);
+ jPanel2Layout.setHorizontalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 400, Short.MAX_VALUE)
+ );
+ jPanel2Layout.setVerticalGroup(
+ jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 277, Short.MAX_VALUE)
+ );
+
+ add(jPanel2, java.awt.BorderLayout.CENTER);
+ }// //GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JLabel lblCaption;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/src/main/java/club/tmworks/telopeditor/MoviePlan.java b/src/main/java/club/tmworks/telopeditor/MoviePlan.java
new file mode 100644
index 0000000..a72a9c2
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/MoviePlan.java
@@ -0,0 +1,123 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor;
+
+import club.tmworks.io.JsonIO;
+import club.tmworks.lyricsmovie.Note;
+import club.tmworks.telopeditor.model.ProjectInfo;
+import java.io.File;
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class MoviePlan {
+
+ private ProjectInfo info;
+
+ private double tempo = 0d;
+ private double baseLength = 0d;
+
+ public MoviePlan(ProjectInfo project) {
+ this.info = project;
+ }
+
+ public ProjectInfo reGenerate() {
+ JsonObject midObject = this.getMidObject();
+ this.baseLength = Double.valueOf(midObject.getString("base_length"));
+ this.tempo = Double.valueOf(midObject.getString("tempo"));
+
+ JsonArray notes = midObject.getJsonArray("NOTES");
+ JsonArray notesDst = Json.createArrayBuilder().build();
+
+ JsonArray phonetic = this.info.getJsonArray(ProjectInfo.PHONETIC);
+ JsonArray lyrics = this.info.getJsonArray(ProjectInfo.LYRICS);
+
+ int offset = 0;
+ String fileBase = this.info.getJsonArray(ProjectInfo.PROJECT_MUSICXML_FILES).getString(0);
+ fileBase = (new File(fileBase)).getName().replace(".musicxml", "");
+
+ for (int i = 0; i < phonetic.size(); i++) {
+ String p = phonetic.getString(i);
+ String l = lyrics.getString(i);
+ if (p.equals("{空白}")) {
+ p = "";
+ }
+ if (l.equals("{空白}")) {
+ l = "";
+ }
+
+ String bindbuffer = "";
+
+ Note dstNote = new Note(notes.getJsonObject(offset));
+ for (int j = offset + 1; j < notes.size(); j++) {
+ boolean margeable = false;
+
+ Note srcNote = new Note(notes.getJsonObject(j));
+
+ // 結合結果がpに含まれるならマージ
+ if (p.contains(dstNote.getString(Note.LYRIC) + srcNote.getString(Note.LYRIC))) {
+ margeable = true;
+ }
+
+ // pが空なら空以外は結合出来ない
+ if (p.length() < 1 && srcNote.getString(Note.LYRIC).length() > 0) {
+ margeable = false;
+ }
+
+ // pと結合結果が一致していたら空欄は結合できない
+ if (p.equals(dstNote.getString(Note.LYRIC)) && srcNote.getString(Note.LYRIC).length() < 1) {
+ margeable = false;
+ }
+
+ // pもsrcも空なら結合できる(上の条件の例外)
+ if (p.length() < 1 && srcNote.getString(Note.LYRIC).length() < 1) {
+ margeable = true;
+ }
+
+ if (margeable) {
+ dstNote = dstNote.marge(dstNote, srcNote);
+ } else {
+ offset = j;
+ break;
+ }
+ }
+
+ dstNote.set(Note.CAPTION, l);
+ dstNote.set("imagefile", fileBase + String.format("-%03d.png", i));
+ notesDst = Json.createArrayBuilder(notesDst).add(dstNote).build();
+ }
+
+ JsonObject dstObject = Json.createObjectBuilder().add("NOTES", notesDst).build();
+ dstObject = Json.createObjectBuilder(dstObject).add("tempo", this.tempo).build();
+ this.info.set(ProjectInfo.TELOP_INFO, dstObject);
+ String srcFileName = this.info.getJsonArray(ProjectInfo.PROJECT_MUSICXML_FILES)
+ .getString(0);
+ String dstFileName = (new File(srcFileName)).getName().replace(".musicxml", ".json.txt");
+ JsonIO.saveJsonFile(dstFileName, dstObject);
+ return this.info;
+ }
+
+ private JsonObject getMidObject() {
+ return JsonIO.loadJson(
+ this.info.getString(ProjectInfo.PROJECT_WORKING_DIR)
+ + File.separator
+ + this.getMidSrc()
+ );
+ }
+
+ private String getMidSrc() {
+ String rvalue = "";
+ String musicxml = info.getJsonArray(ProjectInfo.PROJECT_MUSICXML_FILES)
+ .getString(0);
+ rvalue = musicxml.replace(".musicxml", ".mid01.json");
+ return rvalue;
+ }
+
+}
diff --git a/src/main/java/club/tmworks/telopeditor/ProjectInfoEditor.form b/src/main/java/club/tmworks/telopeditor/ProjectInfoEditor.form
new file mode 100644
index 0000000..652d2fb
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/ProjectInfoEditor.form
@@ -0,0 +1,493 @@
+
+
+
diff --git a/src/main/java/club/tmworks/telopeditor/ProjectInfoEditor.java b/src/main/java/club/tmworks/telopeditor/ProjectInfoEditor.java
new file mode 100644
index 0000000..50b8e5f
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/ProjectInfoEditor.java
@@ -0,0 +1,748 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor;
+
+import club.tmworks.telopeditor.model.DialogCodes;
+import club.tmworks.telopeditor.model.FlexibleFileFilter;
+import club.tmworks.telopeditor.model.ProjectInfo;
+import com.tmworks.telopgenerator.PngGenerator;
+import java.awt.Font;
+import java.awt.GraphicsEnvironment;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.ButtonGroup;
+import javax.swing.JFileChooser;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class ProjectInfoEditor extends javax.swing.JDialog {
+
+ private ProjectInfo pinfo = null;
+
+ private int dialogResult = DialogCodes.DIALOG_CANCEL;
+
+ private String fontSampleText = "あアア漢AaAa";
+
+ private String fontName = "";
+
+ /**
+ * Creates new form ProjectInfoEditor
+ *
+ * @param parent
+ * @param modal
+ */
+ public ProjectInfoEditor(java.awt.Frame parent, boolean modal) {
+ super(parent, modal);
+ initComponents();
+
+ ButtonGroup verticalGroup = new ButtonGroup();
+ verticalGroup.add(this.btnTop);
+ verticalGroup.add(this.btnMiddle);
+ verticalGroup.add(this.btnBottom);
+
+ ButtonGroup horizontalGroup = new ButtonGroup();
+ horizontalGroup.add(this.btnLeft);
+ horizontalGroup.add(this.btnCenter);
+ horizontalGroup.add(this.btnRight);
+
+ this.setLocationRelativeTo(parent);
+ this.pinfo = new ProjectInfo();
+
+ this.showUsableFonts();
+ this.showFontSize();
+ this.showFontLocation();
+ this.showSample();
+ }
+
+ private void showFontLocation() {
+ String vertical = this.pinfo.getString(ProjectInfo.LOCATION_VERTICAL);
+ if (vertical == null) {
+ vertical = ProjectInfo.VERTICAL_CENTER;
+ this.pinfo.set(ProjectInfo.LOCATION_VERTICAL, ProjectInfo.VERTICAL_CENTER);
+ }
+ switch (vertical) {
+ case ProjectInfo.VERTICAL_TOP:
+ this.btnTop.setSelected(true);
+ break;
+ case ProjectInfo.VERTICAL_CENTER:
+ this.btnMiddle.setSelected(true);
+ break;
+ case ProjectInfo.VERTICAL_BOTTOM:
+ this.btnBottom.setSelected(true);
+ break;
+ }
+
+ String horizontal = this.pinfo.getString(ProjectInfo.LOCATION_HORIZONTAL);
+ if (horizontal == null) {
+ horizontal = ProjectInfo.HORIZONTAL_CENTER;
+ this.pinfo.set(ProjectInfo.LOCATION_HORIZONTAL, ProjectInfo.HORIZONTAL_CENTER);
+ }
+ switch (horizontal) {
+ case ProjectInfo.HORIZONTAL_LEFT:
+ this.btnLeft.setSelected(true);
+ break;
+ case ProjectInfo.HORIZONTAL_CENTER:
+ this.btnCenter.setSelected(true);
+ break;
+ case ProjectInfo.HORIZOTAL_RIGHT:
+ this.btnRight.setSelected(true);
+ break;
+ }
+ }
+
+ private void showUsableFonts() {
+ GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ Font[] fonts = env.getAllFonts();
+ for (Font f : fonts) {
+ this.fontSelecter.addItem(f.getName());
+ }
+
+ // フォントの初期化
+ if (this.pinfo.getString(ProjectInfo.FONT_NAME) == null) {
+ this.fontName = this.getFont().getName() + ".plain";
+ } else {
+ this.fontName = this.pinfo.getString(ProjectInfo.FONT_NAME);
+ }
+ this.fontSelecter.setSelectedItem(this.fontName);
+
+ boolean fontInitialized = false;
+ if (this.pinfo != null) {
+ if (this.pinfo.getString(ProjectInfo.FONT_SIZE) != null) {
+ fontInitialized = true;
+ this.txtFontSize.setText(this.pinfo.getString(ProjectInfo.FONT_SIZE));
+ this.txtFontSize.setText(this.pinfo.getString(ProjectInfo.SHADING_SIZE));
+ }
+ }
+ if (!fontInitialized) {
+ this.txtFontSize.setText("96");
+ this.pinfo.set(ProjectInfo.FONT_SIZE, this.txtFontSize.getText());
+ this.txtShadingSize.setText("30");
+ this.pinfo.set(ProjectInfo.SHADING_SIZE, this.txtShadingSize.getText());
+ }
+ }
+
+ private void setFontName(String fontName) {
+ this.fontName = fontName;
+ this.fontSelecter.setSelectedItem(this.fontName);
+ this.pinfo.set(ProjectInfo.FONT_NAME, this.fontName);
+ this.showSample();
+ }
+
+ public void setProjectInfo(ProjectInfo info) {
+ this.pinfo = info;
+ if (info != null) {
+ this.txtProjectName.setText(this.pinfo.getString(ProjectInfo.PROJECT_NAME));
+ this.txtWorkingPath.setText(this.pinfo.getString(ProjectInfo.PROJECT_WORKING_DIR));
+ if (this.pinfo.getMusicXmlFiles().size() > 0) {
+ this.txtMusicXmlFile.setText(this.pinfo.getMusicXmlFile(0));
+ }
+ this.setFontName(this.pinfo.getString(ProjectInfo.FONT_NAME));
+ this.showFontSize();
+ this.showFontLocation();
+ }
+ }
+
+ private void showFontSize() {
+ boolean fontInitialized = false;
+ if (this.pinfo != null) {
+ if (this.pinfo.getString(ProjectInfo.FONT_SIZE) != null) {
+ fontInitialized = true;
+ this.txtFontSize.setText(this.pinfo.getString(ProjectInfo.FONT_SIZE));
+ this.txtShadingSize.setText(this.pinfo.getString(ProjectInfo.SHADING_SIZE));
+ }
+ }
+ if (!fontInitialized) {
+ this.txtFontSize.setText("96");
+ this.pinfo.set(ProjectInfo.FONT_SIZE, this.txtFontSize.getText());
+ this.txtShadingSize.setText("30");
+ this.pinfo.set(ProjectInfo.SHADING_SIZE, this.txtShadingSize.getText());
+ }
+ }
+
+ public void showSample() {
+ PngGenerator pg = new PngGenerator();
+ pg.setFontName(this.fontName);
+ pg.setSize(this.fontSampleView.getWidth(), this.fontSampleView.getHeight());
+ pg.setLocation(ProjectInfo.VERTICAL_CENTER, ProjectInfo.HORIZONTAL_CENTER);
+ pg.setFontSize(Integer.valueOf(this.txtFontSize.getText()));
+ pg.setShadingSize(Integer.valueOf(this.txtShadingSize.getText()));
+ BufferedImage img = pg.getTelopImage(this.fontSampleText);
+ this.fontSampleView.setImage(img);
+ this.fontSampleView.repaint();
+ }
+
+ public ProjectInfo getProjectInfo() {
+ return this.pinfo;
+ }
+
+ public int getDialogResult() {
+ return this.dialogResult;
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jLabel1 = new javax.swing.JLabel();
+ txtProjectName = new javax.swing.JTextField();
+ jLabel2 = new javax.swing.JLabel();
+ txtWorkingPath = new javax.swing.JTextField();
+ btnSelectWorkingFolder = new javax.swing.JButton();
+ jLabel3 = new javax.swing.JLabel();
+ txtMusicXmlFile = new javax.swing.JTextField();
+ btnSelectMusicXml = new javax.swing.JToggleButton();
+ btnOK = new javax.swing.JToggleButton();
+ btnCancel = new javax.swing.JButton();
+ lblMessage = new javax.swing.JLabel();
+ jLabel4 = new javax.swing.JLabel();
+ fontSelecter = new javax.swing.JComboBox<>();
+ fontSampleView = new club.tmworks.telopeditor.fontSampleView();
+ jPanel1 = new javax.swing.JPanel();
+ jLabel5 = new javax.swing.JLabel();
+ txtFontSize = new javax.swing.JTextField();
+ btnFontSizeUp = new javax.swing.JButton();
+ btnFontSizeDown = new javax.swing.JButton();
+ jLabel7 = new javax.swing.JLabel();
+ btnTop = new javax.swing.JToggleButton();
+ btnMiddle = new javax.swing.JToggleButton();
+ btnBottom = new javax.swing.JToggleButton();
+ jPanel2 = new javax.swing.JPanel();
+ jLabel6 = new javax.swing.JLabel();
+ txtShadingSize = new javax.swing.JTextField();
+ btnShadingSizeUp = new javax.swing.JButton();
+ btnShadingSizeDown = new javax.swing.JButton();
+ jLabel8 = new javax.swing.JLabel();
+ btnLeft = new javax.swing.JToggleButton();
+ btnCenter = new javax.swing.JToggleButton();
+ btnRight = new javax.swing.JToggleButton();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setTitle("プロジェクト情報");
+ setResizable(false);
+
+ jLabel1.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jLabel1.setText("プロジェクト名");
+ jLabel1.setPreferredSize(new java.awt.Dimension(94, 14));
+
+ txtProjectName.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ txtProjectName.setText("新規プロジェクト");
+ txtProjectName.setName(""); // NOI18N
+
+ jLabel2.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jLabel2.setText("作業フォルダ");
+ jLabel2.setPreferredSize(new java.awt.Dimension(94, 14));
+
+ txtWorkingPath.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+
+ btnSelectWorkingFolder.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnSelectWorkingFolder.setText("...");
+ btnSelectWorkingFolder.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnSelectWorkingFolderActionPerformed(evt);
+ }
+ });
+
+ jLabel3.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jLabel3.setText("MusicXmlファイル");
+
+ txtMusicXmlFile.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+
+ btnSelectMusicXml.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnSelectMusicXml.setText("jToggleButton1");
+ btnSelectMusicXml.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnSelectMusicXmlActionPerformed(evt);
+ }
+ });
+
+ btnOK.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnOK.setText("OK");
+ btnOK.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnOKActionPerformed(evt);
+ }
+ });
+
+ btnCancel.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnCancel.setText("キャンセル");
+ btnCancel.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnCancelActionPerformed(evt);
+ }
+ });
+
+ jLabel4.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jLabel4.setText("フォント");
+
+ fontSelecter.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ fontSelecterActionPerformed(evt);
+ }
+ });
+
+ fontSampleView.setBackground(new java.awt.Color(0, 153, 51));
+ fontSampleView.setBorder(javax.swing.BorderFactory.createEtchedBorder());
+
+ javax.swing.GroupLayout fontSampleViewLayout = new javax.swing.GroupLayout(fontSampleView);
+ fontSampleView.setLayout(fontSampleViewLayout);
+ fontSampleViewLayout.setHorizontalGroup(
+ fontSampleViewLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 0, Short.MAX_VALUE)
+ );
+ fontSampleViewLayout.setVerticalGroup(
+ fontSampleViewLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 151, Short.MAX_VALUE)
+ );
+
+ jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));
+
+ jLabel5.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jLabel5.setText("文字サイズ");
+ jPanel1.add(jLabel5);
+
+ txtFontSize.setColumns(5);
+ txtFontSize.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ txtFontSize.setHorizontalAlignment(javax.swing.JTextField.CENTER);
+ txtFontSize.setText("000");
+ txtFontSize.setMargin(new java.awt.Insets(2, 7, 2, 7));
+ txtFontSize.setMinimumSize(new java.awt.Dimension(100, 20));
+ txtFontSize.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ txtFontSizeActionPerformed(evt);
+ }
+ });
+ jPanel1.add(txtFontSize);
+
+ btnFontSizeUp.setText("▲");
+ btnFontSizeUp.setMargin(new java.awt.Insets(2, 0, 2, 0));
+ btnFontSizeUp.setPreferredSize(new java.awt.Dimension(21, 21));
+ btnFontSizeUp.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnFontSizeUpActionPerformed(evt);
+ }
+ });
+ jPanel1.add(btnFontSizeUp);
+
+ btnFontSizeDown.setText("▼");
+ btnFontSizeDown.setMargin(new java.awt.Insets(2, 0, 2, 0));
+ btnFontSizeDown.setPreferredSize(new java.awt.Dimension(21, 21));
+ btnFontSizeDown.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnFontSizeDownActionPerformed(evt);
+ }
+ });
+ jPanel1.add(btnFontSizeDown);
+
+ jLabel7.setText("垂直位置");
+ jPanel1.add(jLabel7);
+
+ btnTop.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-テキストを上揃え-16.png"))); // NOI18N
+ btnTop.setIconTextGap(0);
+ btnTop.setPreferredSize(new java.awt.Dimension(32, 21));
+ btnTop.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnTopActionPerformed(evt);
+ }
+ });
+ jPanel1.add(btnTop);
+
+ btnMiddle.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-テキストを中央に揃える-16.png"))); // NOI18N
+ btnMiddle.setIconTextGap(0);
+ btnMiddle.setPreferredSize(new java.awt.Dimension(32, 21));
+ btnMiddle.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnMiddleActionPerformed(evt);
+ }
+ });
+ jPanel1.add(btnMiddle);
+
+ btnBottom.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-テキストを下揃え-16.png"))); // NOI18N
+ btnBottom.setIconTextGap(0);
+ btnBottom.setPreferredSize(new java.awt.Dimension(32, 21));
+ btnBottom.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnBottomActionPerformed(evt);
+ }
+ });
+ jPanel1.add(btnBottom);
+
+ jPanel2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));
+
+ jLabel6.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jLabel6.setText("影の幅");
+ jLabel6.setPreferredSize(new java.awt.Dimension(61, 14));
+ jPanel2.add(jLabel6);
+
+ txtShadingSize.setColumns(5);
+ txtShadingSize.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ txtShadingSize.setHorizontalAlignment(javax.swing.JTextField.CENTER);
+ txtShadingSize.setText("000");
+ txtShadingSize.setToolTipText("");
+ txtShadingSize.setMargin(new java.awt.Insets(2, 7, 2, 7));
+ txtShadingSize.setMinimumSize(new java.awt.Dimension(71, 20));
+ txtShadingSize.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ txtShadingSizeActionPerformed(evt);
+ }
+ });
+ jPanel2.add(txtShadingSize);
+
+ btnShadingSizeUp.setLabel("▲");
+ btnShadingSizeUp.setMargin(new java.awt.Insets(2, 0, 2, 0));
+ btnShadingSizeUp.setPreferredSize(new java.awt.Dimension(21, 21));
+ btnShadingSizeUp.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnShadingSizeUpActionPerformed(evt);
+ }
+ });
+ jPanel2.add(btnShadingSizeUp);
+
+ btnShadingSizeDown.setText("▼");
+ btnShadingSizeDown.setMargin(new java.awt.Insets(2, 0, 2, 0));
+ btnShadingSizeDown.setPreferredSize(new java.awt.Dimension(21, 21));
+ btnShadingSizeDown.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnShadingSizeDownActionPerformed(evt);
+ }
+ });
+ jPanel2.add(btnShadingSizeDown);
+
+ jLabel8.setText("水平位置");
+ jPanel2.add(jLabel8);
+
+ btnLeft.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-左揃え-16.png"))); // NOI18N
+ btnLeft.setPreferredSize(new java.awt.Dimension(32, 21));
+ btnLeft.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnLeftActionPerformed(evt);
+ }
+ });
+ jPanel2.add(btnLeft);
+
+ btnCenter.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-中央揃え-16.png"))); // NOI18N
+ btnCenter.setPreferredSize(new java.awt.Dimension(32, 21));
+ btnCenter.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnCenterActionPerformed(evt);
+ }
+ });
+ jPanel2.add(btnCenter);
+
+ btnRight.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons8-右揃え-16.png"))); // NOI18N
+ btnRight.setPreferredSize(new java.awt.Dimension(32, 21));
+ btnRight.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnRightActionPerformed(evt);
+ }
+ });
+ jPanel2.add(btnRight);
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(32, 32, 32)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 461, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(0, 0, Short.MAX_VALUE))
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 461, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap(25, Short.MAX_VALUE))
+ .addGroup(layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(fontSampleView, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
+ .addComponent(lblMessage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGap(56, 56, 56)
+ .addComponent(btnOK)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnCancel))
+ .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
+ .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(txtProjectName, javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(txtMusicXmlFile, javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(txtWorkingPath, javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(fontSelecter, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(btnSelectWorkingFolder, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(btnSelectMusicXml, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE))))
+ .addGap(19, 19, 19))))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(32, 32, 32)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(txtProjectName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(txtWorkingPath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(btnSelectWorkingFolder))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(jLabel3)
+ .addComponent(txtMusicXmlFile, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(btnSelectMusicXml))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(fontSelecter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(jLabel4))
+ .addGap(18, 18, 18)
+ .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(fontSampleView, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(lblMessage, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(27, 27, 27))
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(btnOK)
+ .addComponent(btnCancel))
+ .addContainerGap())))
+ );
+
+ pack();
+ }// //GEN-END:initComponents
+
+ private void btnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnOKActionPerformed
+
+ if (this.txtProjectName.getText().length() < 1) {
+ this.lblMessage.setText("プロジェクト名は必須です。");
+ return;
+ }
+ if (this.txtWorkingPath.getText().length() < 1) {
+ this.lblMessage.setText("作業フォルダは必須です。");
+ return;
+ }
+ if (this.txtMusicXmlFile.getText().length() < 1) {
+ this.lblMessage.setText("MusicXmlファイルは必須です。");
+ return;
+ }
+
+ if (this.pinfo == null) {
+ this.pinfo = new ProjectInfo();
+ }
+
+ this.pinfo.set(ProjectInfo.PROJECT_NAME, this.txtProjectName.getText().trim());
+ this.pinfo.set(ProjectInfo.PROJECT_WORKING_DIR, this.txtWorkingPath.getText().trim());
+ this.pinfo.addMusicXmlFile(this.txtMusicXmlFile.getText());
+
+ if (this.fmusicxml != null) {
+ if (!this.fmusicxml.getParent().equals(this.pinfo.getString(ProjectInfo.PROJECT_WORKING_DIR))) {
+ try {
+ Path dst = (new File(this.pinfo.getString(ProjectInfo.PROJECT_WORKING_DIR) + File.separator + fmusicxml.getName())).toPath();
+ Files.copy(fmusicxml.toPath(), dst, StandardCopyOption.REPLACE_EXISTING);
+ } catch (IOException ex) {
+ Logger.getLogger(ProjectInfoEditor.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ }
+ this.pinfo.set(ProjectInfo.FONT_NAME, this.fontName);
+
+ this.dialogResult = DialogCodes.DIALOG_OK;
+ this.setVisible(false);
+
+ }//GEN-LAST:event_btnOKActionPerformed
+
+ private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
+
+ this.pinfo = null;
+ this.dialogResult = DialogCodes.DIALOG_CANCEL;
+ this.setVisible(false);
+
+ }//GEN-LAST:event_btnCancelActionPerformed
+
+ private void btnSelectWorkingFolderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSelectWorkingFolderActionPerformed
+ JFileChooser fc = new JFileChooser();
+ fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ if (this.pinfo.getString(ProjectInfo.PROJECT_WORKING_DIR) != null) {
+ fc.setCurrentDirectory(new File(this.pinfo.getString(ProjectInfo.PROJECT_WORKING_DIR)));
+ } else {
+ Path path = Paths.get("");
+ fc.setCurrentDirectory(path.toAbsolutePath().toFile());
+ }
+ if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
+ String path = fc.getSelectedFile().getAbsolutePath();
+ this.txtWorkingPath.setText(path);
+ }
+ }//GEN-LAST:event_btnSelectWorkingFolderActionPerformed
+
+ File fmusicxml = null;
+ private void btnSelectMusicXmlActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSelectMusicXmlActionPerformed
+ JFileChooser fc = new JFileChooser();
+ fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ fc.setFileFilter(new FlexibleFileFilter(new String[]{".musicxml"}, "MusicXmlファイル"));
+ if (this.pinfo.getMusicXmlFiles().size() > 0) {
+ fc.setCurrentDirectory(new File(this.pinfo.getMusicXmlFile(0)));
+ } else {
+ Path path = Paths.get("");
+ fc.setCurrentDirectory(path.toAbsolutePath().toFile());
+ }
+ if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
+ String path = fc.getSelectedFile().getName();
+ fmusicxml = fc.getSelectedFile();
+ this.txtMusicXmlFile.setText(path);
+
+ }
+ }//GEN-LAST:event_btnSelectMusicXmlActionPerformed
+
+ private void fontSelecterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fontSelecterActionPerformed
+
+ this.fontName = (String) this.fontSelecter.getSelectedItem();
+ if (this.isVisible()) {
+ this.showSample();
+ }
+
+ }//GEN-LAST:event_fontSelecterActionPerformed
+
+ private void btnFontSizeUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFontSizeUpActionPerformed
+
+ String currSize = this.txtFontSize.getText();
+ int fontsize = Integer.valueOf(currSize);
+ fontsize += 1;
+ this.txtFontSize.setText(String.valueOf(fontsize));
+ this.showSample();
+
+ }//GEN-LAST:event_btnFontSizeUpActionPerformed
+
+ private void btnFontSizeDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnFontSizeDownActionPerformed
+
+ int fontsize = Integer.valueOf(this.txtFontSize.getText());
+ fontsize -= 1;
+ if (fontsize < 10) {
+ fontsize = 10;
+ }
+ this.txtFontSize.setText(String.valueOf(fontsize));
+ this.showSample();
+
+ }//GEN-LAST:event_btnFontSizeDownActionPerformed
+
+ private void txtFontSizeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtFontSizeActionPerformed
+
+ if (this.txtFontSize.getText().length() > 0) {
+ this.showSample();
+ }
+
+ }//GEN-LAST:event_txtFontSizeActionPerformed
+
+ private void txtShadingSizeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_txtShadingSizeActionPerformed
+
+ if (this.txtShadingSize.getText().length() > 0) {
+ this.showSample();
+ }
+
+ }//GEN-LAST:event_txtShadingSizeActionPerformed
+
+ private void btnShadingSizeUpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnShadingSizeUpActionPerformed
+
+ String currSize = this.txtShadingSize.getText();
+ int fontsize = Integer.valueOf(currSize);
+ fontsize += 1;
+ this.txtShadingSize.setText(String.valueOf(fontsize));
+ this.showSample();
+
+ }//GEN-LAST:event_btnShadingSizeUpActionPerformed
+
+ private void btnShadingSizeDownActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnShadingSizeDownActionPerformed
+
+ int fontsize = Integer.valueOf(this.txtShadingSize.getText());
+ fontsize -= 1;
+ if (fontsize < 10) {
+ fontsize = 10;
+ }
+ this.txtShadingSize.setText(String.valueOf(fontsize));
+ this.showSample();
+
+ }//GEN-LAST:event_btnShadingSizeDownActionPerformed
+
+ private void btnTopActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTopActionPerformed
+ this.pinfo.set(ProjectInfo.LOCATION_VERTICAL, ProjectInfo.VERTICAL_TOP);
+ }//GEN-LAST:event_btnTopActionPerformed
+
+ private void btnMiddleActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMiddleActionPerformed
+ this.pinfo.set(ProjectInfo.LOCATION_VERTICAL, ProjectInfo.VERTICAL_CENTER);
+ }//GEN-LAST:event_btnMiddleActionPerformed
+
+ private void btnBottomActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnBottomActionPerformed
+ this.pinfo.set(ProjectInfo.LOCATION_VERTICAL, ProjectInfo.VERTICAL_BOTTOM);
+ }//GEN-LAST:event_btnBottomActionPerformed
+
+ private void btnLeftActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLeftActionPerformed
+ this.pinfo.set(ProjectInfo.LOCATION_HORIZONTAL, ProjectInfo.HORIZONTAL_LEFT);
+ }//GEN-LAST:event_btnLeftActionPerformed
+
+ private void btnCenterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCenterActionPerformed
+ this.pinfo.set(ProjectInfo.LOCATION_HORIZONTAL, ProjectInfo.HORIZONTAL_CENTER);
+ }//GEN-LAST:event_btnCenterActionPerformed
+
+ private void btnRightActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRightActionPerformed
+ this.pinfo.set(ProjectInfo.LOCATION_HORIZONTAL, ProjectInfo.HORIZOTAL_RIGHT);
+ }//GEN-LAST:event_btnRightActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JToggleButton btnBottom;
+ private javax.swing.JButton btnCancel;
+ private javax.swing.JToggleButton btnCenter;
+ private javax.swing.JButton btnFontSizeDown;
+ private javax.swing.JButton btnFontSizeUp;
+ private javax.swing.JToggleButton btnLeft;
+ private javax.swing.JToggleButton btnMiddle;
+ private javax.swing.JToggleButton btnOK;
+ private javax.swing.JToggleButton btnRight;
+ private javax.swing.JToggleButton btnSelectMusicXml;
+ private javax.swing.JButton btnSelectWorkingFolder;
+ private javax.swing.JButton btnShadingSizeDown;
+ private javax.swing.JButton btnShadingSizeUp;
+ private javax.swing.JToggleButton btnTop;
+ private club.tmworks.telopeditor.fontSampleView fontSampleView;
+ private javax.swing.JComboBox fontSelecter;
+ private javax.swing.JLabel jLabel1;
+ private javax.swing.JLabel jLabel2;
+ private javax.swing.JLabel jLabel3;
+ private javax.swing.JLabel jLabel4;
+ private javax.swing.JLabel jLabel5;
+ private javax.swing.JLabel jLabel6;
+ private javax.swing.JLabel jLabel7;
+ private javax.swing.JLabel jLabel8;
+ private javax.swing.JPanel jPanel1;
+ private javax.swing.JPanel jPanel2;
+ private javax.swing.JLabel lblMessage;
+ private javax.swing.JTextField txtFontSize;
+ private javax.swing.JTextField txtMusicXmlFile;
+ private javax.swing.JTextField txtProjectName;
+ private javax.swing.JTextField txtShadingSize;
+ private javax.swing.JTextField txtWorkingPath;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/src/main/java/club/tmworks/telopeditor/Setting.form b/src/main/java/club/tmworks/telopeditor/Setting.form
new file mode 100644
index 0000000..d485414
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/Setting.form
@@ -0,0 +1,115 @@
+
+
+
diff --git a/src/main/java/club/tmworks/telopeditor/Setting.java b/src/main/java/club/tmworks/telopeditor/Setting.java
new file mode 100644
index 0000000..a543a28
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/Setting.java
@@ -0,0 +1,179 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor;
+
+import club.tmworks.telopeditor.model.ApplicationSetting;
+import club.tmworks.telopeditor.model.DialogCodes;
+import java.io.File;
+import java.nio.file.Paths;
+import javax.swing.ImageIcon;
+import javax.swing.JFileChooser;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class Setting extends javax.swing.JDialog {
+
+ private ApplicationSetting applicationSetting;
+
+ private int dialogResult = DialogCodes.DIALOG_CANCEL;
+
+ /**
+ * Creates new form Setting
+ */
+ public Setting(java.awt.Frame parent, boolean modal) {
+ super(parent, modal);
+ initComponents();
+ this.applicationSetting = new ApplicationSetting();
+ this.setIconImage(new ImageIcon(this.getClass().getResource("/icons8-設定-16.png")).getImage());
+ this.setLocationRelativeTo(parent);
+
+ }
+
+ /**
+ * ApplicationSettingのデータを格納し、その中身をコンポーネントに展開
+ *
+ * @param setting
+ */
+ public void setApplicationSetting(ApplicationSetting setting) {
+ this.applicationSetting = setting;
+ this.txtFfmpegPath.setText(this.applicationSetting.getString(ApplicationSetting.FFMPEG_PATH));
+ }
+
+ public ApplicationSetting getApplicationSetting() {
+ return this.applicationSetting;
+ }
+
+ public int getDialogResult() {
+ return this.dialogResult;
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jLabel1 = new javax.swing.JLabel();
+ txtFfmpegPath = new javax.swing.JTextField();
+ btnSelectFfmpegPath = new javax.swing.JButton();
+ btnSave = new javax.swing.JButton();
+ btnCancel = new javax.swing.JButton();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setTitle("設定");
+ setIconImage(null);
+
+ jLabel1.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ jLabel1.setText("ffmpegの場所");
+
+ txtFfmpegPath.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+
+ btnSelectFfmpegPath.setText("...");
+ btnSelectFfmpegPath.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnSelectFfmpegPathActionPerformed(evt);
+ }
+ });
+
+ btnSave.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnSave.setText("保存");
+ btnSave.setToolTipText("");
+ btnSave.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnSaveActionPerformed(evt);
+ }
+ });
+
+ btnCancel.setFont(new java.awt.Font("MS UI Gothic", 0, 14)); // NOI18N
+ btnCancel.setText("キャンセル");
+ btnCancel.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ btnCancelActionPerformed(evt);
+ }
+ });
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(68, 68, 68)
+ .addComponent(jLabel1)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(txtFfmpegPath, javax.swing.GroupLayout.PREFERRED_SIZE, 255, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnSelectFfmpegPath, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap(84, Short.MAX_VALUE))
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(btnSave)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnCancel)
+ .addGap(72, 72, 72))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(65, 65, 65)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(jLabel1)
+ .addComponent(txtFfmpegPath, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(btnSelectFfmpegPath))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 106, Short.MAX_VALUE)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(btnSave)
+ .addComponent(btnCancel))
+ .addGap(23, 23, 23))
+ );
+
+ pack();
+ }// //GEN-END:initComponents
+
+ private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
+
+ this.applicationSetting.set(ApplicationSetting.FFMPEG_PATH, this.txtFfmpegPath.getText().trim());
+ this.dialogResult = DialogCodes.DIALOG_OK;
+ this.setVisible(false);
+
+ }//GEN-LAST:event_btnSaveActionPerformed
+
+ private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
+
+ this.dialogResult = DialogCodes.DIALOG_CANCEL;
+ this.setVisible(false);
+
+ }//GEN-LAST:event_btnCancelActionPerformed
+
+ private void btnSelectFfmpegPathActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSelectFfmpegPathActionPerformed
+
+ JFileChooser fc = new JFileChooser();
+ fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ fc.setCurrentDirectory(Paths.get("").toAbsolutePath().toFile());
+ if (this.applicationSetting.getString(ApplicationSetting.FFMPEG_PATH) != null) {
+ File f = new File(this.applicationSetting.getString(ApplicationSetting.FFMPEG_PATH));
+ String parent = f.getParent();
+ fc.setCurrentDirectory(new File(parent));
+ }
+ if (fc.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
+ String path = fc.getSelectedFile().getAbsolutePath();
+ this.txtFfmpegPath.setText(path);
+ }
+
+ }//GEN-LAST:event_btnSelectFfmpegPathActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnCancel;
+ private javax.swing.JButton btnSave;
+ private javax.swing.JButton btnSelectFfmpegPath;
+ private javax.swing.JLabel jLabel1;
+ private javax.swing.JTextField txtFfmpegPath;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/src/main/java/club/tmworks/telopeditor/fontSampleView.form b/src/main/java/club/tmworks/telopeditor/fontSampleView.form
new file mode 100644
index 0000000..c638b68
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/fontSampleView.form
@@ -0,0 +1,28 @@
+
+
+
diff --git a/src/main/java/club/tmworks/telopeditor/fontSampleView.java b/src/main/java/club/tmworks/telopeditor/fontSampleView.java
new file mode 100644
index 0000000..8a8eeaf
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/fontSampleView.java
@@ -0,0 +1,62 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor;
+
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class fontSampleView extends javax.swing.JPanel {
+
+ BufferedImage image = null;
+
+ /**
+ * Creates new form ImagePanel
+ */
+ public fontSampleView() {
+ initComponents();
+ }
+
+ public void setImage(BufferedImage image) {
+ this.image = image;
+ }
+
+ @Override
+ public void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ if (image != null) {
+ int x = (this.getWidth() - image.getWidth()) / 2;
+ g.drawImage(image, x, 0, this);
+ }
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 400, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 300, Short.MAX_VALUE)
+ );
+ }// //GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/src/main/java/club/tmworks/telopeditor/generators/SimpleMkvGenerator.java b/src/main/java/club/tmworks/telopeditor/generators/SimpleMkvGenerator.java
new file mode 100644
index 0000000..7919918
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/generators/SimpleMkvGenerator.java
@@ -0,0 +1,157 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor.generators;
+
+import club.tmworks.io.TextFile;
+import club.tmworks.telopeditor.model.ApplicationSetting;
+import club.tmworks.telopeditor.model.ProjectInfo;
+import com.tmworks.telopgenerator.PngGenerator;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.nio.charset.Charset;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JProgressBar;
+
+/**
+ * 単純なテロップを生成するスレッド
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class SimpleMkvGenerator extends Thread {
+
+ private JButton button;
+ private JMenuItem menuItem;
+ private ApplicationSetting setting;
+ private ProjectInfo currentProject;
+ private JProgressBar progress;
+ private JLabel message;
+
+ public SimpleMkvGenerator(ApplicationSetting setting, ProjectInfo project, JLabel label, JProgressBar bar, JButton button, JMenuItem menuItem) {
+ this.setting = setting;
+ this.currentProject = project;
+ this.message = label;
+ this.progress = bar;
+ this.button = button;
+ this.menuItem = menuItem;
+ }
+
+ @Override
+ public void run() {
+ JsonObject telopInfo = this.currentProject.getJsonObject(ProjectInfo.TELOP_INFO);
+ JsonArray notes = telopInfo.getJsonArray("NOTES");
+ double tempo = telopInfo.getJsonNumber("tempo").doubleValue();
+
+ this.progress.setMinimum(0);
+ this.progress.setMaximum(notes.size() - 1);
+
+ String bindFiles = "";
+
+ this.button.setEnabled(false);
+ this.menuItem.setEnabled(false);
+
+ for (int i = 0; i < notes.size(); i++) {
+ JsonObject note = notes.getJsonObject(i);
+
+ // png 出力
+ String pngFileName = note.getString("imagefile");
+ pngFileName = this.currentProject.getString(ProjectInfo.PROJECT_WORKING_DIR)
+ + File.separator + pngFileName;
+ String caption = note.getString("caption");
+ this.message.setText(caption);
+ PngGenerator pg = new PngGenerator();
+ pg.setFontName(this.currentProject.getString(ProjectInfo.FONT_NAME));
+ pg.setFontSize(Integer.valueOf(this.currentProject.getString(ProjectInfo.FONT_SIZE)));
+ pg.setLocation(
+ this.currentProject.getString(ProjectInfo.LOCATION_VERTICAL),
+ this.currentProject.getString(ProjectInfo.LOCATION_HORIZONTAL)
+ );
+ pg.setShadingSize(Integer.valueOf(this.currentProject.getString(ProjectInfo.SHADING_SIZE)));
+ pg.generate(pngFileName, caption);
+
+ // mkv 出力
+ String mkvFileName = pngFileName.replace(".png", ".mkv");
+ bindFiles += "file " + (new File(mkvFileName)).getName() + "\n";
+ double length = note.getJsonNumber("sound_length").doubleValue();
+ length = length * 24d;
+ length = length / 1000d;
+ BigDecimal bd = new BigDecimal(length).setScale(0, RoundingMode.HALF_UP);
+ length = bd.doubleValue();
+
+ String cmdline = "%BIN% -y -loop 1 -i %SRC% -vf scale=1920:1080 -profile:v 4444 -c:v prores_ks -pix_fmt rgba -vframes %LENGTH% -r 24 %DST%";
+ cmdline = cmdline.replace("%BIN%", this.setting.getString(ApplicationSetting.FFMPEG_PATH));
+ cmdline = cmdline.replace("%SRC%", pngFileName);
+ cmdline = cmdline.replace("%LENGTH%", String.valueOf(length));
+ cmdline = cmdline.replace("%DST%", mkvFileName);
+
+ String[] cmd = cmdline.split(" ");
+
+ ProcessBuilder pb = new ProcessBuilder(cmd);
+ pb.redirectErrorStream(true);
+
+ Process p;
+
+ try {
+ p = pb.start();
+ try (BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream(), Charset.defaultCharset()))) {
+ String line;
+ while ((line = r.readLine()) != null) {
+ System.out.println(line);
+ }
+ }
+ p.waitFor();
+ } catch (IOException | InterruptedException ex) {
+ Logger.getLogger(SimpleMkvGenerator.class.getName()).log(Level.SEVERE, null, ex);
+ }
+
+ this.progress.setValue(i);
+ }
+
+ this.message.setText("動画ファイルを結合中");
+ String dataFile = "bindlist.txt";
+ dataFile = this.currentProject.getString(ProjectInfo.PROJECT_WORKING_DIR) + File.separator + dataFile;
+
+ TextFile.save(dataFile, bindFiles);
+
+ String dstMkv = this.setting.getString(ApplicationSetting.CURRENT_PROJECT);
+ dstMkv = dstMkv.replace(".project.json", ".mkv");
+
+ String bindcmd = "%BIN% -y -f concat -i %DATA% -c copy %DST%";
+ bindcmd = bindcmd.replace("%BIN%", this.setting.getString(ApplicationSetting.FFMPEG_PATH));
+ bindcmd = bindcmd.replace("%DATA%", dataFile);
+ bindcmd = bindcmd.replace("%DST%", dstMkv);
+
+ ProcessBuilder pb = new ProcessBuilder(bindcmd.split(" "));
+ pb.redirectErrorStream(true);
+
+ Process p;
+ try {
+ p = pb.start();
+ try (BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream(), Charset.defaultCharset()))) {
+ String line;
+ while ((line = r.readLine()) != null) {
+ System.out.println(line);
+ }
+ }
+ p.waitFor();
+ } catch (IOException | InterruptedException ex) {
+ Logger.getLogger(SimpleMkvGenerator.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ this.message.setText("MKV作成終了 : " + dstMkv);
+ this.button.setEnabled(true);
+ this.menuItem.setEnabled(true);
+ }
+
+}
diff --git a/src/main/java/club/tmworks/telopeditor/model/AbstractSetting.java b/src/main/java/club/tmworks/telopeditor/model/AbstractSetting.java
new file mode 100644
index 0000000..eef2a7d
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/model/AbstractSetting.java
@@ -0,0 +1,65 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor.model;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class AbstractSetting {
+
+ protected JsonObject jsonData;
+
+ public AbstractSetting() {
+ this.jsonData = Json.createObjectBuilder().build();
+ }
+
+ public void set(String name, String value) {
+ this.jsonData = Json.createObjectBuilder(this.jsonData).add(name, value).build();
+ }
+
+ public void set(String name, JsonObject object) {
+ this.jsonData = Json.createObjectBuilder(this.jsonData).add(name, object).build();
+ }
+
+ public void set(String name, JsonArray array) {
+ this.jsonData = Json.createObjectBuilder(this.jsonData).add(name, array).build();
+ }
+
+ public String getString(String name) {
+ if (this.jsonData.containsKey(name)) {
+ return this.jsonData.getString(name);
+ }
+ return null;
+ }
+
+ public JsonObject getJsonObject(String name) {
+ if (this.jsonData.containsKey(name)) {
+ return this.jsonData.getJsonObject(name);
+ }
+ return null;
+ }
+
+ public JsonArray getJsonArray(String name) {
+ if (this.jsonData.containsKey(name)) {
+ return this.jsonData.getJsonArray(name);
+ }
+ return null;
+ }
+
+ public JsonObject getRoot() {
+ return this.jsonData;
+ }
+
+ public void getRoot(JsonObject setting) {
+ this.jsonData = setting;
+ }
+
+}
diff --git a/src/main/java/club/tmworks/telopeditor/model/ApplicationSetting.java b/src/main/java/club/tmworks/telopeditor/model/ApplicationSetting.java
new file mode 100644
index 0000000..5a18225
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/model/ApplicationSetting.java
@@ -0,0 +1,24 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor.model;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class ApplicationSetting extends AbstractSetting {
+
+ public static final String FFMPEG_PATH = "ffmpeg_path";
+
+ public static final String CURRENT_PROJECT = "current_project";
+
+ public static final String LAST_PROJECT = "last_project";
+
+ public ApplicationSetting() {
+ super();
+ }
+
+}
diff --git a/src/main/java/club/tmworks/telopeditor/model/DialogCodes.java b/src/main/java/club/tmworks/telopeditor/model/DialogCodes.java
new file mode 100644
index 0000000..3febc97
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/model/DialogCodes.java
@@ -0,0 +1,20 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor.model;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class DialogCodes {
+
+ public static final int DIALOG_OK = 1;
+ public static final int DIALOG_CANCEL = 2;
+ public static final int DIALOG_YES = 3;
+ public static final int DIALOG_NO = 4;
+ public static final int DIALOG_ABORT = 5;
+
+}
diff --git a/src/main/java/club/tmworks/telopeditor/model/FlexibleFileFilter.java b/src/main/java/club/tmworks/telopeditor/model/FlexibleFileFilter.java
new file mode 100644
index 0000000..e00f779
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/model/FlexibleFileFilter.java
@@ -0,0 +1,44 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor.model;
+
+import java.io.File;
+import javax.swing.filechooser.FileFilter;
+
+/**
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class FlexibleFileFilter extends FileFilter {
+
+ private String[] filters;
+
+ private String description;
+
+ public FlexibleFileFilter(String[] filters, String description) {
+ this.filters = filters;
+ }
+
+ @Override
+ public boolean accept(File f) {
+ if (f.isDirectory()) {
+ return true;
+ }
+ String fileName = f.getName();
+ for (String filter : filters) {
+ if (fileName.toLowerCase().endsWith(filter.toLowerCase())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String getDescription() {
+ return this.description;
+ }
+
+}
diff --git a/src/main/java/club/tmworks/telopeditor/model/ProjectInfo.java b/src/main/java/club/tmworks/telopeditor/model/ProjectInfo.java
new file mode 100644
index 0000000..46cf3ed
--- /dev/null
+++ b/src/main/java/club/tmworks/telopeditor/model/ProjectInfo.java
@@ -0,0 +1,119 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package club.tmworks.telopeditor.model;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+
+/**
+ * プロジェクトの情報モデル
+ *
+ * @author MURAKAMI Takahiro
+ */
+public class ProjectInfo extends AbstractSetting {
+
+ public static final String PROJECT_NAME = "project_name";
+
+ public static final String PROJECT_WORKING_DIR = "working_dir";
+
+ public static final String PROJECT_MUSICXML_FILES = "musicxml_files";
+
+ public static final String PHONETIC = "phonetic";
+
+ public static final String LYRICS = "lyrics";
+
+ public static final String TELOP_INFO = "telop_info";
+
+ public static final String FONT_SIZE = "font_size";
+
+ public static final String FONT_NAME = "font_name";
+
+ public static final String SHADING_SIZE = "shading_size";
+
+ public static final String LOCATION_HORIZONTAL = "location_horizontal";
+
+ public static final String HORIZONTAL_LEFT = "horizontal_LEFT";
+
+ public static final String HORIZONTAL_CENTER = "horizontal_center";
+
+ public static final String HORIZOTAL_RIGHT = "horizontal_right";
+
+ public static final String LOCATION_VERTICAL = "location_vertical";
+
+ public static final String VERTICAL_TOP = "vertical_top";
+
+ public static final String VERTICAL_CENTER = "vertical_center";
+
+ public static final String VERTICAL_BOTTOM = "vertical_bottom";
+
+ public String projectName = "";
+
+ public String workingFolder = "";
+
+ public JsonArray musicXmlFiles;
+
+ public ProjectInfo() {
+ super();
+
+ this.musicXmlFiles = Json.createArrayBuilder().build();
+ this.setMusicXmlFiles(musicXmlFiles);
+ }
+
+ @Override
+ public void getRoot(JsonObject jsonData) {
+ super.getRoot(jsonData);
+ this.musicXmlFiles = this.jsonData.getJsonArray(ProjectInfo.PROJECT_MUSICXML_FILES);
+ }
+
+ public final void setMusicXmlFiles(JsonArray array) {
+ this.musicXmlFiles = array;
+ this.jsonData = Json.createObjectBuilder(this.jsonData)
+ .add(PROJECT_MUSICXML_FILES, this.musicXmlFiles)
+ .build();
+ }
+
+ public void addMusicXmlFile(String filePath) {
+ if (this.findMusicXmlFle(filePath) < 0) {
+ this.musicXmlFiles = Json.createArrayBuilder(this.musicXmlFiles)
+ .add(this.musicXmlFiles.size(), filePath)
+ .build();
+ this.setMusicXmlFiles(this.musicXmlFiles);
+ }
+ }
+
+ public int findMusicXmlFle(String filePath) {
+ int rvalue = -1;
+ for (int i = 0; i < this.musicXmlFiles.size(); i++) {
+ if (this.musicXmlFiles.getString(i).equals(filePath)) {
+ rvalue = i;
+ break;
+ }
+ }
+ return rvalue;
+ }
+
+ public void removeMusicXmlFile(String filePath) {
+ int index = this.findMusicXmlFle(filePath);
+ if (index > -1) {
+ this.removeMusicXmlFile(index);
+ }
+ }
+
+ public void removeMusicXmlFile(int i) {
+ this.musicXmlFiles.remove(i);
+ this.setMusicXmlFiles(musicXmlFiles);
+ }
+
+ public JsonArray getMusicXmlFiles() {
+ return this.musicXmlFiles;
+ }
+
+ public String getMusicXmlFile(int i) {
+ return this.musicXmlFiles.getString(i);
+ }
+
+}
diff --git "a/src/main/resources/icons8-\343\202\253\343\203\201\343\203\263\343\202\263-16.png" "b/src/main/resources/icons8-\343\202\253\343\203\201\343\203\263\343\202\263-16.png"
new file mode 100644
index 0000000..bd5ba93
--- /dev/null
+++ "b/src/main/resources/icons8-\343\202\253\343\203\201\343\203\263\343\202\263-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\202\267\343\203\243\343\203\203\343\203\210\343\203\200\343\202\246\343\203\263-16.png" "b/src/main/resources/icons8-\343\202\267\343\203\243\343\203\203\343\203\210\343\203\200\343\202\246\343\203\263-16.png"
new file mode 100644
index 0000000..41fc994
--- /dev/null
+++ "b/src/main/resources/icons8-\343\202\267\343\203\243\343\203\203\343\203\210\343\203\200\343\202\246\343\203\263-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\202\267\343\203\243\343\203\203\343\203\210\343\203\200\343\202\246\343\203\263-32.png" "b/src/main/resources/icons8-\343\202\267\343\203\243\343\203\203\343\203\210\343\203\200\343\202\246\343\203\263-32.png"
new file mode 100644
index 0000000..d14f954
--- /dev/null
+++ "b/src/main/resources/icons8-\343\202\267\343\203\243\343\203\203\343\203\210\343\203\200\343\202\246\343\203\263-32.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\202\271\343\203\212\343\202\244\343\203\221\343\203\274-16.png" "b/src/main/resources/icons8-\343\202\271\343\203\212\343\202\244\343\203\221\343\203\274-16.png"
new file mode 100644
index 0000000..1cf0da4
--- /dev/null
+++ "b/src/main/resources/icons8-\343\202\271\343\203\212\343\202\244\343\203\221\343\203\274-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\202\271\343\203\212\343\202\244\343\203\221\343\203\274-32.png" "b/src/main/resources/icons8-\343\202\271\343\203\212\343\202\244\343\203\221\343\203\274-32.png"
new file mode 100644
index 0000000..1222726
--- /dev/null
+++ "b/src/main/resources/icons8-\343\202\271\343\203\212\343\202\244\343\203\221\343\203\274-32.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\202\273\343\203\274\343\203\226-16.png" "b/src/main/resources/icons8-\343\202\273\343\203\274\343\203\226-16.png"
new file mode 100644
index 0000000..5d82197
--- /dev/null
+++ "b/src/main/resources/icons8-\343\202\273\343\203\274\343\203\226-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\202\273\343\203\274\343\203\226-32.png" "b/src/main/resources/icons8-\343\202\273\343\203\274\343\203\226-32.png"
new file mode 100644
index 0000000..dbaa0cb
--- /dev/null
+++ "b/src/main/resources/icons8-\343\202\273\343\203\274\343\203\226-32.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\203\206\343\202\255\343\202\271\343\203\210\343\202\222\344\270\212\346\217\203\343\201\210-16.png" "b/src/main/resources/icons8-\343\203\206\343\202\255\343\202\271\343\203\210\343\202\222\344\270\212\346\217\203\343\201\210-16.png"
new file mode 100644
index 0000000..7f3d260
--- /dev/null
+++ "b/src/main/resources/icons8-\343\203\206\343\202\255\343\202\271\343\203\210\343\202\222\344\270\212\346\217\203\343\201\210-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\203\206\343\202\255\343\202\271\343\203\210\343\202\222\344\270\213\346\217\203\343\201\210-16.png" "b/src/main/resources/icons8-\343\203\206\343\202\255\343\202\271\343\203\210\343\202\222\344\270\213\346\217\203\343\201\210-16.png"
new file mode 100644
index 0000000..94dd2ea
--- /dev/null
+++ "b/src/main/resources/icons8-\343\203\206\343\202\255\343\202\271\343\203\210\343\202\222\344\270\213\346\217\203\343\201\210-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\203\206\343\202\255\343\202\271\343\203\210\343\202\222\344\270\255\345\244\256\343\201\253\346\217\203\343\201\210\343\202\213-16.png" "b/src/main/resources/icons8-\343\203\206\343\202\255\343\202\271\343\203\210\343\202\222\344\270\255\345\244\256\343\201\253\346\217\203\343\201\210\343\202\213-16.png"
new file mode 100644
index 0000000..ad59f8b
--- /dev/null
+++ "b/src/main/resources/icons8-\343\203\206\343\202\255\343\202\271\343\203\210\343\202\222\344\270\255\345\244\256\343\201\253\346\217\203\343\201\210\343\202\213-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\203\225\343\202\251\343\203\253\343\203\200\343\203\274\343\202\222\351\226\213\343\201\217-16.png" "b/src/main/resources/icons8-\343\203\225\343\202\251\343\203\253\343\203\200\343\203\274\343\202\222\351\226\213\343\201\217-16.png"
new file mode 100644
index 0000000..0ad54ef
--- /dev/null
+++ "b/src/main/resources/icons8-\343\203\225\343\202\251\343\203\253\343\203\200\343\203\274\343\202\222\351\226\213\343\201\217-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\343\203\225\343\202\251\343\203\253\343\203\200\343\203\274\343\202\222\351\226\213\343\201\217-32.png" "b/src/main/resources/icons8-\343\203\225\343\202\251\343\203\253\343\203\200\343\203\274\343\202\222\351\226\213\343\201\217-32.png"
new file mode 100644
index 0000000..f439661
--- /dev/null
+++ "b/src/main/resources/icons8-\343\203\225\343\202\251\343\203\253\343\203\200\343\203\274\343\202\222\351\226\213\343\201\217-32.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\344\270\255\345\244\256\346\217\203\343\201\210-16.png" "b/src/main/resources/icons8-\344\270\255\345\244\256\346\217\203\343\201\210-16.png"
new file mode 100644
index 0000000..e067241
--- /dev/null
+++ "b/src/main/resources/icons8-\344\270\255\345\244\256\346\217\203\343\201\210-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\345\206\215\347\224\237-16.png" "b/src/main/resources/icons8-\345\206\215\347\224\237-16.png"
new file mode 100644
index 0000000..131447c
--- /dev/null
+++ "b/src/main/resources/icons8-\345\206\215\347\224\237-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\345\206\215\347\224\237-32.png" "b/src/main/resources/icons8-\345\206\215\347\224\237-32.png"
new file mode 100644
index 0000000..1310b1b
--- /dev/null
+++ "b/src/main/resources/icons8-\345\206\215\347\224\237-32.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\345\217\263\346\217\203\343\201\210-16.png" "b/src/main/resources/icons8-\345\217\263\346\217\203\343\201\210-16.png"
new file mode 100644
index 0000000..9fd3639
--- /dev/null
+++ "b/src/main/resources/icons8-\345\217\263\346\217\203\343\201\210-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\345\220\215\345\211\215\343\202\222\344\273\230\343\201\221\343\201\246\344\277\235\345\255\230-16.png" "b/src/main/resources/icons8-\345\220\215\345\211\215\343\202\222\344\273\230\343\201\221\343\201\246\344\277\235\345\255\230-16.png"
new file mode 100644
index 0000000..9752301
--- /dev/null
+++ "b/src/main/resources/icons8-\345\220\215\345\211\215\343\202\222\344\273\230\343\201\221\343\201\246\344\277\235\345\255\230-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\345\220\215\345\211\215\343\202\222\344\273\230\343\201\221\343\201\246\344\277\235\345\255\230-32.png" "b/src/main/resources/icons8-\345\220\215\345\211\215\343\202\222\344\273\230\343\201\221\343\201\246\344\277\235\345\255\230-32.png"
new file mode 100644
index 0000000..51a6a62
--- /dev/null
+++ "b/src/main/resources/icons8-\345\220\215\345\211\215\343\202\222\344\273\230\343\201\221\343\201\246\344\277\235\345\255\230-32.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\345\267\246\346\217\203\343\201\210-16.png" "b/src/main/resources/icons8-\345\267\246\346\217\203\343\201\210-16.png"
new file mode 100644
index 0000000..bb82f8c
--- /dev/null
+++ "b/src/main/resources/icons8-\345\267\246\346\217\203\343\201\210-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\346\226\260\350\246\217\344\275\234\346\210\220-16.png" "b/src/main/resources/icons8-\346\226\260\350\246\217\344\275\234\346\210\220-16.png"
new file mode 100644
index 0000000..6682872
--- /dev/null
+++ "b/src/main/resources/icons8-\346\226\260\350\246\217\344\275\234\346\210\220-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\346\226\260\350\246\217\344\275\234\346\210\220-32.png" "b/src/main/resources/icons8-\346\226\260\350\246\217\344\275\234\346\210\220-32.png"
new file mode 100644
index 0000000..f632f18
--- /dev/null
+++ "b/src/main/resources/icons8-\346\226\260\350\246\217\344\275\234\346\210\220-32.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\346\230\240\347\224\273-16.png" "b/src/main/resources/icons8-\346\230\240\347\224\273-16.png"
new file mode 100644
index 0000000..bd3bf85
--- /dev/null
+++ "b/src/main/resources/icons8-\346\230\240\347\224\273-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\346\230\240\347\224\273-32.png" "b/src/main/resources/icons8-\346\230\240\347\224\273-32.png"
new file mode 100644
index 0000000..e50af19
--- /dev/null
+++ "b/src/main/resources/icons8-\346\230\240\347\224\273-32.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\347\251\272\343\203\225\343\202\243\343\203\253\343\202\277\343\203\274-16.png" "b/src/main/resources/icons8-\347\251\272\343\203\225\343\202\243\343\203\253\343\202\277\343\203\274-16.png"
new file mode 100644
index 0000000..f9c85f5
--- /dev/null
+++ "b/src/main/resources/icons8-\347\251\272\343\203\225\343\202\243\343\203\253\343\202\277\343\203\274-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\347\251\272\343\203\225\343\202\243\343\203\253\343\202\277\343\203\274-32.png" "b/src/main/resources/icons8-\347\251\272\343\203\225\343\202\243\343\203\253\343\202\277\343\203\274-32.png"
new file mode 100644
index 0000000..ac964c1
--- /dev/null
+++ "b/src/main/resources/icons8-\347\251\272\343\203\225\343\202\243\343\203\253\343\202\277\343\203\274-32.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\350\250\255\345\256\232-16.png" "b/src/main/resources/icons8-\350\250\255\345\256\232-16.png"
new file mode 100644
index 0000000..3b15ad0
--- /dev/null
+++ "b/src/main/resources/icons8-\350\250\255\345\256\232-16.png"
Binary files differ
diff --git "a/src/main/resources/icons8-\350\250\255\345\256\232-32.png" "b/src/main/resources/icons8-\350\250\255\345\256\232-32.png"
new file mode 100644
index 0000000..6c0d8b4
--- /dev/null
+++ "b/src/main/resources/icons8-\350\250\255\345\256\232-32.png"
Binary files differ