OSDN Git Service

a8b08f635691714259712114794d5d323312aab8
[midichordhelper/MIDIChordHelper.git] / src / camidion / chordhelper / midieditor / MidiSequenceEditorDialog.java
1 package camidion.chordhelper.midieditor;
2
3 import java.awt.Container;
4 import java.awt.Dimension;
5 import java.awt.FlowLayout;
6 import java.awt.datatransfer.DataFlavor;
7 import java.awt.event.ActionEvent;
8 import java.io.File;
9 import java.util.List;
10
11 import javax.sound.midi.Sequencer;
12 import javax.swing.AbstractAction;
13 import javax.swing.Action;
14 import javax.swing.Box;
15 import javax.swing.BoxLayout;
16 import javax.swing.Icon;
17 import javax.swing.JButton;
18 import javax.swing.JCheckBox;
19 import javax.swing.JComboBox;
20 import javax.swing.JDialog;
21 import javax.swing.JLabel;
22 import javax.swing.JOptionPane;
23 import javax.swing.JPanel;
24 import javax.swing.JScrollPane;
25 import javax.swing.JSplitPane;
26 import javax.swing.TransferHandler;
27 import javax.swing.border.EtchedBorder;
28
29 import camidion.chordhelper.ButtonIcon;
30 import camidion.chordhelper.ChordHelperApplet;
31 import camidion.chordhelper.mididevice.MidiSequencerModel;
32 import camidion.chordhelper.mididevice.VirtualMidiDevice;
33
34 /**
35  * MIDIエディタ(MIDI Editor/Playlist for MIDI Chord Helper)
36  *
37  * @author
38  *      Copyright (C) 2006-2017 Akiyoshi Kamide
39  *      http://www.yk.rim.or.jp/~kamide/music/chordhelper/
40  */
41 public class MidiSequenceEditorDialog extends JDialog {
42         /**
43          * このダイアログを開きます。表示されていなければ表示し、すでに表示されていたら最前面に移動します。
44          */
45         public void open() { if( isVisible() ) toFront(); else setVisible(true); }
46         /**
47          * このダイアログを表示するボタン用アクション
48          */
49         public final Action openAction = new AbstractAction("Edit/Playlist/Speed", new ButtonIcon(ButtonIcon.EDIT_ICON)) {
50                 {
51                         String tooltip = "MIDIシーケンスの編集/プレイリスト/再生速度調整";
52                         putValue(Action.SHORT_DESCRIPTION, tooltip);
53                 }
54                 @Override
55                 public void actionPerformed(ActionEvent e) { open(); }
56         };
57         /**
58          * ドロップされた複数のMIDIファイルを読み込むハンドラー
59          */
60         public final TransferHandler transferHandler = new TransferHandler() {
61                 @Override
62                 public boolean canImport(TransferSupport support) {
63                         return support.isDataFlavorSupported(DataFlavor.javaFileListFlavor);
64                 }
65                 @SuppressWarnings("unchecked")
66                 @Override
67                 public boolean importData(TransferSupport support) {
68                         try {
69                                 Object data = support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
70                                 play((List<File>)data);
71                                 return true;
72                         } catch (Exception ex) {
73                                 JOptionPane.showMessageDialog(
74                                                 MidiSequenceEditorDialog.this, ex,
75                                                 ChordHelperApplet.VersionInfo.NAME,
76                                                 JOptionPane.ERROR_MESSAGE);
77                                 return false;
78                         }
79                 }
80         };
81         /**
82          * プレイリストビュー(シーケンスリスト)
83          */
84         public PlaylistTable playlistTable;
85         /**
86          * このエディタダイアログが表示しているプレイリストモデルを返します。
87          * @return プレイリストモデル
88          */
89         public PlaylistTableModel getPlaylistModel() {
90                 return playlistTable.getModel();
91         }
92         /**
93          * 指定されたリストに格納されたMIDIファイルを読み込んで再生します。
94          * すでに再生されていた場合、このエディタダイアログを表示します。
95          * @param fileList 読み込むMIDIファイルのリスト
96          */
97         public void play(List<File> fileList) {
98                 play(playlistTable.add(fileList));
99         }
100         /**
101          * 指定されたインデックス値(先頭が0)のMIDIシーケンスから再生します。
102          * すでに再生されていた場合、このエディタダイアログを表示します。
103          * @param index プレイリスト内にあるMIDIシーケンスのインデックス値
104          */
105         public void play(int index) {
106                 try {
107                         PlaylistTableModel playlist = getPlaylistModel();
108                         MidiSequencerModel sequencerModel = playlist.getSequencerModel();
109                         if( sequencerModel.getSequencer().isRunning() ) { open(); return; }
110                         if( index >= 0 ) {
111                                 playlist.play(index);
112                                 playlistTable.getSelectionModel().setSelectionInterval(index, index);
113                         }
114                 } catch (Exception e) {
115                         JOptionPane.showMessageDialog(this, e, ChordHelperApplet.VersionInfo.NAME, JOptionPane.ERROR_MESSAGE);
116                 }
117         }
118         /**
119          * 現在選択されているMIDIシーケンスから再生します。
120          * すでに再生されていた場合、このエディタダイアログを表示します。
121          */
122         public void play() {
123                 play(playlistTable.getSelectionModel().getMinSelectionIndex());
124         }
125
126         static final Icon deleteIcon = new ButtonIcon(ButtonIcon.X_ICON);
127         /**
128          * 新しいMIDIシーケンスを生成するダイアログ
129          */
130         public NewSequenceDialog newSequenceDialog;
131         /**
132          * 新しい {@link MidiSequenceEditorDialog} を構築します。
133          * @param playlistTableModel このエディタが参照するプレイリストモデル
134          * @param eventDialog MIDIイベント入力ダイアログ
135          * @param outputMidiDevice イベントテーブルの操作音出力先MIDIデバイス
136          * @param midiDeviceDialogOpenAction MIDIデバイスダイアログを開くアクション
137          */
138         public MidiSequenceEditorDialog(PlaylistTableModel playlistTableModel, MidiEventDialog eventDialog, VirtualMidiDevice outputMidiDevice, Action midiDeviceDialogOpenAction) {
139                 MidiEventTable eventListTable = new MidiEventTable(playlistTableModel.emptyEventListTableModel, eventDialog, outputMidiDevice);
140                 SequenceTrackListTable trackListTable = new SequenceTrackListTable(playlistTableModel.emptyTrackListTableModel, eventListTable);
141                 playlistTable = new PlaylistTable(playlistTableModel, midiDeviceDialogOpenAction, trackListTable);
142                 newSequenceDialog = new NewSequenceDialog(playlistTable, outputMidiDevice);
143                 setTitle("MIDI Editor/Playlist - "+ChordHelperApplet.VersionInfo.NAME);
144                 setBounds( 150, 200, 900, 500 );
145                 setLayout(new FlowLayout());
146                 setTransferHandler(transferHandler);
147                 //
148                 // パネルレイアウト
149                 JPanel playlistPanel = new JPanel() {{
150                         JPanel playlistOperationPanel = new JPanel() {{
151                                 setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
152                                 add(Box.createRigidArea(new Dimension(10, 0)));
153                                 add(new JButton(newSequenceDialog.openAction) {
154                                         { setMargin(ChordHelperApplet.ZERO_INSETS); }
155                                 });
156                                 if( playlistTable.midiFileChooser != null ) {
157                                         add( Box.createRigidArea(new Dimension(5, 0)) );
158                                         add(new JButton(playlistTable.midiFileChooser.openMidiFileAction) {
159                                                 { setMargin(ChordHelperApplet.ZERO_INSETS); }
160                                         });
161                                 }
162                                 add(Box.createRigidArea(new Dimension(5, 0)));
163                                 add(new JButton(playlistTable.base64EncodeAction) {
164                                         { setMargin(ChordHelperApplet.ZERO_INSETS); }
165                                 });
166                                 add(Box.createRigidArea(new Dimension(5, 0)));
167                                 add(new JButton(playlistTableModel.getMoveToTopAction()) {
168                                         { setMargin(ChordHelperApplet.ZERO_INSETS); }
169                                 });
170                                 add(Box.createRigidArea(new Dimension(5, 0)));
171                                 add(new JButton(playlistTableModel.getMoveToBottomAction()) {
172                                         { setMargin(ChordHelperApplet.ZERO_INSETS); }
173                                 });
174                                 if( playlistTable.midiFileChooser != null ) {
175                                         add(Box.createRigidArea(new Dimension(5, 0)));
176                                         add(new JButton(playlistTable.midiFileChooser.saveMidiFileAction) {
177                                                 { setMargin(ChordHelperApplet.ZERO_INSETS); }
178                                         });
179                                 }
180                                 add( Box.createRigidArea(new Dimension(5, 0)) );
181                                 add(new JButton(playlistTable.deleteSequenceAction) {
182                                         { setMargin(ChordHelperApplet.ZERO_INSETS); }
183                                 });
184                                 add( Box.createRigidArea(new Dimension(5, 0)) );
185                                 add(new SequencerSpeedSlider(playlistTableModel.getSequencerModel().speedSliderModel));
186                                 add( Box.createRigidArea(new Dimension(5, 0)) );
187                                 add(new JPanel() {{
188                                         setBorder(new EtchedBorder());
189                                         MidiSequencerModel sequencerModel = playlistTableModel.getSequencerModel();
190                                         add(new JLabel("Sync Master"));
191                                         add(new JComboBox<Sequencer.SyncMode>(sequencerModel.masterSyncModeModel));
192                                         add(new JLabel("Slave"));
193                                         add(new JComboBox<Sequencer.SyncMode>(sequencerModel.slaveSyncModeModel));
194                                 }});
195                         }};
196                         setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
197                         add(new JScrollPane(playlistTable));
198                         add(Box.createRigidArea(new Dimension(0, 10)));
199                         add(playlistOperationPanel);
200                         add(Box.createRigidArea(new Dimension(0, 10)));
201                 }};
202                 JPanel trackListPanel = new JPanel() {{
203                         JPanel trackListOperationPanel = new JPanel() {{
204                                 add(new JButton(trackListTable.addTrackAction) {{ setMargin(ChordHelperApplet.ZERO_INSETS); }});
205                                 add(new JButton(trackListTable.deleteTrackAction) {{ setMargin(ChordHelperApplet.ZERO_INSETS); }});
206                         }};
207                         setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
208                         add(trackListTable.titleLabel);
209                         add(Box.createRigidArea(new Dimension(0, 5)));
210                         add(new JScrollPane(trackListTable));
211                         add(Box.createRigidArea(new Dimension(0, 5)));
212                         add(trackListOperationPanel);
213                 }};
214                 JPanel eventListPanel = new JPanel() {{
215                         JPanel eventListOperationPanel = new JPanel() {{
216                                 add(new JCheckBox("Pair NoteON/OFF") {{
217                                         setModel(eventListTable.pairNoteOnOffModel);
218                                         setToolTipText("NoteON/OFFをペアで同時選択する");
219                                 }});
220                                 add(new JButton(eventListTable.queryJumpEventAction) {{ setMargin(ChordHelperApplet.ZERO_INSETS); }});
221                                 add(new JButton(eventListTable.queryAddEventAction) {{ setMargin(ChordHelperApplet.ZERO_INSETS); }});
222                                 add(new JButton(eventListTable.copyEventAction) {{ setMargin(ChordHelperApplet.ZERO_INSETS); }});
223                                 add(new JButton(eventListTable.cutEventAction) {{ setMargin(ChordHelperApplet.ZERO_INSETS); }});
224                                 add(new JButton(eventListTable.queryPasteEventAction) {{ setMargin(ChordHelperApplet.ZERO_INSETS); }});
225                                 add(new JButton(eventListTable.deleteEventAction) {{ setMargin(ChordHelperApplet.ZERO_INSETS); }});
226                         }};
227                         setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
228                         add(eventListTable.titleLabel);
229                         add(eventListTable.scrollPane);
230                         add(eventListOperationPanel);
231                 }};
232                 Container cp = getContentPane();
233                 cp.setLayout(new BoxLayout(cp, BoxLayout.Y_AXIS));
234                 cp.add(Box.createVerticalStrut(2));
235                 cp.add(
236                         new JSplitPane(JSplitPane.VERTICAL_SPLIT, playlistPanel,
237                                 new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, trackListPanel, eventListPanel) {{
238                                         setDividerLocation(300);
239                                 }}
240                         ) {{
241                                 setDividerLocation(160);
242                         }}
243                 );
244         }
245
246 }