* プレイリスト上で現在選択されているMIDIシーケンスをシーケンサへロードして再生します。
*/
public void play() {
- play(playlistModel.sequenceListSelectionModel.getMinSelectionIndex());
+ play(playlistModel.getSelectionModel().getMinSelectionIndex());
}
/**
* 指定されたインデックス値が示すプレイリスト上のMIDIシーケンスをシーケンサへロードして再生します。
*/
public static class VersionInfo {
public static final String NAME = "MIDI Chord Helper";
- public static final String VERSION = "Ver.20170421.1";
+ public static final String VERSION = "Ver.20170422.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/";
// 追加するデータを適切な文字コードで文字列に変換
String additionalText;
if( m != null ) {
- additionalText = new String(data,m.charset);
+ additionalText = new String(data,m.getCharset());
}
else try {
additionalText = new String(data,"JISAutoDetect");
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToggleButton;
-import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellEditor;
-import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import camidion.chordhelper.ChordHelperApplet;
/**
* MIDIイベント入力ダイアログ(イベント入力とイベント送出で共用)
*/
- public MidiEventDialog eventDialog;
+ private MidiEventDialog eventDialog;
/**
* 操作音を鳴らすMIDI出力デバイス
*/
private VirtualMidiDevice outputMidiDevice;
/**
+ * イベント選択リスナー
+ */
+ private ListSelectionListener selectionListener;
+ /**
* 新しいイベントリストテーブルを構築します。
* <p>データモデルとして一つのトラックのイベントリストを指定できます。
* トラックを切り替えたいときは {@link #setModel(TableModel)}
super(model, null, model.getSelectionModel());
this.outputMidiDevice = outputMidiDevice;
this.eventDialog = eventDialog;
+ titleLabel = new TitleLabel();
+ Arrays.stream(TrackEventListTableModel.Column.values()).forEach(c->
+ getColumnModel().getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
+ );
pairNoteOnOffModel = new JToggleButton.ToggleButtonModel() {
{
addItemListener(e->eventDialog.midiMessageForm.durationForm.setEnabled(isSelected()));
setSelected(true);
}
};
- //
- // 列モデルにセルエディタを設定
eventCellEditor = new MidiEventCellEditor();
setAutoCreateColumnsFromModel(false);
- //
- eventSelectionListener = new EventSelectionListener();
- titleLabel = new TitleLabel();
- //
- TableColumnModel cm = getColumnModel();
- Arrays.stream(TrackEventListTableModel.Column.values()).forEach(c->
- cm.getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
- );
+ selectionModel.addListSelectionListener(selectionListener = event->{
+ if( event.getValueIsAdjusting() ) return;
+ if( selectionModel.isSelectionEmpty() ) {
+ queryPasteEventAction.setEnabled(false);
+ copyEventAction.setEnabled(false);
+ deleteEventAction.setEnabled(false);
+ cutEventAction.setEnabled(false);
+ }
+ else {
+ copyEventAction.setEnabled(true);
+ deleteEventAction.setEnabled(true);
+ cutEventAction.setEnabled(true);
+ int minIndex = selectionModel.getMinSelectionIndex();
+ MidiEvent midiEvent = model.getMidiEvent(minIndex);
+ if( midiEvent != null ) {
+ MidiMessage msg = midiEvent.getMessage();
+ if( msg instanceof ShortMessage ) {
+ ShortMessage sm = (ShortMessage)msg;
+ int cmd = sm.getCommand();
+ if( cmd == 0x80 || cmd == 0x90 || cmd == 0xA0 ) {
+ // ノート番号を持つ場合、音を鳴らす。
+ MidiChannel outMidiChannels[] = outputMidiDevice.getChannels();
+ int ch = sm.getChannel();
+ int note = sm.getData1();
+ int vel = sm.getData2();
+ outMidiChannels[ch].noteOn(note, vel);
+ outMidiChannels[ch].noteOff(note, vel);
+ }
+ }
+ }
+ if( pairNoteOnOffModel.isSelected() ) {
+ int maxIndex = selectionModel.getMaxSelectionIndex();
+ int partnerIndex;
+ for( int i=minIndex; i<=maxIndex; i++ ) {
+ if( ! selectionModel.isSelectedIndex(i) ) continue;
+ partnerIndex = model.getIndexOfPartnerFor(i);
+ if( partnerIndex >= 0 && ! selectionModel.isSelectedIndex(partnerIndex) )
+ selectionModel.addSelectionInterval(partnerIndex, partnerIndex);
+ }
+ }
+ }
+ });
}
/**
- * このテーブルビューが表示するデータを提供する
- * トラック(イベントリスト)データモデルを返します。
+ * このテーブルビューが表示するデータを提供するトラック(イベントリスト)データモデルを返します。
* @return トラック(イベントリスト)データモデル
*/
@Override
public TrackEventListTableModel getModel() {
return (TrackEventListTableModel) dataModel;
}
+ /**
+ * このテーブルビューが表示するデータを提供するトラック(イベントリスト)データモデルを設定します。
+ * @param model トラック(イベントリスト)データモデル
+ */
public void setModel(TrackEventListTableModel model) {
- TrackEventListTableModel oldModel = getModel();
- if( oldModel == model ) return;
+ if( dataModel == model ) return;
if( model == null ) {
- model = getModel().getParent().getParent().emptyEventListTableModel;
+ PlaylistTableModel playlist = getModel().getParent().getParent();
+ model = playlist.emptyEventListTableModel;
queryJumpEventAction.setEnabled(false);
queryAddEventAction.setEnabled(false);
queryJumpEventAction.setEnabled(true);
queryAddEventAction.setEnabled(true);
}
- oldModel.getSelectionModel().removeListSelectionListener(eventSelectionListener);
+ selectionModel.removeListSelectionListener(selectionListener);
super.setModel(model);
setSelectionModel(model.getSelectionModel());
- model.getSelectionModel().addListSelectionListener(eventSelectionListener);
+ titleLabel.updateTrackNumber(model.getParent().getSelectionModel().getMinSelectionIndex());
+ selectionModel.addListSelectionListener(selectionListener);
}
/**
* タイトルラベル
setText(text);
}
}
-
- /**
- * イベント選択リスナー
- */
- private EventSelectionListener eventSelectionListener;
- /**
- * 選択イベントの変更に反応するリスナー
- */
- private class EventSelectionListener implements ListSelectionListener {
- public EventSelectionListener() {
- getModel().getSelectionModel().addListSelectionListener(this);
- }
- @Override
- public void valueChanged(ListSelectionEvent e) {
- if( e.getValueIsAdjusting() )
- return;
- if( getSelectionModel().isSelectionEmpty() ) {
- queryPasteEventAction.setEnabled(false);
- copyEventAction.setEnabled(false);
- deleteEventAction.setEnabled(false);
- cutEventAction.setEnabled(false);
- }
- else {
- copyEventAction.setEnabled(true);
- deleteEventAction.setEnabled(true);
- cutEventAction.setEnabled(true);
- TrackEventListTableModel trackModel = getModel();
- int minIndex = getSelectionModel().getMinSelectionIndex();
- MidiEvent midiEvent = trackModel.getMidiEvent(minIndex);
- if( midiEvent != null ) {
- MidiMessage msg = midiEvent.getMessage();
- if( msg instanceof ShortMessage ) {
- ShortMessage sm = (ShortMessage)msg;
- int cmd = sm.getCommand();
- if( cmd == 0x80 || cmd == 0x90 || cmd == 0xA0 ) {
- // ノート番号を持つ場合、音を鳴らす。
- MidiChannel outMidiChannels[] = outputMidiDevice.getChannels();
- int ch = sm.getChannel();
- int note = sm.getData1();
- int vel = sm.getData2();
- outMidiChannels[ch].noteOn(note, vel);
- outMidiChannels[ch].noteOff(note, vel);
- }
- }
- }
- if( pairNoteOnOffModel.isSelected() ) {
- int maxIndex = getSelectionModel().getMaxSelectionIndex();
- int partnerIndex;
- for( int i=minIndex; i<=maxIndex; i++ ) {
- if( ! getSelectionModel().isSelectedIndex(i) ) continue;
- partnerIndex = trackModel.getIndexOfPartnerFor(i);
- if( partnerIndex >= 0 && ! getSelectionModel().isSelectedIndex(partnerIndex) )
- getSelectionModel().addSelectionInterval(partnerIndex, partnerIndex);
- }
- }
- }
- }
- }
/**
* Pair noteON/OFF トグルボタンモデル
*/
MidiEvent partnerEvent = null;
eventDialog.midiMessageForm.setMessage(
selectedMidiEvent.getMessage(),
- trackModel.getParent().charset
+ trackModel.getParent().getCharset()
);
if( eventDialog.midiMessageForm.isNote() ) {
int partnerIndex = trackModel.getIndexOfPartnerFor(selectedIndex);
long tick = tickPositionModel.getTickPosition();
MidiMessageForm form = eventDialog.midiMessageForm;
SequenceTrackListTableModel seqModel = trackModel.getParent();
- MidiMessage msg = form.getMessage(seqModel.charset);
+ MidiMessage msg = form.getMessage(seqModel.getCharset());
if( msg == null ) {
return false;
}
ChordHelperApplet.VersionInfo.NAME,
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION
- ) getModel().removeSelectedMidiEvents();
+ ) {
+ getModel().removeMidiEvents(getModel().getSelectedMidiEvents());
+ }
}
};
/**
}
};
/**
+ * プレイリストビュー(シーケンスリスト)
+ */
+ public PlaylistTable playlistTable;
+ /**
* このエディタダイアログが表示しているプレイリストモデルを返します。
* @return プレイリストモデル
*/
*/
public NewSequenceDialog newSequenceDialog;
/**
- * プレイリストビュー(シーケンスリスト)
- */
- public PlaylistTable playlistTable;
- /**
* 新しい {@link MidiSequenceEditorDialog} を構築します。
* @param playlistTableModel このエディタが参照するプレイリストモデル
* @param eventDialog MIDIイベント入力ダイアログ
* @param midiDeviceDialogOpenAction MIDIデバイスダイアログを開くアクション
*/
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);
+ playlistTable = new PlaylistTable(playlistTableModel, midiDeviceDialogOpenAction, trackListTable);
newSequenceDialog = new NewSequenceDialog(playlistTableModel, outputMidiDevice);
setTitle("MIDI Editor/Playlist - "+ChordHelperApplet.VersionInfo.NAME);
setBounds( 150, 200, 900, 500 );
{ setMargin(ChordHelperApplet.ZERO_INSETS); }
});
}
- if(playlistTable.base64EncodeAction != null) {
- add(Box.createRigidArea(new Dimension(5, 0)));
- add(new JButton(playlistTable.base64EncodeAction) {
- { setMargin(ChordHelperApplet.ZERO_INSETS); }
- });
- }
+ add(Box.createRigidArea(new Dimension(5, 0)));
+ add(new JButton(playlistTable.base64EncodeAction) {
+ { setMargin(ChordHelperApplet.ZERO_INSETS); }
+ });
add(Box.createRigidArea(new Dimension(5, 0)));
add(new JButton(playlistTableModel.getMoveToTopAction()) {
{ setMargin(ChordHelperApplet.ZERO_INSETS); }
* プレイリストビューを構築します。
* @param model プレイリストデータモデル
* @param midiDeviceDialogOpenAction MIDIデバイスダイアログを開くアクション
+ * @param trackListTable トラックリストテーブル(子テーブル)
*/
- public PlaylistTable(PlaylistTableModel model, Action midiDeviceDialogOpenAction) {
- super(model, null, model.sequenceListSelectionModel);
+ public PlaylistTable(PlaylistTableModel model, Action midiDeviceDialogOpenAction, SequenceTrackListTable trackListTable) {
+ super(model, null, model.getSelectionModel());
this.midiDeviceDialogOpenAction = midiDeviceDialogOpenAction;
try {
midiFileChooser = new MidiFileChooser();
tc.setPreferredWidth(c.preferredWidth);
if( c == PlaylistTableModel.Column.LENGTH ) lengthColumn = tc;
});
+ selectionModel.addListSelectionListener(event->{
+ if( event.getValueIsAdjusting() ) return;
+ trackListTable.setModel(getModel().getSelectedSequenceModel());
+ });
}
private TableColumn lengthColumn;
@Override
) break;
} catch(Exception ex) {
JOptionPane.showMessageDialog(
- getRootPane(), ex,
- ChordHelperApplet.VersionInfo.NAME,
+ getRootPane(), ex, ChordHelperApplet.VersionInfo.NAME,
JOptionPane.ERROR_MESSAGE);
break;
}
JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION
) return;
}
- if( ! model.sequenceListSelectionModel.isSelectionEmpty() ) try {
- model.remove(model.sequenceListSelectionModel.getMinSelectionIndex());
+ if( ! model.getSelectionModel().isSelectionEmpty() ) try {
+ model.remove(model.getSelectionModel().getMinSelectionIndex());
} catch (Exception ex) {
JOptionPane.showMessageDialog(
- ((JComponent)event.getSource()).getRootPane(),
- ex,
+ ((JComponent)event.getSource()).getRootPane(), ex,
ChordHelperApplet.VersionInfo.NAME,
JOptionPane.ERROR_MESSAGE);
}
}
catch( Exception ex ) {
JOptionPane.showMessageDialog(
- rootPane, ex,
- ChordHelperApplet.VersionInfo.NAME,
+ rootPane, ex, ChordHelperApplet.VersionInfo.NAME,
JOptionPane.ERROR_MESSAGE);
}
}
if( firstIndex >= 0 ) playlist.play(firstIndex);
} catch (Exception ex) {
JOptionPane.showMessageDialog(
- rootPane, ex,
- ChordHelperApplet.VersionInfo.NAME,
+ rootPane, ex, ChordHelperApplet.VersionInfo.NAME,
JOptionPane.ERROR_MESSAGE);
}
}
*/
public final TrackEventListTableModel emptyEventListTableModel = new TrackEventListTableModel(emptyTrackListTableModel, null);
/**
- * 選択されているシーケンスのインデックス
+ * このプレイリストの選択モデルを返します。
*/
- public final ListSelectionModel sequenceListSelectionModel = new DefaultListSelectionModel() {
+ public ListSelectionModel getSelectionModel() { return selectionModel; }
+ private ListSelectionModel selectionModel = new DefaultListSelectionModel() {
{
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
setEnebledBySelection();
}
protected void setEnebledBySelection() {
- int index = sequenceListSelectionModel.getMinSelectionIndex();
+ int index = selectionModel.getMinSelectionIndex();
setEnabled(index >= 0);
}
private void init(String tooltip) {
putValue(Action.SHORT_DESCRIPTION, tooltip);
- sequenceListSelectionModel.addListSelectionListener(this);
+ selectionModel.addListSelectionListener(this);
setEnebledBySelection();
}
}
public boolean isCellEditable() { return true; }
@Override
public Object getValueOf(SequenceTrackListTableModel sequenceModel) {
- return sequenceModel.charset;
+ return sequenceModel.getCharset();
}
},
/** タイミング解像度 */
case CHARSET:
// 文字コードの変更
SequenceTrackListTableModel seq = sequenceModelList.get(row);
- seq.charset = Charset.forName(val.toString());
+ seq.setCharset(Charset.forName(val.toString()));
fireTableCellUpdated(row, column);
// シーケンス名の表示更新
fireTableCellUpdated(row, Column.NAME.ordinal());
* @return 選択されたMIDIシーケンスのテーブルモデル(非選択時はnull)
*/
public SequenceTrackListTableModel getSelectedSequenceModel() {
- if( sequenceListSelectionModel.isSelectionEmpty() ) return null;
- int selectedIndex = sequenceListSelectionModel.getMinSelectionIndex();
+ if( selectionModel.isSelectionEmpty() ) return null;
+ int selectedIndex = selectionModel.getMinSelectionIndex();
if( selectedIndex >= sequenceModelList.size() ) return null;
return sequenceModelList.get(selectedIndex);
}
sequenceModelList.add(new SequenceTrackListTableModel(this, sequence, filename));
int lastIndex = sequenceModelList.size() - 1;
fireTableRowsInserted(lastIndex, lastIndex);
- sequenceListSelectionModel.setSelectionInterval(lastIndex, lastIndex);
+ selectionModel.setSelectionInterval(lastIndex, lastIndex);
return lastIndex;
}
/**
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イベントリストテーブルビュー(選択中のトラックの中身)
+ * トラック追加アクション
+ */
+ 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();
+ }
+ };
+ /**
+ * トラック選択リスナー
*/
- public MidiEventTable eventListTable;
+ private ListSelectionListener trackSelectionListener;
/**
* トラックリストテーブルビューを構築します。
* @param model シーケンス(トラックリスト)データモデル
*/
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("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)
+ getColumnModel().getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
);
+ selectionModel.addListSelectionListener(trackSelectionListener = event->{
+ if( event.getValueIsAdjusting() ) return;
+ deleteTrackAction.setEnabled(! selectionModel.isSelectionEmpty());
+ eventListTable.setModel(getModel().getSelectedTrackModel());
+ });
}
/**
- * このテーブルビューが表示するデータを提供する
- * シーケンス(トラックリスト)データモデルを返します。
+ * このテーブルビューが表示するデータを提供するシーケンス(トラックリスト)データモデルを返します。
* @return シーケンス(トラックリスト)データモデル
*/
@Override
return (SequenceTrackListTableModel)dataModel;
}
/**
- * タイトルラベル
+ * このテーブルビューが表示するデータを提供するシーケンス(トラックリスト)データモデルを設定します。
+ * @param model シーケンス(トラックリスト)データモデル
+ */
+ public void setModel(SequenceTrackListTableModel model) {
+ if( dataModel == model ) return;
+ cancelCellEditing();
+ if( model == null ) {
+ model = getModel().getParent().emptyTrackListTableModel;
+ addTrackAction.setEnabled(false);
+ }
+ else {
+ addTrackAction.setEnabled(true);
+ }
+ selectionModel.clearSelection();
+ selectionModel.removeListSelectionListener(trackSelectionListener);
+ super.setModel(model);
+ setSelectionModel(model.getSelectionModel());
+ titleLabel.setSelection(model.getParent().getSelectionModel());
+ selectionModel.addListSelectionListener(trackSelectionListener);
+ }
+ /**
+ * 曲番号表示付きタイトルラベル
*/
TitleLabel titleLabel = new TitleLabel();
/**
- * 親テーブルの選択シーケンスの変更に反応する
* 曲番号表示付きタイトルラベル
*/
- private class TitleLabel extends JLabel implements ListSelectionListener {
+ private class TitleLabel extends JLabel {
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();
- //
+ public void setSelection(ListSelectionModel sequenceSelectionModel) {
String text = TITLE;
- ListSelectionModel sm = oldModel.getParent().sequenceListSelectionModel;
- if( ! sm.isSelectionEmpty() ) {
- int index = sm.getMinSelectionIndex();
+ if( ! sequenceSelectionModel.isSelectionEmpty() ) {
+ int index = sequenceSelectionModel.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
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
+}
this.preferredWidth = preferredWidth;
}
}
- private PlaylistTableModel sequenceListTableModel;
/**
* このモデルを収容している親のプレイリストを返します。
*/
public PlaylistTableModel getParent() { return sequenceListTableModel; }
- /**
- * ラップされたMIDIシーケンス
- */
- private Sequence sequence;
+ private PlaylistTableModel sequenceListTableModel;
/**
* ラップされたMIDIシーケンスのtickインデックス
*/
private SequenceTickIndex sequenceTickIndex;
/**
- * MIDIファイル名
+ * ファイル名を返します。
+ * @return ファイル名
*/
+ public String getFilename() { return filename; }
private String filename;
/**
- * テキスト部分の文字コード(タイトル、歌詞など)
+ * ファイル名を設定します。
+ * @param filename ファイル名
+ */
+ public void setFilename(String filename) { this.filename = filename; }
+ /**
+ * タイトルや歌詞などで使うテキストの文字コードを返します。
+ * @return テキストの文字コード
+ */
+ public Charset getCharset() { return charset; }
+ private Charset charset = Charset.defaultCharset();
+ /**
+ * タイトルや歌詞などで使うテキストの文字コードを設定します。
+ * @param charset テキストの文字コード
*/
- public Charset charset = Charset.defaultCharset();
+ public void setCharset(Charset charset) { this.charset = charset; }
/**
* トラックリスト
*/
private List<TrackEventListTableModel> trackModelList = new ArrayList<>();
- private ListSelectionModel trackListSelectionModel = new DefaultListSelectionModel(){
+ private ListSelectionModel selectionModel = new DefaultListSelectionModel(){
{
setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
};
/**
- * 選択状態を返します。
+ * このトラックリストの選択モデルを返します。
*/
- public ListSelectionModel getSelectionModel() { return trackListSelectionModel; }
+ public ListSelectionModel getSelectionModel() { return selectionModel; }
/**
* MIDIシーケンスとファイル名から {@link SequenceTrackListTableModel} を構築します。
* @param sequenceListTableModel 親のプレイリスト
* @return MIDIシーケンス
*/
public Sequence getSequence() { return sequence; }
+ private Sequence sequence;
/**
* MIDIシーケンスのマイクロ秒単位の長さを返します。
* 曲が長すぎて {@link Sequence#getMicrosecondLength()} が負数を返してしまった場合の補正も行います。
public void fireTimeSignatureChanged() {
sequenceTickIndex = new SequenceTickIndex(sequence);
}
- private boolean isModified = false;
/**
* 変更されたかどうかを返します。
* @return 変更済みのときtrue
*/
public boolean isModified() { return isModified; }
+ private boolean isModified = false;
/**
* 変更されたかどうかを設定します。
* @param isModified 変更されたときtrue
if( index >= 0 ) sequenceListTableModel.fireTableRowsUpdated(index, index);
}
/**
- * ファイル名を設定します。
- * @param filename ファイル名
- */
- public void setFilename(String filename) { this.filename = filename; }
- /**
- * ファイル名を返します。
- * @return ファイル名
- */
- public String getFilename() { return filename; }
- /**
* このシーケンスを表す文字列としてシーケンス名を返します。シーケンス名がない場合は空文字列を返します。
*/
@Override
byte b[] = MIDISpec.getNameBytesOf(sequence);
return b == null ? "" : new String(b, charset);
}
+
/**
* シーケンス名を設定します。
* @param name シーケンス名
* @return トラックモデル(見つからない場合null)
*/
public TrackEventListTableModel getSelectedTrackModel() {
- if( trackListSelectionModel.isSelectionEmpty() ) return null;
+ if( selectionModel.isSelectionEmpty() ) return null;
Track tracks[] = sequence.getTracks();
if( tracks.length == 0 ) return null;
- Track t = tracks[trackListSelectionModel.getMinSelectionIndex()];
+ Track t = tracks[selectionModel.getMinSelectionIndex()];
return trackModelList.stream().filter(tm -> tm.getTrack() == t).findFirst().orElse(null);
}
/**
setModified(true);
int lastRow = getRowCount() - 1;
fireTableRowsInserted(lastRow, lastRow);
- trackListSelectionModel.setSelectionInterval(lastRow, lastRow);
+ selectionModel.setSelectionInterval(lastRow, lastRow);
return lastRow;
}
/**
* 選択されているトラックを削除します。
*/
public void deleteSelectedTracks() {
- if( trackListSelectionModel.isSelectionEmpty() )
+ if( selectionModel.isSelectionEmpty() )
return;
- int minIndex = trackListSelectionModel.getMinSelectionIndex();
- int maxIndex = trackListSelectionModel.getMaxSelectionIndex();
+ int minIndex = selectionModel.getMinSelectionIndex();
+ int maxIndex = selectionModel.getMaxSelectionIndex();
Track tracks[] = sequence.getTracks();
for( int i = maxIndex; i >= minIndex; i-- ) {
- if( ! trackListSelectionModel.isSelectedIndex(i) ) continue;
+ if( ! selectionModel.isSelectedIndex(i) ) continue;
sequence.deleteTrack(tracks[i]);
trackModelList.remove(i);
}
MESSAGE("MIDI Message", String.class, 300) {
@Override
public Object getValue(SequenceTrackListTableModel seq, MidiEvent event) {
- return MIDISpec.msgToString(event.getMessage(), seq.charset);
+ return MIDISpec.msgToString(event.getMessage(), seq.getCharset());
}
};
private String title;
byte b[] = MIDISpec.getNameBytesOf(track);
if( b == null ) return "";
Charset cs = Charset.defaultCharset();
- if( sequenceTrackListTableModel != null ) cs = sequenceTrackListTableModel.charset;
+ if( sequenceTrackListTableModel != null )
+ cs = sequenceTrackListTableModel.getCharset();
return new String(b, cs);
}
/**
*/
public boolean setString(String name) {
if( name.equals(toString()) || ! MIDISpec.setNameBytesOf(
- track, name.getBytes(sequenceTrackListTableModel.charset))
+ track, name.getBytes(sequenceTrackListTableModel.getCharset()))
) return false;
sequenceTrackListTableModel.setModified(true);
fireTableDataChanged();
if(lastIndex < 0) lastIndex = 0;
fireTableRowsDeleted(oldLastIndex, lastIndex);
}
- /**
- * 引数の選択内容が示すMIDIイベントを除去します。
- * @param selectionModel 選択内容
- */
- public void removeSelectedMidiEvents() {
- removeMidiEvents(getSelectedMidiEvents());
- }
}