import camidion.chordhelper.mididevice.VirtualMidiDevice;
import camidion.chordhelper.midieditor.Base64Dialog;
import camidion.chordhelper.midieditor.KeySignatureLabel;
+import camidion.chordhelper.midieditor.MidiEventDialog;
import camidion.chordhelper.midieditor.MidiSequenceEditorDialog;
import camidion.chordhelper.midieditor.NewSequenceDialog;
import camidion.chordhelper.midieditor.PlaylistTableModel;
* @return 追加先のインデックス値(0から始まる)。追加できなかったときは -1
*/
public int addToPlaylistBase64(String base64EncodedText, String filename) {
- Base64Dialog d = midiEditor.sequenceListTable.base64Dialog;
+ Base64Dialog d = midiEditor.playlistTable.base64Dialog;
d.setBase64Data(base64EncodedText, filename);
return d.addToPlaylist();
}
public String getMidiDataBase64() throws IOException {
SequenceTrackListTableModel s = sequencerModel.getSequenceTrackListTableModel();
if( s == null ) return null;
- Base64Dialog d = midiEditor.sequenceListTable.base64Dialog;
+ Base64Dialog d = midiEditor.playlistTable.base64Dialog;
d.setMIDIData(s.getMIDIdata());
return d.getBase64Data();
}
*/
public static class VersionInfo {
public static final String NAME = "MIDI Chord Helper";
- public static final String VERSION = "Ver.20170419.1";
+ public static final String VERSION = "Ver.20170421.1";
public static final String COPYRIGHT = "Copyright (C) 2004-2017";
public static final String AUTHER = "@きよし - Akiyoshi Kamide";
public static final String URL = "http://www.yk.rim.or.jp/~kamide/music/chordhelper/";
));
keyboardCenterPanel.keyboard.setPreferredSize(new Dimension(571, 80));
}};
- // MIDIã\83\87ã\83\90ã\82¤ã\82¹ã\81¨MIDIã\82¨ã\83\87ã\82£ã\82¿ã\81®ã\82»ã\83\83ã\83\88ã\82¢ã\83\83ã\83\97
+ // MIDIã\83\87ã\83\90ã\82¤ã\82¹ã\83\84ã\83ªã\83¼ã\81®æ§\8bç¯\89
VirtualMidiDevice guiMidiDevice = keyboardPanel.keyboardCenterPanel.keyboard.midiDevice;
deviceTreeModel = new MidiDeviceTreeModel(guiMidiDevice);
- sequencerModel = deviceTreeModel.getSequencerModel();
- playlistModel = new PlaylistTableModel(sequencerModel);
+ //
+ // MIDIデバイスツリーを操作するダイアログの構築
MidiDeviceDialog midiDeviceDialog = new MidiDeviceDialog(deviceTreeModel);
midiDeviceDialog.setIconImage(iconImage);
- midiEditor = new MidiSequenceEditorDialog(playlistModel, guiMidiDevice, midiDeviceDialog.getOpenAction());
- midiEditor.setIconImage(iconImage);
//
- // メイン画面へのMIDIファイルのドラッグ&ドロップ受付開始
- setTransferHandler(midiEditor.transferHandler);
+ // MIDIイベントダイアログの構築
+ MidiEventDialog eventDialog = new MidiEventDialog();
+ keyboardPanel.setEventDialog(eventDialog);
//
- // MIDIエディタのイベントダイアログを、ピアノ鍵盤のイベント送出ダイアログと共用
- keyboardPanel.setEventDialog(midiEditor.eventListTable.eventDialog);
+ // MIDIエディタダイアログの構築・MIDIファイルのドロップ受付開始
+ sequencerModel = deviceTreeModel.getSequencerModel();
+ playlistModel = new PlaylistTableModel(sequencerModel);
+ midiEditor = new MidiSequenceEditorDialog(playlistModel, eventDialog, guiMidiDevice, midiDeviceDialog.getOpenAction());
+ midiEditor.setIconImage(iconImage);
+ setTransferHandler(midiEditor.transferHandler);
//
// 歌詞表示/コード入力フィールド
(lyricDisplay = new ChordTextField(sequencerModel)).addActionListener(
*/
public class MidiEventTable extends JTable {
/**
- * 操作音を鳴らすMIDI出力デバイス
+ * MIDIイベント入力ダイアログ(イベント入力とイベント送出で共用)
*/
- private VirtualMidiDevice outputMidiDevice;
+ public MidiEventDialog eventDialog;
/**
- * MIDIイベント入力ダイアログ(イベント入力とイベント送出で共用)
+ * 操作音を鳴らすMIDI出力デバイス
*/
- public MidiEventDialog eventDialog = new MidiEventDialog();
+ private VirtualMidiDevice outputMidiDevice;
/**
* 新しいイベントリストテーブルを構築します。
* <p>データモデルとして一つのトラックのイベントリストを指定できます。
* </p>
*
* @param model トラック(イベントリスト)データモデル
+ * @param eventDialog MIDIイベントダイアログ
* @param outputMidiDevice 操作音出力先MIDIデバイス
*/
- public MidiEventTable(TrackEventListTableModel model, VirtualMidiDevice outputMidiDevice) {
+ public MidiEventTable(TrackEventListTableModel model, MidiEventDialog eventDialog, VirtualMidiDevice outputMidiDevice) {
super(model, null, model.getSelectionModel());
this.outputMidiDevice = outputMidiDevice;
+ this.eventDialog = eventDialog;
+ pairNoteOnOffModel = new JToggleButton.ToggleButtonModel() {
+ {
+ addItemListener(e->eventDialog.midiMessageForm.durationForm.setEnabled(isSelected()));
+ setSelected(true);
+ }
+ };
//
// 列モデルにセルエディタを設定
eventCellEditor = new MidiEventCellEditor();
*/
@Override
public TrackEventListTableModel getModel() {
- return (TrackEventListTableModel) super.getModel();
+ return (TrackEventListTableModel) dataModel;
}
- public void updateTo(SequenceTrackListTableModel sequenceModel) {
- titleLabel.updateTrackNumber(sequenceModel.getSelectionModel().getMinSelectionIndex());
- TrackEventListTableModel oldTrackModel = getModel();
- TrackEventListTableModel newTrackModel = sequenceModel.getSelectedTrackModel();
- if( oldTrackModel == newTrackModel )
- return;
- if( newTrackModel == null ) {
- newTrackModel = getModel().getParent().getParent().emptyEventListTableModel;
+ public void setModel(TrackEventListTableModel model) {
+ TrackEventListTableModel oldModel = getModel();
+ if( oldModel == model ) return;
+ if( model == null ) {
+ model = getModel().getParent().getParent().emptyEventListTableModel;
queryJumpEventAction.setEnabled(false);
queryAddEventAction.setEnabled(false);
queryJumpEventAction.setEnabled(true);
queryAddEventAction.setEnabled(true);
}
- oldTrackModel.getSelectionModel().removeListSelectionListener(eventSelectionListener);
- setModel(newTrackModel);
- setSelectionModel(newTrackModel.getSelectionModel());
- newTrackModel.getSelectionModel().addListSelectionListener(eventSelectionListener);
+ oldModel.getSelectionModel().removeListSelectionListener(eventSelectionListener);
+ super.setModel(model);
+ setSelectionModel(model.getSelectionModel());
+ model.getSelectionModel().addListSelectionListener(eventSelectionListener);
}
/**
* タイトルラベル
* 親テーブルの選択トラックの変更に反応する
* トラック番号つきタイトルラベル
*/
- private class TitleLabel extends JLabel {
+ class TitleLabel extends JLabel {
private static final String TITLE = "MIDI Events";
private TitleLabel() { super(TITLE); }
- private void updateTrackNumber(int index) {
+ void updateTrackNumber(int index) {
String text = TITLE;
if( index >= 0 ) text = String.format(TITLE+" - track #%d", index);
setText(text);
/**
* Pair noteON/OFF トグルボタンモデル
*/
- JToggleButton.ToggleButtonModel
- pairNoteOnOffModel = new JToggleButton.ToggleButtonModel() {
- {
- addItemListener(e->eventDialog.midiMessageForm.durationForm.setEnabled(isSelected()));
- setSelected(true);
- }
- };
+ JToggleButton.ToggleButtonModel pairNoteOnOffModel;
private class EventEditContext {
/**
* 編集対象トラック
import java.awt.datatransfer.DataFlavor;
import java.awt.event.ActionEvent;
import java.io.File;
-import java.util.Arrays;
import java.util.List;
import javax.sound.midi.Sequencer;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.BoxLayout;
-import javax.swing.DefaultCellEditor;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
-import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
-import javax.swing.JTable;
-import javax.swing.ListSelectionModel;
import javax.swing.TransferHandler;
import javax.swing.border.EtchedBorder;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-import javax.swing.event.TableModelEvent;
-import javax.swing.table.TableCellEditor;
-import javax.swing.table.TableColumnModel;
import camidion.chordhelper.ButtonIcon;
import camidion.chordhelper.ChordHelperApplet;
import camidion.chordhelper.mididevice.MidiSequencerModel;
import camidion.chordhelper.mididevice.VirtualMidiDevice;
-import camidion.chordhelper.music.MIDISpec;
/**
* MIDIエディタ(MIDI Editor/Playlist for MIDI Chord Helper)
*
* @author
- * Copyright (C) 2006-2016 Akiyoshi Kamide
+ * Copyright (C) 2006-2017 Akiyoshi Kamide
* http://www.yk.rim.or.jp/~kamide/music/chordhelper/
*/
public class MidiSequenceEditorDialog extends JDialog {
* @return プレイリストモデル
*/
public PlaylistTableModel getPlaylistModel() {
- return sequenceListTable.getModel();
+ return playlistTable.getModel();
}
/**
* 指定されたリストに格納されたMIDIファイルを読み込んで再生します。
* @param fileList 読み込むMIDIファイルのリスト
*/
public void play(List<File> fileList) {
- play(sequenceListTable.add(fileList));
+ play(playlistTable.add(fileList));
}
/**
* 指定されたインデックス値(先頭が0)のMIDIシーケンスから再生します。
/**
* プレイリストビュー(シーケンスリスト)
*/
- public PlaylistTable sequenceListTable;
- /**
- * MIDIトラックリストテーブルビュー(選択中のシーケンスの中身)
- */
- private SequenceTrackListTable trackListTable;
- /**
- * MIDIイベントリストテーブルビュー(選択中のトラックの中身)
- */
- public MidiEventTable eventListTable;
- /**
- * シーケンス(トラックリスト)テーブルビュー
- */
- public class SequenceTrackListTable extends JTable {
- /**
- * トラックリストテーブルビューを構築します。
- * @param model シーケンス(トラックリスト)データモデル
- */
- public SequenceTrackListTable(SequenceTrackListTableModel model) {
- super(model, null, model.getSelectionModel());
- //
- // 録音対象のMIDIチャンネルをコンボボックスで選択できるようにする
- getColumnModel()
- .getColumn(SequenceTrackListTableModel.Column.RECORD_CHANNEL.ordinal())
- .setCellEditor(new DefaultCellEditor(new JComboBox<String>(){{
- addItem("OFF");
- for(int i=1; i <= MIDISpec.MAX_CHANNELS; i++) addItem(String.format("%d", i));
- addItem("ALL");
- }}));
- setAutoCreateColumnsFromModel(false);
- model.getParent().sequenceListSelectionModel.addListSelectionListener(titleLabel);
- TableColumnModel colModel = getColumnModel();
- Arrays.stream(SequenceTrackListTableModel.Column.values()).forEach(c->
- colModel.getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
- );
- }
- /**
- * このテーブルビューが表示するデータを提供する
- * シーケンス(トラックリスト)データモデルを返します。
- * @return シーケンス(トラックリスト)データモデル
- */
- @Override
- public SequenceTrackListTableModel getModel() {
- return (SequenceTrackListTableModel)dataModel;
- }
- /**
- * タイトルラベル
- */
- TitleLabel titleLabel = new TitleLabel();
- /**
- * 親テーブルの選択シーケンスの変更に反応する
- * 曲番号表示付きタイトルラベル
- */
- private class TitleLabel extends JLabel implements ListSelectionListener {
- private static final String TITLE = "Tracks";
- public TitleLabel() { setText(TITLE); }
- @Override
- public void valueChanged(ListSelectionEvent event) {
- if( event.getValueIsAdjusting() ) return;
- SequenceTrackListTableModel oldModel = getModel();
- SequenceTrackListTableModel newModel = oldModel.getParent().getSelectedSequenceModel();
- if( oldModel == newModel ) return;
- //
- // MIDIチャンネル選択中のときはキャンセルする
- cancelCellEditing();
- //
- String text = TITLE;
- ListSelectionModel sm = oldModel.getParent().sequenceListSelectionModel;
- if( ! sm.isSelectionEmpty() ) {
- int index = sm.getMinSelectionIndex();
- if( index >= 0 ) text = String.format(text+" - MIDI file #%d", index);
- }
- setText(text);
- if( newModel == null ) {
- newModel = oldModel.getParent().emptyTrackListTableModel;
- addTrackAction.setEnabled(false);
- }
- else {
- addTrackAction.setEnabled(true);
- }
- oldModel.getSelectionModel().removeListSelectionListener(trackSelectionListener);
- setModel(newModel);
- setSelectionModel(newModel.getSelectionModel());
- newModel.getSelectionModel().addListSelectionListener(trackSelectionListener);
- trackSelectionListener.valueChanged(null);
- }
- }
- /**
- * トラック選択リスナー
- */
- ListSelectionListener trackSelectionListener = new ListSelectionListener() {
- @Override
- public void valueChanged(ListSelectionEvent e) {
- if( e != null && e.getValueIsAdjusting() ) return;
- ListSelectionModel selModel = getModel().getSelectionModel();
- deleteTrackAction.setEnabled(! selModel.isSelectionEmpty());
- eventListTable.updateTo(getModel());
- }
- };
- /**
- * {@inheritDoc}
- *
- * <p>このトラックリストテーブルのデータが変わったときに編集を解除します。
- * 例えば、イベントが編集された場合や、
- * シーケンサーからこのモデルが外された場合がこれに該当します。
- * </p>
- */
- @Override
- public void tableChanged(TableModelEvent e) {
- super.tableChanged(e);
- cancelCellEditing();
- }
- /**
- * このトラックリストテーブルが編集モードになっていたら解除します。
- */
- private void cancelCellEditing() {
- TableCellEditor currentCellEditor = getCellEditor();
- if( currentCellEditor != null ) currentCellEditor.cancelCellEditing();
- }
- /**
- * トラック追加アクション
- */
- Action addTrackAction = new AbstractAction("New") {
- {
- String tooltip = "Append new track - 新しいトラックの追加";
- putValue(Action.SHORT_DESCRIPTION, tooltip);
- setEnabled(false);
- }
- @Override
- public void actionPerformed(ActionEvent e) { getModel().createTrack(); }
- };
- /**
- * トラック削除アクション
- */
- Action deleteTrackAction = new AbstractAction("Delete", deleteIcon) {
- public static final String CONFIRM_MESSAGE =
- "Do you want to delete selected track ?\n選択したトラックを削除しますか?";
- {
- putValue(Action.SHORT_DESCRIPTION, "Delete selected track - 選択したトラックを削除");
- setEnabled(false);
- }
- @Override
- public void actionPerformed(ActionEvent event) {
- if( JOptionPane.showConfirmDialog(
- ((JComponent)event.getSource()).getRootPane(),
- CONFIRM_MESSAGE,
- ChordHelperApplet.VersionInfo.NAME,
- JOptionPane.YES_NO_OPTION,
- JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION
- ) getModel().deleteSelectedTracks();
- }
- };
- }
-
+ public PlaylistTable playlistTable;
/**
* 新しい {@link MidiSequenceEditorDialog} を構築します。
* @param playlistTableModel このエディタが参照するプレイリストモデル
+ * @param eventDialog MIDIイベント入力ダイアログ
* @param outputMidiDevice イベントテーブルの操作音出力先MIDIデバイス
* @param midiDeviceDialogOpenAction MIDIデバイスダイアログを開くアクション
*/
- public MidiSequenceEditorDialog(PlaylistTableModel playlistTableModel, VirtualMidiDevice outputMidiDevice, Action midiDeviceDialogOpenAction) {
- sequenceListTable = new PlaylistTable(playlistTableModel, midiDeviceDialogOpenAction);
- trackListTable = new SequenceTrackListTable(playlistTableModel.emptyTrackListTableModel);
- eventListTable = new MidiEventTable(playlistTableModel.emptyEventListTableModel, outputMidiDevice);
+ public MidiSequenceEditorDialog(PlaylistTableModel playlistTableModel, MidiEventDialog eventDialog, VirtualMidiDevice outputMidiDevice, Action midiDeviceDialogOpenAction) {
+ playlistTable = new PlaylistTable(playlistTableModel, midiDeviceDialogOpenAction);
+ MidiEventTable eventListTable = new MidiEventTable(playlistTableModel.emptyEventListTableModel, eventDialog, outputMidiDevice);
+ SequenceTrackListTable trackListTable = new SequenceTrackListTable(playlistTableModel.emptyTrackListTableModel, eventListTable);
newSequenceDialog = new NewSequenceDialog(playlistTableModel, outputMidiDevice);
setTitle("MIDI Editor/Playlist - "+ChordHelperApplet.VersionInfo.NAME);
setBounds( 150, 200, 900, 500 );
add(new JButton(newSequenceDialog.openAction) {
{ setMargin(ChordHelperApplet.ZERO_INSETS); }
});
- if( sequenceListTable.midiFileChooser != null ) {
+ if( playlistTable.midiFileChooser != null ) {
add( Box.createRigidArea(new Dimension(5, 0)) );
- add(new JButton(sequenceListTable.midiFileChooser.openMidiFileAction) {
+ add(new JButton(playlistTable.midiFileChooser.openMidiFileAction) {
{ setMargin(ChordHelperApplet.ZERO_INSETS); }
});
}
- if(sequenceListTable.base64EncodeAction != null) {
+ if(playlistTable.base64EncodeAction != null) {
add(Box.createRigidArea(new Dimension(5, 0)));
- add(new JButton(sequenceListTable.base64EncodeAction) {
+ add(new JButton(playlistTable.base64EncodeAction) {
{ setMargin(ChordHelperApplet.ZERO_INSETS); }
});
}
add(new JButton(playlistTableModel.getMoveToBottomAction()) {
{ setMargin(ChordHelperApplet.ZERO_INSETS); }
});
- if( sequenceListTable.midiFileChooser != null ) {
+ if( playlistTable.midiFileChooser != null ) {
add(Box.createRigidArea(new Dimension(5, 0)));
- add(new JButton(sequenceListTable.midiFileChooser.saveMidiFileAction) {
+ add(new JButton(playlistTable.midiFileChooser.saveMidiFileAction) {
{ setMargin(ChordHelperApplet.ZERO_INSETS); }
});
}
add( Box.createRigidArea(new Dimension(5, 0)) );
- add(new JButton(sequenceListTable.deleteSequenceAction) {
+ add(new JButton(playlistTable.deleteSequenceAction) {
{ setMargin(ChordHelperApplet.ZERO_INSETS); }
});
add( Box.createRigidArea(new Dimension(5, 0)) );
}});
}};
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
- add(new JScrollPane(sequenceListTable));
+ add(new JScrollPane(playlistTable));
add(Box.createRigidArea(new Dimension(0, 10)));
add(playlistOperationPanel);
add(Box.createRigidArea(new Dimension(0, 10)));
/**
* プレイリストビューを構築します。
* @param model プレイリストデータモデル
+ * @param midiDeviceDialogOpenAction MIDIデバイスダイアログを開くアクション
*/
public PlaylistTable(PlaylistTableModel model, Action midiDeviceDialogOpenAction) {
super(model, null, model.sequenceListSelectionModel);
new PositionCellEditor();
//
// 文字コード選択をプルダウンにする
- int column = PlaylistTableModel.Column.CHARSET.ordinal();
- TableCellEditor ce = new DefaultCellEditor(new JComboBox<Charset>() {{
- Charset.availableCharsets().values().stream().forEach(v->addItem(v));
- }});
- getColumnModel().getColumn(column).setCellEditor(ce);
+ getColumnModel().getColumn(PlaylistTableModel.Column.CHARSET.ordinal())
+ .setCellEditor(new DefaultCellEditor(new JComboBox<Charset>() {{
+ Charset.availableCharsets().values().stream().forEach(v->addItem(v));
+ }}));
setAutoCreateColumnsFromModel(false);
//
// Base64画面を開くアクションの生成
--- /dev/null
+package camidion.chordhelper.midieditor;
+
+import java.awt.event.ActionEvent;
+import java.util.Arrays;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.DefaultCellEditor;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableColumnModel;
+
+import camidion.chordhelper.ChordHelperApplet;
+import camidion.chordhelper.music.MIDISpec;
+
+/**
+ * シーケンス(トラックリスト)テーブルビュー
+ */
+public class SequenceTrackListTable extends JTable {
+ /**
+ * MIDIイベントリストテーブルビュー(選択中のトラックの中身)
+ */
+ public MidiEventTable eventListTable;
+ /**
+ * トラックリストテーブルビューを構築します。
+ * @param model シーケンス(トラックリスト)データモデル
+ * @param eventListTable イベントリストテーブル
+ */
+ public SequenceTrackListTable(SequenceTrackListTableModel model, MidiEventTable eventListTable) {
+ super(model, null, model.getSelectionModel());
+ this.eventListTable = eventListTable;
+ //
+ // 録音対象のMIDIチャンネルをコンボボックスで選択できるようにする
+ getColumnModel()
+ .getColumn(SequenceTrackListTableModel.Column.RECORD_CHANNEL.ordinal())
+ .setCellEditor(new DefaultCellEditor(new JComboBox<String>(){{
+ addItem("OFF");
+ for(int i=1; i <= MIDISpec.MAX_CHANNELS; i++) addItem(String.format("%d", i));
+ addItem("ALL");
+ }}));
+ setAutoCreateColumnsFromModel(false);
+ model.getParent().sequenceListSelectionModel.addListSelectionListener(titleLabel);
+ TableColumnModel colModel = getColumnModel();
+ Arrays.stream(SequenceTrackListTableModel.Column.values()).forEach(c->
+ colModel.getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
+ );
+ }
+ /**
+ * このテーブルビューが表示するデータを提供する
+ * シーケンス(トラックリスト)データモデルを返します。
+ * @return シーケンス(トラックリスト)データモデル
+ */
+ @Override
+ public SequenceTrackListTableModel getModel() {
+ return (SequenceTrackListTableModel)dataModel;
+ }
+ /**
+ * タイトルラベル
+ */
+ TitleLabel titleLabel = new TitleLabel();
+ /**
+ * 親テーブルの選択シーケンスの変更に反応する
+ * 曲番号表示付きタイトルラベル
+ */
+ private class TitleLabel extends JLabel implements ListSelectionListener {
+ private static final String TITLE = "Tracks";
+ public TitleLabel() { setText(TITLE); }
+ @Override
+ public void valueChanged(ListSelectionEvent event) {
+ if( event.getValueIsAdjusting() ) return;
+ SequenceTrackListTableModel oldModel = getModel();
+ SequenceTrackListTableModel newModel = oldModel.getParent().getSelectedSequenceModel();
+ if( oldModel == newModel ) return;
+ //
+ // MIDIチャンネル選択中のときはキャンセルする
+ cancelCellEditing();
+ //
+ String text = TITLE;
+ ListSelectionModel sm = oldModel.getParent().sequenceListSelectionModel;
+ if( ! sm.isSelectionEmpty() ) {
+ int index = sm.getMinSelectionIndex();
+ if( index >= 0 ) text = String.format(text+" - MIDI file #%d", index);
+ }
+ setText(text);
+ if( newModel == null ) {
+ newModel = oldModel.getParent().emptyTrackListTableModel;
+ addTrackAction.setEnabled(false);
+ }
+ else {
+ addTrackAction.setEnabled(true);
+ }
+ oldModel.getSelectionModel().removeListSelectionListener(trackSelectionListener);
+ setModel(newModel);
+ setSelectionModel(newModel.getSelectionModel());
+ newModel.getSelectionModel().addListSelectionListener(trackSelectionListener);
+ }
+ }
+ /**
+ * {@inheritDoc}
+ *
+ * <p>このトラックリストテーブルのデータが変わったときに編集を解除します。
+ * 例えば、イベントが編集された場合や、
+ * シーケンサーからこのモデルが外された場合がこれに該当します。
+ * </p>
+ */
+ @Override
+ public void tableChanged(TableModelEvent e) {
+ super.tableChanged(e);
+ cancelCellEditing();
+ }
+ /**
+ * このトラックリストテーブルが編集モードになっていたら解除します。
+ */
+ private void cancelCellEditing() {
+ TableCellEditor currentCellEditor = getCellEditor();
+ if( currentCellEditor != null ) currentCellEditor.cancelCellEditing();
+ }
+ /**
+ * トラック追加アクション
+ */
+ Action addTrackAction = new AbstractAction("New") {
+ {
+ String tooltip = "Append new track - 新しいトラックの追加";
+ putValue(Action.SHORT_DESCRIPTION, tooltip);
+ setEnabled(false);
+ }
+ @Override
+ public void actionPerformed(ActionEvent e) { getModel().createTrack(); }
+ };
+ /**
+ * トラック削除アクション
+ */
+ Action deleteTrackAction = new AbstractAction("Delete", MidiSequenceEditorDialog.deleteIcon) {
+ public static final String CONFIRM_MESSAGE =
+ "Do you want to delete selected track ?\n選択したトラックを削除しますか?";
+ {
+ putValue(Action.SHORT_DESCRIPTION, "Delete selected track - 選択したトラックを削除");
+ setEnabled(false);
+ }
+ @Override
+ public void actionPerformed(ActionEvent event) {
+ if( JOptionPane.showConfirmDialog(
+ ((JComponent)event.getSource()).getRootPane(),
+ CONFIRM_MESSAGE,
+ ChordHelperApplet.VersionInfo.NAME,
+ JOptionPane.YES_NO_OPTION,
+ JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION
+ ) getModel().deleteSelectedTracks();
+ }
+ };
+ /**
+ * トラック選択リスナー
+ */
+ private ListSelectionListener trackSelectionListener = event->{
+ if( event.getValueIsAdjusting() ) return;
+ ListSelectionModel selModel = getModel().getSelectionModel();
+ deleteTrackAction.setEnabled(! selModel.isSelectionEmpty());
+ eventListTable.titleLabel.updateTrackNumber(selModel.getMinSelectionIndex());
+ eventListTable.setModel(getModel().getSelectedTrackModel());
+ };
+}
\ No newline at end of file