OSDN Git Service

リファクタリング(MIDIエディタの内部クラスを外出し)
[midichordhelper/MIDIChordHelper.git] / src / camidion / chordhelper / midieditor / SequenceTrackListTable.java
1 package camidion.chordhelper.midieditor;
2
3 import java.awt.event.ActionEvent;
4 import java.util.Arrays;
5
6 import javax.swing.AbstractAction;
7 import javax.swing.Action;
8 import javax.swing.DefaultCellEditor;
9 import javax.swing.JComboBox;
10 import javax.swing.JComponent;
11 import javax.swing.JLabel;
12 import javax.swing.JOptionPane;
13 import javax.swing.JTable;
14 import javax.swing.ListSelectionModel;
15 import javax.swing.event.ListSelectionEvent;
16 import javax.swing.event.ListSelectionListener;
17 import javax.swing.event.TableModelEvent;
18 import javax.swing.table.TableCellEditor;
19 import javax.swing.table.TableColumnModel;
20
21 import camidion.chordhelper.ChordHelperApplet;
22 import camidion.chordhelper.music.MIDISpec;
23
24 /**
25  * シーケンス(トラックリスト)テーブルビュー
26  */
27 public class SequenceTrackListTable extends JTable {
28         /**
29          * MIDIイベントリストテーブルビュー(選択中のトラックの中身)
30          */
31         public MidiEventTable eventListTable;
32         /**
33          * トラックリストテーブルビューを構築します。
34          * @param model シーケンス(トラックリスト)データモデル
35          * @param eventListTable イベントリストテーブル
36          */
37         public SequenceTrackListTable(SequenceTrackListTableModel model, MidiEventTable eventListTable) {
38                 super(model, null, model.getSelectionModel());
39                 this.eventListTable = eventListTable;
40                 //
41                 // 録音対象のMIDIチャンネルをコンボボックスで選択できるようにする
42                 getColumnModel()
43                         .getColumn(SequenceTrackListTableModel.Column.RECORD_CHANNEL.ordinal())
44                         .setCellEditor(new DefaultCellEditor(new JComboBox<String>(){{
45                                 addItem("OFF");
46                                 for(int i=1; i <= MIDISpec.MAX_CHANNELS; i++) addItem(String.format("%d", i));
47                                 addItem("ALL");
48                         }}));
49                 setAutoCreateColumnsFromModel(false);
50                 model.getParent().sequenceListSelectionModel.addListSelectionListener(titleLabel);
51                 TableColumnModel colModel = getColumnModel();
52                 Arrays.stream(SequenceTrackListTableModel.Column.values()).forEach(c->
53                         colModel.getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
54                 );
55         }
56         /**
57          * このテーブルビューが表示するデータを提供する
58          * シーケンス(トラックリスト)データモデルを返します。
59          * @return シーケンス(トラックリスト)データモデル
60          */
61         @Override
62         public SequenceTrackListTableModel getModel() {
63                 return (SequenceTrackListTableModel)dataModel;
64         }
65         /**
66          * タイトルラベル
67          */
68         TitleLabel titleLabel = new TitleLabel();
69         /**
70          * 親テーブルの選択シーケンスの変更に反応する
71          * 曲番号表示付きタイトルラベル
72          */
73         private class TitleLabel extends JLabel implements ListSelectionListener {
74                 private static final String TITLE = "Tracks";
75                 public TitleLabel() { setText(TITLE); }
76                 @Override
77                 public void valueChanged(ListSelectionEvent event) {
78                         if( event.getValueIsAdjusting() ) return;
79                         SequenceTrackListTableModel oldModel = getModel();
80                         SequenceTrackListTableModel newModel = oldModel.getParent().getSelectedSequenceModel();
81                         if( oldModel == newModel ) return;
82                         //
83                         // MIDIチャンネル選択中のときはキャンセルする
84                         cancelCellEditing();
85                         //
86                         String text = TITLE;
87                         ListSelectionModel sm = oldModel.getParent().sequenceListSelectionModel;
88                         if( ! sm.isSelectionEmpty() ) {
89                                 int index = sm.getMinSelectionIndex();
90                                 if( index >= 0 ) text = String.format(text+" - MIDI file #%d", index);
91                         }
92                         setText(text);
93                         if( newModel == null ) {
94                                 newModel = oldModel.getParent().emptyTrackListTableModel;
95                                 addTrackAction.setEnabled(false);
96                         }
97                         else {
98                                 addTrackAction.setEnabled(true);
99                         }
100                         oldModel.getSelectionModel().removeListSelectionListener(trackSelectionListener);
101                         setModel(newModel);
102                         setSelectionModel(newModel.getSelectionModel());
103                         newModel.getSelectionModel().addListSelectionListener(trackSelectionListener);
104                 }
105         }
106         /**
107          * {@inheritDoc}
108          *
109          * <p>このトラックリストテーブルのデータが変わったときに編集を解除します。
110          * 例えば、イベントが編集された場合や、
111          * シーケンサーからこのモデルが外された場合がこれに該当します。
112          * </p>
113          */
114         @Override
115         public void tableChanged(TableModelEvent e) {
116                 super.tableChanged(e);
117                 cancelCellEditing();
118         }
119         /**
120          * このトラックリストテーブルが編集モードになっていたら解除します。
121          */
122         private void cancelCellEditing() {
123                 TableCellEditor currentCellEditor = getCellEditor();
124                 if( currentCellEditor != null ) currentCellEditor.cancelCellEditing();
125         }
126         /**
127          * トラック追加アクション
128          */
129         Action addTrackAction = new AbstractAction("New") {
130                 {
131                         String tooltip = "Append new track - 新しいトラックの追加";
132                         putValue(Action.SHORT_DESCRIPTION, tooltip);
133                         setEnabled(false);
134                 }
135                 @Override
136                 public void actionPerformed(ActionEvent e) { getModel().createTrack(); }
137         };
138         /**
139          * トラック削除アクション
140          */
141         Action deleteTrackAction = new AbstractAction("Delete", MidiSequenceEditorDialog.deleteIcon) {
142                 public static final String CONFIRM_MESSAGE =
143                                 "Do you want to delete selected track ?\n選択したトラックを削除しますか?";
144                 {
145                         putValue(Action.SHORT_DESCRIPTION, "Delete selected track - 選択したトラックを削除");
146                         setEnabled(false);
147                 }
148                 @Override
149                 public void actionPerformed(ActionEvent event) {
150                         if( JOptionPane.showConfirmDialog(
151                                         ((JComponent)event.getSource()).getRootPane(),
152                                         CONFIRM_MESSAGE,
153                                         ChordHelperApplet.VersionInfo.NAME,
154                                         JOptionPane.YES_NO_OPTION,
155                                         JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION
156                         ) getModel().deleteSelectedTracks();
157                 }
158         };
159         /**
160          * トラック選択リスナー
161          */
162         private ListSelectionListener trackSelectionListener = event->{
163                 if( event.getValueIsAdjusting() ) return;
164                 ListSelectionModel selModel = getModel().getSelectionModel();
165                 deleteTrackAction.setEnabled(! selModel.isSelectionEmpty());
166                 eventListTable.titleLabel.updateTrackNumber(selModel.getMinSelectionIndex());
167                 eventListTable.setModel(getModel().getSelectedTrackModel());
168         };
169 }