import javax.swing.table.TableModel;\r
\r
/**\r
- * MIDI Editor/Playlist for MIDI Chord Helper\r
+ * MIDIエディタ(MIDI Editor/Playlist for MIDI Chord Helper)\r
*\r
* @author\r
* Copyright (C) 2006-2013 Akiyoshi Kamide\r
class MidiEditor extends JDialog\r
implements DropTargetListener, ListSelectionListener, ActionListener\r
{\r
- public static final Insets ZERO_INSETS = new Insets(0,0,0,0);\r
-\r
- MidiDeviceModelList deviceManager;\r
-\r
- SequenceListTableModel seqListModel;\r
- private JFileChooser fileChooser = null;\r
- private Base64Dialog base64Dialog = new Base64Dialog(this);\r
- NewSequenceDialog newSequenceDialog;\r
- MidiEventDialog eventDialog = new MidiEventDialog();\r
-\r
- MidiEvent copied_events[] = null;\r
- int copied_events_PPQ = 0;\r
-\r
- ListSelectionModel seqSelectionModel;\r
- ListSelectionModel track_selection_model;\r
- ListSelectionModel event_selection_model;\r
-\r
- JTable sequence_table_view;\r
- JTable track_table_view;\r
- JTable event_table_view;\r
-\r
- JScrollPane scrollable_sequence_table;\r
- JScrollPane scrollable_track_table_view;\r
- JScrollPane scrollable_event_table_view;\r
-\r
- JLabel totalTimeLabel;\r
- JLabel tracks_label;\r
- JLabel midi_events_label;\r
-\r
- JButton\r
- add_new_sequence_button, delete_sequence_button,\r
- base64_encode_button = null,\r
- add_midi_file_button,\r
- save_midi_file_button,\r
- jump_sequence_button,\r
- add_track_button, remove_track_button,\r
- add_event_button, jump_event_button,\r
- cut_event_button, copy_event_button,\r
- paste_event_button, remove_event_button;\r
-\r
- JCheckBox pair_note_checkbox;\r
-\r
- JButton forward_button;\r
- JButton backward_button;\r
- JToggleButton play_pause_button;\r
-\r
- JSplitPane sequence_split_pane;\r
- JSplitPane track_split_pane;\r
-\r
+ public static final Insets ZERO_INSETS = new Insets(0,0,0,0);\r
+ /**\r
+ * MIDIデバイスモデルリスト\r
+ */\r
+ MidiDeviceModelList deviceModelList;\r
+ /**\r
+ * プレイリストのモデル\r
+ */\r
+ SequenceListTableModel sequenceListTableModel;\r
+ /**\r
+ * このMIDIエディタの仮想MIDIデバイス\r
+ */\r
VirtualMidiDevice virtualMidiDevice = new AbstractVirtualMidiDevice() {\r
+ class MyInfo extends Info {\r
+ protected MyInfo() {\r
+ super("MIDI Editor","Unknown vendor","MIDI sequence editor","");\r
+ }\r
+ }\r
{\r
info = new MyInfo();\r
+ // 送信のみなので MIDI IN はサポートしない\r
setMaxReceivers(0);\r
}\r
- class MyInfo extends Info {\r
- protected MyInfo() {\r
- super(\r
- "MIDI Editor",\r
- "Unknown vendor",\r
- "MIDI sequence editor",\r
- ""\r
- );\r
- }\r
+ };\r
+ /**\r
+ * 新しいMIDIシーケンスを生成するダイアログ\r
+ */\r
+ NewSequenceDialog newSequenceDialog = new NewSequenceDialog(this) {\r
+ {\r
+ setChannels(virtualMidiDevice.getChannels());\r
}\r
};\r
+ /**\r
+ * MIDIイベント入力ダイアログ\r
+ */\r
+ MidiEventDialog eventDialog = new MidiEventDialog();\r
+\r
+ /**\r
+ * MIDIシーケンス選択状態\r
+ */\r
+ ListSelectionModel seqSelectionModel;\r
+ /**\r
+ * MIDIトラック選択状態\r
+ */\r
+ private ListSelectionModel trackSelectionModel;\r
+ /**\r
+ * MIDIイベント選択状態\r
+ */\r
+ private ListSelectionModel eventSelectionModel;\r
+\r
+ /**\r
+ * MIDIシーケンスリストテーブルビュー\r
+ */\r
+ private JTable sequenceListTableView;\r
+ /**\r
+ * MIDIトラックリストテーブルビュー\r
+ */\r
+ private JTable trackListTableView;\r
+ /**\r
+ * MIDIイベントリストテーブルビュー\r
+ */\r
+ private JTable eventListTableView;\r
+ /**\r
+ * スクロール可能なMIDIイベントテーブルビュー\r
+ */\r
+ private JScrollPane scrollableEventTableView;\r
\r
- MidiEventCellEditor event_cell_editor;\r
+ /**\r
+ * 全MIDIシーケンス合計時間表示ラベル\r
+ */\r
+ private JLabel totalTimeLabel = new JLabel();\r
+ /**\r
+ * MIDIトラック数表示ラベル\r
+ */\r
+ private JLabel tracksLabel = new JLabel("Tracks");\r
+ /**\r
+ * MIDIイベント数表示ラベル\r
+ */\r
+ private JLabel midiEventsLabel = new JLabel("No track selected");\r
+\r
+ /**\r
+ * BASE64エンコードボタン(ライブラリが見えている場合のみ有効)\r
+ */\r
+ private JButton base64EncodeButton = null;\r
+ /**\r
+ * MIDIシーケンス追加ボタン\r
+ */\r
+ private JButton addMidiFileButton;\r
+ /**\r
+ * MIDIシーケンス削除ボタン\r
+ */\r
+ private JButton deleteSequenceButton;\r
+ /**\r
+ * MIDIファイル保存ボタン\r
+ */\r
+ private JButton saveMidiFileButton = new JButton("Save") {{\r
+ setMargin(ZERO_INSETS);\r
+ }};\r
+ /**\r
+ * MIDIシーケンスジャンプボタン\r
+ */\r
+ private JButton jumpSequenceButton = new JButton("Jump") {{\r
+ setToolTipText("Move to selected song - 選択した曲へ進む");\r
+ setMargin(ZERO_INSETS);\r
+ addActionListener(\r
+ new ActionListener() {\r
+ public void actionPerformed(ActionEvent e) {\r
+ load(seqSelectionModel.getMinSelectionIndex());\r
+ }\r
+ }\r
+ );\r
+ }};\r
+ /**\r
+ * MIDIトラック追加ボタン\r
+ */\r
+ private JButton addTrackButton = new JButton("New") {{\r
+ setMargin(ZERO_INSETS);\r
+ addActionListener(\r
+ new ActionListener() {\r
+ public void actionPerformed(ActionEvent e) {\r
+ sequenceListTableModel.getSequenceModel(seqSelectionModel).createTrack();\r
+ int trackCount = sequenceListTableModel.getSequenceModel(seqSelectionModel).getRowCount();\r
+ if( trackCount > 0 ) {\r
+ int createdTrackIndex = trackCount - 1;\r
+ trackSelectionModel.setSelectionInterval(createdTrackIndex, createdTrackIndex);\r
+ }\r
+ sequenceListTableModel.fireSequenceChanged(seqSelectionModel);\r
+ }\r
+ }\r
+ );\r
+ }};;\r
+ /**\r
+ * MIDIトラック除去ボタン\r
+ */\r
+ private JButton removeTrackButton;\r
+ /**\r
+ * MIDIイベント除去ボタン\r
+ */\r
+ private JButton removeEventButton;\r
+ /**\r
+ * Pair note on/off チェックボックス\r
+ */\r
+ private JCheckBox pairNoteCheckbox;\r
+ /**\r
+ * ファイル選択ダイアログ\r
+ */\r
+ private JFileChooser fileChooser = null;\r
+ /**\r
+ * BASE64テキスト入力ダイアログ\r
+ */\r
+ private Base64Dialog base64Dialog = new Base64Dialog(this);\r
\r
+ /**\r
+ * MIDIイベント表のセルエディタ\r
+ */\r
class MidiEventCellEditor extends AbstractCellEditor implements TableCellEditor {\r
- MidiEvent[] midi_events_to_be_removed; // 削除対象にする変更前イベント(null可)\r
+ MidiEvent[] midiEventsToBeRemoved; // 削除対象にする変更前イベント(null可)\r
MidiTrackTableModel midi_track_model; // 対象トラック\r
MidiSequenceTableModel seq_model; // 対象シーケンス\r
MidiEvent sel_midi_evt = null; // 選択されたイベント\r
int sel_index = -1; // 選択されたイベントの場所\r
long current_tick = 0; // 選択されたイベントのtick位置\r
\r
- TickPositionModel tick_position_model = new TickPositionModel();\r
+ TickPositionModel tickPositionModel = new TickPositionModel();\r
JToggleButton.ToggleButtonModel\r
- pair_note_on_off_model = new JToggleButton.ToggleButtonModel();\r
-\r
- JButton edit_event_button = new JButton();\r
-\r
- Action cancel_action = new AbstractAction() {\r
- { putValue(NAME,"Cancel"); }\r
- public void actionPerformed(ActionEvent e) {\r
- fireEditingCanceled();\r
- eventDialog.setVisible(false);\r
- }\r
- };\r
+ pairNoteOnOffModel = new JToggleButton.ToggleButtonModel();\r
\r
private void setSelectedEvent() {\r
- seq_model = seqListModel.getSequenceModel(seqSelectionModel);\r
- eventDialog.midiMessageForm.durationForm.setPPQ(\r
- seq_model.getSequence().getResolution()\r
- );\r
- tick_position_model.setSequenceIndex(seq_model.getSequenceTickIndex());\r
+ seq_model = sequenceListTableModel.getSequenceModel(seqSelectionModel);\r
+ eventDialog.midiMessageForm.durationForm.setPPQ(seq_model.getSequence().getResolution());\r
+ tickPositionModel.setSequenceIndex(seq_model.getSequenceTickIndex());\r
sel_index = -1;\r
current_tick = 0;\r
sel_midi_evt = null;\r
- midi_track_model = (MidiTrackTableModel)event_table_view.getModel();\r
- if( ! event_selection_model.isSelectionEmpty() ) {\r
- sel_index = event_selection_model.getMinSelectionIndex();\r
+ midi_track_model = (MidiTrackTableModel)eventListTableView.getModel();\r
+ if( ! eventSelectionModel.isSelectionEmpty() ) {\r
+ sel_index = eventSelectionModel.getMinSelectionIndex();\r
sel_midi_evt = midi_track_model.getMidiEvent(sel_index);\r
current_tick = sel_midi_evt.getTick();\r
- tick_position_model.setTickPosition(current_tick);\r
+ tickPositionModel.setTickPosition(current_tick);\r
}\r
}\r
-\r
- // 指定のTick位置へジャンプ\r
- Action query_jump_event_action = new AbstractAction() {\r
+ /**\r
+ * キャンセルするアクション\r
+ */\r
+ Action cancelAction = new AbstractAction() {\r
+ { putValue(NAME,"Cancel"); }\r
+ public void actionPerformed(ActionEvent e) {\r
+ fireEditingCanceled();\r
+ eventDialog.setVisible(false);\r
+ }\r
+ };\r
+ /**\r
+ * 指定のTick位置へジャンプするアクション\r
+ */\r
+ Action queryJumpEventAction = new AbstractAction() {\r
+ private Action jumpEventAction = new AbstractAction() {\r
+ { putValue(NAME,"Jump"); }\r
+ public void actionPerformed(ActionEvent e) {\r
+ scrollToEventAt(tickPositionModel.getTickPosition());\r
+ eventDialog.setVisible(false);\r
+ }\r
+ };\r
{ putValue(NAME,"Jump to ..."); }\r
public void actionPerformed(ActionEvent e) {\r
setSelectedEvent();\r
eventDialog.setTitle("Jump selection to");\r
- eventDialog.okButton.setAction(jump_event_action);\r
+ eventDialog.okButton.setAction(jumpEventAction);\r
eventDialog.openTickForm();\r
}\r
};\r
- Action jump_event_action = new AbstractAction() {\r
- { putValue(NAME,"Jump"); }\r
- public void actionPerformed(ActionEvent e) {\r
- scrollToEventAt(tick_position_model.getTickPosition());\r
- eventDialog.setVisible(false);\r
- }\r
- };\r
-\r
- // 指定のTick位置へ貼り付け\r
- Action query_paste_event_action = new AbstractAction() {\r
+ /**\r
+ * 指定のTick位置へ貼り付けるアクション\r
+ */\r
+ Action queryPasteEventAction = new AbstractAction() {\r
+ private Action pasteEventAction = new AbstractAction() {\r
+ { putValue(NAME,"Paste"); }\r
+ public void actionPerformed(ActionEvent e) {\r
+ long tick = tickPositionModel.getTickPosition();\r
+ ((MidiTrackTableModel)eventListTableView.getModel()).addMidiEvents(\r
+ copiedEventsToPaste, tick, copiedEventsPPQ\r
+ );\r
+ scrollToEventAt( tick );\r
+ sequenceListTableModel.fireSequenceChanged(seqSelectionModel);\r
+ eventDialog.setVisible(false);\r
+ }\r
+ };\r
{ putValue(NAME,"Paste to ..."); }\r
public void actionPerformed(ActionEvent e) {\r
setSelectedEvent();\r
eventDialog.setTitle("Paste to");\r
- eventDialog.okButton.setAction(paste_event_action);\r
+ eventDialog.okButton.setAction(pasteEventAction);\r
eventDialog.openTickForm();\r
}\r
};\r
- Action paste_event_action = new AbstractAction() {\r
- { putValue(NAME,"Paste"); }\r
- public void actionPerformed(ActionEvent e) {\r
- long tick = tick_position_model.getTickPosition();\r
- ((MidiTrackTableModel)event_table_view.getModel()).addMidiEvents(\r
- copied_events, tick, copied_events_PPQ\r
- );\r
- scrollToEventAt( tick );\r
- seqListModel.fireSequenceChanged(seqSelectionModel);\r
- eventDialog.setVisible(false);\r
- }\r
- };\r
-\r
- // イベントの追加(または変更)\r
- Action query_add_event_action = new AbstractAction() {\r
+ /**\r
+ * 新しいイベントの追加を行うアクション\r
+ */\r
+ Action queryAddEventAction = new AbstractAction() {\r
{ putValue(NAME,"New"); }\r
public void actionPerformed(ActionEvent e) {\r
setSelectedEvent();\r
- midi_events_to_be_removed = null;\r
+ midiEventsToBeRemoved = null;\r
eventDialog.setTitle("Add a new MIDI event");\r
- eventDialog.okButton.setAction(add_event_action);\r
+ eventDialog.okButton.setAction(addEventAction);\r
int ch = midi_track_model.getChannel();\r
if( ch >= 0 ) {\r
eventDialog.midiMessageForm.channelText.setSelectedChannel(ch);\r
eventDialog.openEventForm();\r
}\r
};\r
- Action add_event_action = new AbstractAction() {\r
+ /**\r
+ * イベントの追加(または変更)を行うアクション\r
+ */\r
+ private Action addEventAction = new AbstractAction() {\r
{ putValue(NAME,"OK"); }\r
public void actionPerformed(ActionEvent e) {\r
- long tick = tick_position_model.getTickPosition();\r
+ long tick = tickPositionModel.getTickPosition();\r
MidiMessage midi_msg = eventDialog.midiMessageForm.getMessage();\r
MidiEvent new_midi_event = new MidiEvent(midi_msg,tick);\r
- if( midi_events_to_be_removed != null ) {\r
- midi_track_model.removeMidiEvents(midi_events_to_be_removed);\r
+ if( midiEventsToBeRemoved != null ) {\r
+ midi_track_model.removeMidiEvents(midiEventsToBeRemoved);\r
}\r
if( ! midi_track_model.addMidiEvent(new_midi_event) ) {\r
System.out.println("addMidiEvent failure");\r
return;\r
}\r
if(\r
- pair_note_on_off_model.isSelected() &&\r
+ pairNoteOnOffModel.isSelected() &&\r
eventDialog.midiMessageForm.isNote()\r
) {\r
ShortMessage sm = eventDialog.midiMessageForm.getPartnerMessage();\r
scrollToEventAt( partner_tick > tick ? partner_tick : tick );\r
}\r
}\r
- seqListModel.fireSequenceChanged(seq_model);\r
+ sequenceListTableModel.fireSequenceChanged(seq_model);\r
eventDialog.setVisible(false);\r
fireEditingStopped();\r
}\r
};\r
\r
- // Constructor\r
- //\r
+ JButton editEventButton = new JButton() {{\r
+ setHorizontalAlignment(JButton.LEFT);\r
+ }};\r
+\r
public MidiEventCellEditor() {\r
- edit_event_button.setHorizontalAlignment(JButton.LEFT);\r
- eventDialog.cancel_button.setAction(cancel_action);\r
+ eventDialog.cancelButton.setAction(cancelAction);\r
eventDialog.midiMessageForm.setOutputMidiChannels(virtualMidiDevice.getChannels());\r
- eventDialog.tick_position_form.setModel(tick_position_model);\r
- edit_event_button.addActionListener(\r
+ eventDialog.tickPositionForm.setModel(tickPositionModel);\r
+ editEventButton.addActionListener(\r
new ActionListener() {\r
public void actionPerformed(ActionEvent e) {\r
setSelectedEvent();\r
events[0] = sel_midi_evt;\r
events[1] = partner_event;\r
}\r
- midi_events_to_be_removed = events;\r
+ midiEventsToBeRemoved = events;\r
eventDialog.setTitle("Change MIDI event");\r
- eventDialog.okButton.setAction(add_event_action);\r
+ eventDialog.okButton.setAction(addEventAction);\r
eventDialog.openEventForm();\r
}\r
}\r
);\r
- pair_note_on_off_model.addItemListener(new ItemListener() {\r
+ pairNoteOnOffModel.addItemListener(new ItemListener() {\r
public void itemStateChanged(ItemEvent e) {\r
eventDialog.midiMessageForm.durationForm.setEnabled(\r
- pair_note_on_off_model.isSelected()\r
+ pairNoteOnOffModel.isSelected()\r
);\r
}\r
});\r
- pair_note_on_off_model.setSelected(true);\r
+ pairNoteOnOffModel.setSelected(true);\r
}\r
- // TableCellEditor\r
- //\r
public boolean isCellEditable(EventObject e) {\r
// ダブルクリックで編集\r
return e instanceof MouseEvent && ((MouseEvent)e).getClickCount() == 2;\r
JTable table, Object value, boolean isSelected,\r
int row, int column\r
) {\r
- edit_event_button.setText((String)value);\r
- return edit_event_button;\r
+ editEventButton.setText((String)value);\r
+ return editEventButton;\r
}\r
}\r
\r
- public Action move_to_top_action = new AbstractAction() {\r
+ /**\r
+ * 曲の先頭または前の曲へ戻るアクション\r
+ */\r
+ public Action moveToTopAction = new AbstractAction() {\r
{\r
putValue( SHORT_DESCRIPTION,\r
"Move to top or previous song - 曲の先頭または前の曲へ戻る"\r
putValue( LARGE_ICON_KEY, new ButtonIcon(ButtonIcon.TOP_ICON) );\r
}\r
public void actionPerformed( ActionEvent event ) {\r
- if( deviceManager.getSequencer().getTickPosition() <= 40 )\r
+ if( deviceModelList.getSequencer().getTickPosition() <= 40 )\r
loadNext(-1);\r
- deviceManager.timeRangeModel.setValue(0);\r
+ deviceModelList.timeRangeModel.setValue(0);\r
}\r
};\r
- public Action move_to_bottom_action = new AbstractAction() {\r
+ /**\r
+ * 次の曲へ進むアクション\r
+ */\r
+ public Action moveToBottomAction = new AbstractAction() {\r
{\r
putValue( SHORT_DESCRIPTION, "Move to next song - 次の曲へ進む" );\r
putValue( LARGE_ICON_KEY, new ButtonIcon(ButtonIcon.BOTTOM_ICON) );\r
}\r
public void actionPerformed( ActionEvent event ) {\r
- if( loadNext(1) ) deviceManager.timeRangeModel.setValue(0);\r
+ if( loadNext(1) )\r
+ deviceModelList.timeRangeModel.setValue(0);\r
}\r
};\r
- //\r
- // Constructor\r
- //\r
- public MidiEditor(MidiDeviceModelList deviceManager) {\r
- this.deviceManager = deviceManager;\r
- setTitle("MIDI Editor/Playlist - MIDI Chord Helper");\r
- setBounds( 150, 200, 850, 500 );\r
- setLayout(new FlowLayout());\r
- Icon delete_icon = new ButtonIcon(ButtonIcon.X_ICON);\r
- new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this, true);\r
- totalTimeLabel = new JLabel();\r
- //\r
- // Buttons (Sequence)\r
- //\r
- add_new_sequence_button = new JButton("New");\r
- add_new_sequence_button.setToolTipText("Generate new song - 新しい曲を生成");\r
- add_new_sequence_button.setMargin(ZERO_INSETS);\r
- add_new_sequence_button.addActionListener(\r
+\r
+ /**\r
+ * MIDIイベントセルエディタ\r
+ */\r
+ private MidiEventCellEditor eventCellEditor = new MidiEventCellEditor();\r
+ /**\r
+ * ペースト用にコピーされたMIDIイベントの配列\r
+ */\r
+ private MidiEvent copiedEventsToPaste[] = null;\r
+ /**\r
+ * ペースト用にコピーされたMIDIイベントのタイミング解像度\r
+ */\r
+ private int copiedEventsPPQ = 0;\r
+ /**\r
+ * イベント追加ボタン\r
+ */\r
+ private JButton addEventButton = new JButton(eventCellEditor.queryAddEventAction) {{\r
+ setMargin(ZERO_INSETS);\r
+ }};\r
+ /**\r
+ * イベントジャンプボタン\r
+ */\r
+ private JButton jumpEventButton = new JButton(eventCellEditor.queryJumpEventAction) {{\r
+ setMargin(ZERO_INSETS);\r
+ }};\r
+ /**\r
+ * イベント貼り付けボタン\r
+ */\r
+ private JButton pasteEventButton = new JButton(eventCellEditor.queryPasteEventAction) {{\r
+ setMargin(ZERO_INSETS);\r
+ }};\r
+ /**\r
+ * イベントカットボタン\r
+ */\r
+ private JButton cutEventButton = new JButton("Cut") {{\r
+ setMargin(ZERO_INSETS);\r
+ addActionListener(\r
new ActionListener() {\r
public void actionPerformed(ActionEvent e) {\r
- newSequenceDialog.setVisible(true);\r
+ if( ! confirm("Do you want to cut selected event ?\n選択したMIDIイベントを切り取りますか?"))\r
+ return;\r
+ MidiTrackTableModel trackTableModel = (MidiTrackTableModel)eventListTableView.getModel();\r
+ copiedEventsToPaste = trackTableModel.getMidiEvents( eventSelectionModel );\r
+ copiedEventsPPQ = sequenceListTableModel.getSequenceModel(seqSelectionModel).getSequence().getResolution();\r
+ trackTableModel.removeMidiEvents( copiedEventsToPaste );\r
+ sequenceListTableModel.fireSequenceChanged(seqSelectionModel);\r
}\r
}\r
);\r
- add_midi_file_button = new JButton("Open");\r
- add_midi_file_button.setMargin(ZERO_INSETS);\r
- add_midi_file_button.addActionListener(\r
+ }};\r
+ /**\r
+ * イベントコピーボタン\r
+ */\r
+ private JButton copyEventButton = new JButton("Copy") {{\r
+ setMargin(ZERO_INSETS);\r
+ addActionListener(\r
new ActionListener() {\r
public void actionPerformed(ActionEvent e) {\r
- if(\r
- fileChooser == null ||\r
- fileChooser.showOpenDialog(MidiEditor.this) != JFileChooser.APPROVE_OPTION\r
- ) return;\r
- addSequenceFromMidiFile(fileChooser.getSelectedFile());\r
+ copiedEventsToPaste = ((MidiTrackTableModel)eventListTableView.getModel()).getMidiEvents(eventSelectionModel);\r
+ copiedEventsPPQ = sequenceListTableModel.getSequenceModel(seqSelectionModel).getSequence().getResolution();\r
+ updateButtonStatus();\r
}\r
}\r
);\r
- //\r
- play_pause_button = new JToggleButton(deviceManager.timeRangeModel.startStopAction);\r
- backward_button = new JButton(move_to_top_action);\r
- backward_button.setMargin(ZERO_INSETS);\r
- forward_button = new JButton(move_to_bottom_action);\r
- forward_button.setMargin(ZERO_INSETS);\r
- //\r
- jump_sequence_button = new JButton("Jump");\r
- jump_sequence_button.setToolTipText("Move to selected song - 選択した曲へ進む");\r
- jump_sequence_button.setMargin(ZERO_INSETS);\r
- jump_sequence_button.addActionListener(\r
- new ActionListener() {\r
- public void actionPerformed(ActionEvent e) {\r
- load( seqSelectionModel.getMinSelectionIndex() );\r
+ }};\r
+ /**\r
+ * 再生/一時停止ボタン\r
+ */\r
+ private JToggleButton playPauseButton;\r
+\r
+ /**\r
+ * 新しい {@link MidiEditor} を構築します。\r
+ * @param deviceModelList MIDIデバイスモデルリスト\r
+ */\r
+ public MidiEditor(MidiDeviceModelList deviceModelList) {\r
+ this.deviceModelList = deviceModelList;\r
+ setTitle("MIDI Editor/Playlist - MIDI Chord Helper");\r
+ setBounds( 150, 200, 850, 500 );\r
+ setLayout(new FlowLayout());\r
+ new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this, true);\r
+ addMidiFileButton = new JButton("Open") {{\r
+ setMargin(ZERO_INSETS);\r
+ addActionListener(\r
+ new ActionListener() {\r
+ public void actionPerformed(ActionEvent e) {\r
+ if(\r
+ fileChooser == null ||\r
+ fileChooser.showOpenDialog(MidiEditor.this) != JFileChooser.APPROVE_OPTION\r
+ ) return;\r
+ addSequenceFromMidiFile(fileChooser.getSelectedFile());\r
+ }\r
}\r
- }\r
- );\r
- save_midi_file_button = new JButton("Save");\r
- save_midi_file_button.setMargin(ZERO_INSETS);\r
- save_midi_file_button.addActionListener(\r
+ );\r
+ }};\r
+ playPauseButton = new JToggleButton(deviceModelList.timeRangeModel.startStopAction);\r
+ saveMidiFileButton.addActionListener(\r
new ActionListener() {\r
public void actionPerformed(ActionEvent e) {\r
if( fileChooser == null ) return;\r
File midi_file;\r
MidiSequenceTableModel seq_model =\r
- seqListModel.getSequenceModel(seqSelectionModel);\r
+ sequenceListTableModel.getSequenceModel(seqSelectionModel);\r
String filename = seq_model.getFilename();\r
if( filename != null && ! filename.isEmpty() ) {\r
midi_file = new File(filename);\r
}\r
}\r
);\r
- delete_sequence_button = new JButton("Delete", delete_icon);\r
- delete_sequence_button.setMargin(ZERO_INSETS);\r
- delete_sequence_button.addActionListener(\r
- new ActionListener() {\r
- public void actionPerformed(ActionEvent e) {\r
- if(\r
- fileChooser != null &&\r
- seqListModel.getSequenceModel(seqSelectionModel).isModified() &&\r
- ! confirm(\r
- "Selected MIDI sequence not saved - delete it ?\n" +\r
- "選択したMIDIシーケンスは保存されていませんが、削除しますか?"\r
- )\r
- ) return;\r
- seqListModel.removeSequence(seqSelectionModel);\r
- totalTimeLabel.setText( seqListModel.getTotalLength() );\r
- }\r
- }\r
- );\r
- //\r
- // Buttons (Track)\r
- //\r
- tracks_label = new JLabel("Tracks");\r
- add_track_button = new JButton("New");\r
- add_track_button.setMargin(ZERO_INSETS);\r
- add_track_button.addActionListener(\r
+ Icon deleteIcon = new ButtonIcon(ButtonIcon.X_ICON);\r
+ deleteSequenceButton = new JButton("Delete", deleteIcon) {{\r
+ setMargin(ZERO_INSETS);\r
+ addActionListener(\r
new ActionListener() {\r
public void actionPerformed(ActionEvent e) {\r
- seqListModel.getSequenceModel(seqSelectionModel).createTrack();\r
- int n_tracks = seqListModel.getSequenceModel(seqSelectionModel).getRowCount();\r
- if( n_tracks > 0 ) {\r
- // Select a created track\r
- track_selection_model.setSelectionInterval(\r
- n_tracks - 1, n_tracks - 1\r
- );\r
+ if( fileChooser != null ) {\r
+ // ファイルに保存できる場合(Javaアプレットではなく、Javaアプリとして動作している場合)\r
+ MidiSequenceTableModel seqModel = sequenceListTableModel.getSequenceModel(seqSelectionModel);\r
+ if( seqModel.isModified() ) {\r
+ // ファイル未保存の変更がある場合\r
+ String confirmMessage =\r
+ "Selected MIDI sequence not saved - delete it ?\n" +\r
+ "選択したMIDIシーケンスは保存されていませんが、削除しますか?";\r
+ if( ! confirm(confirmMessage) ) {\r
+ // ユーザに確認してNoって言われた場合\r
+ return;\r
+ }\r
+ }\r
}\r
- seqListModel.fireSequenceChanged(seqSelectionModel);\r
+ // 削除を実行\r
+ sequenceListTableModel.removeSequence(seqSelectionModel);\r
+ // 削除された分、合計時間が短くなったはずなので表示を更新\r
+ totalTimeLabel.setText(sequenceListTableModel.getTotalLength());\r
}\r
}\r
- );\r
- remove_track_button = new JButton("Delete", delete_icon);\r
- remove_track_button.setMargin(ZERO_INSETS);\r
- remove_track_button.addActionListener(\r
+ );\r
+ }};\r
+ removeTrackButton = new JButton("Delete", deleteIcon) {{\r
+ setMargin(ZERO_INSETS);\r
+ addActionListener(\r
new ActionListener() {\r
public void actionPerformed(ActionEvent e) {\r
- if( ! confirm(\r
- "Do you want to delete selected track ?\n選択したトラックを削除しますか?"\r
- )) return;\r
- seqListModel.getSequenceModel(\r
- seqSelectionModel\r
- ).deleteTracks( track_selection_model );\r
- seqListModel.fireSequenceChanged(seqSelectionModel);\r
+ if( ! confirm("Do you want to delete selected track ?\n選択したトラックを削除しますか?"))\r
+ return;\r
+ sequenceListTableModel.getSequenceModel(seqSelectionModel).deleteTracks(trackSelectionModel);\r
+ sequenceListTableModel.fireSequenceChanged(seqSelectionModel);\r
}\r
}\r
- );\r
- JPanel track_button_panel = new JPanel();\r
- track_button_panel.add(add_track_button);\r
- track_button_panel.add(remove_track_button);\r
- //\r
- // Buttons (Event)\r
- //\r
- event_cell_editor = new MidiEventCellEditor();\r
- add_event_button = new JButton(event_cell_editor.query_add_event_action);\r
- add_event_button.setMargin(ZERO_INSETS);\r
- jump_event_button = new JButton(event_cell_editor.query_jump_event_action);\r
- jump_event_button.setMargin(ZERO_INSETS);\r
- paste_event_button = new JButton(event_cell_editor.query_paste_event_action);\r
- paste_event_button.setMargin(ZERO_INSETS);\r
- remove_event_button = new JButton("Delete", delete_icon);\r
- remove_event_button.setMargin(ZERO_INSETS);\r
- remove_event_button.addActionListener(\r
- new ActionListener() {\r
- public void actionPerformed(ActionEvent e) {\r
- if( ! confirm(\r
- "Do you want to delete selected event ?\n選択したMIDIイベントを削除しますか?"\r
- )) return;\r
- ((MidiTrackTableModel)event_table_view.getModel()).removeMidiEvents( event_selection_model );\r
- seqListModel.fireSequenceChanged(seqSelectionModel);\r
- }\r
- }\r
- );\r
- cut_event_button = new JButton("Cut");\r
- cut_event_button.setMargin(ZERO_INSETS);\r
- cut_event_button.addActionListener(\r
- new ActionListener() {\r
- public void actionPerformed(ActionEvent e) {\r
- if( ! confirm(\r
- "Do you want to cut selected event ?\n選択したMIDIイベントを切り取りますか?"\r
- )) return;\r
- MidiTrackTableModel track_model = (MidiTrackTableModel)event_table_view.getModel();\r
- copied_events = track_model.getMidiEvents( event_selection_model );\r
- copied_events_PPQ = seqListModel.getSequenceModel(\r
- seqSelectionModel\r
- ).getSequence().getResolution();\r
- track_model.removeMidiEvents( copied_events );\r
- seqListModel.fireSequenceChanged(seqSelectionModel);\r
- }\r
- }\r
- );\r
- copy_event_button = new JButton("Copy");\r
- copy_event_button.setMargin(ZERO_INSETS);\r
- copy_event_button.addActionListener(\r
- new ActionListener() {\r
- public void actionPerformed(ActionEvent e) {\r
- copied_events = ((MidiTrackTableModel)event_table_view.getModel()).getMidiEvents(\r
- event_selection_model\r
- );\r
- copied_events_PPQ = seqListModel.getSequenceModel(\r
- seqSelectionModel\r
- ).getSequence().getResolution();\r
- updateButtonStatus();\r
+ );\r
+ }};\r
+ removeEventButton = new JButton("Delete", deleteIcon) {{\r
+ setMargin(ZERO_INSETS);\r
+ addActionListener(\r
+ new ActionListener() {\r
+ public void actionPerformed(ActionEvent e) {\r
+ if( ! confirm("Do you want to delete selected event ?\n選択したMIDIイベントを削除しますか?"))\r
+ return;\r
+ ((MidiTrackTableModel)eventListTableView.getModel()).removeMidiEvents(eventSelectionModel);\r
+ sequenceListTableModel.fireSequenceChanged(seqSelectionModel);\r
+ }\r
}\r
- }\r
- );\r
- pair_note_checkbox = new JCheckBox( "Pair NoteON/OFF" );\r
- pair_note_checkbox.setModel(event_cell_editor.pair_note_on_off_model);\r
+ );\r
+ }};\r
//\r
// Tables\r
//\r
- MidiSequenceTableModel empty_track_table_model = new MidiSequenceTableModel(\r
- seqListModel = new SequenceListTableModel(deviceManager)\r
+ MidiSequenceTableModel emptyTrackTableModel = new MidiSequenceTableModel(\r
+ sequenceListTableModel = new SequenceListTableModel(deviceModelList)\r
);\r
- sequence_table_view = new JTable( seqListModel );\r
- track_table_view = new JTable( empty_track_table_model );\r
- event_table_view = new JTable( new MidiTrackTableModel() );\r
+ sequenceListTableView = new JTable(sequenceListTableModel);\r
+ trackListTableView = new JTable(emptyTrackTableModel);\r
+ eventListTableView = new JTable(new MidiTrackTableModel());\r
//\r
- seqListModel.sizeColumnWidthToFit( sequence_table_view );\r
+ sequenceListTableModel.sizeColumnWidthToFit(sequenceListTableView);\r
+ emptyTrackTableModel.sizeColumnWidthToFit(trackListTableView.getColumnModel());\r
//\r
- TableColumnModel track_column_model = track_table_view.getColumnModel();\r
- empty_track_table_model.sizeColumnWidthToFit(track_column_model);\r
- //\r
- seqSelectionModel = sequence_table_view.getSelectionModel();\r
+ seqSelectionModel = sequenceListTableView.getSelectionModel();\r
seqSelectionModel.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );\r
seqSelectionModel.addListSelectionListener(\r
new ListSelectionListener() {\r
public void valueChanged(ListSelectionEvent e) {\r
if( e.getValueIsAdjusting() ) return;\r
sequenceSelectionChanged();\r
- track_selection_model.setSelectionInterval(0,0);\r
+ trackSelectionModel.setSelectionInterval(0,0);\r
}\r
}\r
);\r
- JScrollPane scrollable_sequence_table = new JScrollPane(sequence_table_view);\r
//\r
- track_selection_model = track_table_view.getSelectionModel();\r
- track_selection_model.setSelectionMode(\r
- ListSelectionModel.MULTIPLE_INTERVAL_SELECTION\r
- );\r
- track_selection_model.addListSelectionListener(this);\r
- JScrollPane scrollable_track_table_view\r
- = new JScrollPane(track_table_view);\r
+ trackSelectionModel = trackListTableView.getSelectionModel();\r
+ trackSelectionModel.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\r
+ trackSelectionModel.addListSelectionListener(this);\r
+ //\r
+ eventSelectionModel = eventListTableView.getSelectionModel();\r
+ eventSelectionModel.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\r
+ eventSelectionModel.addListSelectionListener(this);\r
//\r
- event_selection_model = event_table_view.getSelectionModel();\r
- event_selection_model.setSelectionMode(\r
- ListSelectionModel.MULTIPLE_INTERVAL_SELECTION\r
- );\r
- event_selection_model.addListSelectionListener(this);\r
- scrollable_event_table_view\r
- = new JScrollPane(event_table_view);\r
-\r
if( base64Dialog.isBase64Available() ) {\r
- base64_encode_button = new JButton( "Base64 Encode" );\r
- base64_encode_button.setMargin(ZERO_INSETS);\r
- base64_encode_button.addActionListener(\r
- new ActionListener() {\r
- public void actionPerformed(ActionEvent e) {\r
- MidiSequenceTableModel seq_model =\r
- seqListModel.getSequenceModel(seqSelectionModel);\r
- base64Dialog.setMIDIData(\r
- seq_model.getMIDIdata(), seq_model.getFilename()\r
- );\r
- base64Dialog.setVisible(true);\r
+ base64EncodeButton = new JButton("Base64 Encode") {{\r
+ setMargin(ZERO_INSETS);\r
+ addActionListener(\r
+ new ActionListener() {\r
+ public void actionPerformed(ActionEvent e) {\r
+ MidiSequenceTableModel mstm = sequenceListTableModel.getSequenceModel(seqSelectionModel);\r
+ base64Dialog.setMIDIData(mstm.getMIDIdata(), mstm.getFilename());\r
+ base64Dialog.setVisible(true);\r
+ }\r
}\r
- }\r
- );\r
- }\r
- newSequenceDialog = new NewSequenceDialog(this);\r
- newSequenceDialog.setChannels(virtualMidiDevice.getChannels());\r
-\r
- JPanel button_panel = new JPanel();\r
- button_panel.setLayout( new BoxLayout( button_panel, BoxLayout.LINE_AXIS ) );\r
- button_panel.add( totalTimeLabel );\r
- button_panel.add( Box.createRigidArea(new Dimension(10, 0)) );\r
- button_panel.add( add_new_sequence_button );\r
- button_panel.add( Box.createRigidArea(new Dimension(5, 0)) );\r
- button_panel.add( add_midi_file_button );\r
- button_panel.add( Box.createRigidArea(new Dimension(5, 0)) );\r
- button_panel.add( backward_button );\r
- button_panel.add( Box.createRigidArea(new Dimension(5, 0)) );\r
- button_panel.add( play_pause_button );\r
- button_panel.add( Box.createRigidArea(new Dimension(5, 0)) );\r
- button_panel.add( forward_button );\r
- button_panel.add( Box.createRigidArea(new Dimension(5, 0)) );\r
- button_panel.add( jump_sequence_button );\r
- button_panel.add( Box.createRigidArea(new Dimension(5, 0)) );\r
- button_panel.add( save_midi_file_button );\r
- if( base64_encode_button != null ) {\r
- button_panel.add( Box.createRigidArea(new Dimension(5, 0)) );\r
- button_panel.add( base64_encode_button );\r
- }\r
- button_panel.add( Box.createRigidArea(new Dimension(5, 0)) );\r
- button_panel.add( delete_sequence_button );\r
- button_panel.add( Box.createRigidArea(new Dimension(5, 0)) );\r
- button_panel.add( new SpeedSlider(deviceManager.speedSliderModel) );\r
-\r
- JPanel playlist_panel = new JPanel();\r
- playlist_panel.setLayout(\r
- new BoxLayout( playlist_panel, BoxLayout.Y_AXIS )\r
);\r
- playlist_panel.add( scrollable_sequence_table );\r
- playlist_panel.add( Box.createRigidArea(new Dimension(0, 10)) );\r
- playlist_panel.add( button_panel );\r
- playlist_panel.add( Box.createRigidArea(new Dimension(0, 10)) );\r
+ }};\r
+ }\r
+ JPanel buttonPanel = new JPanel() {{\r
+ setLayout( new BoxLayout(this, BoxLayout.LINE_AXIS ));\r
+ add( totalTimeLabel );\r
+ add( Box.createRigidArea(new Dimension(10, 0)) );\r
+ add( new JButton("New") {{\r
+ setToolTipText("Generate new song - 新しい曲を生成");\r
+ setMargin(ZERO_INSETS);\r
+ addActionListener(\r
+ new ActionListener() {\r
+ public void actionPerformed(ActionEvent e) {\r
+ newSequenceDialog.setVisible(true);\r
+ }\r
+ }\r
+ );\r
+ }});\r
+ add( Box.createRigidArea(new Dimension(5, 0)) );\r
+ add( addMidiFileButton );\r
+ add( Box.createRigidArea(new Dimension(5, 0)) );\r
+ add( new JButton(moveToTopAction) {{setMargin(ZERO_INSETS);}} );\r
+ add( Box.createRigidArea(new Dimension(5, 0)) );\r
+ add( playPauseButton );\r
+ add( Box.createRigidArea(new Dimension(5, 0)) );\r
+ add( new JButton(moveToBottomAction) {{setMargin(ZERO_INSETS);}} );\r
+ add( Box.createRigidArea(new Dimension(5, 0)) );\r
+ add( jumpSequenceButton );\r
+ add( Box.createRigidArea(new Dimension(5, 0)) );\r
+ add( saveMidiFileButton );\r
+ if( base64EncodeButton != null ) {\r
+ add( Box.createRigidArea(new Dimension(5, 0)) );\r
+ add( base64EncodeButton );\r
+ }\r
+ add( Box.createRigidArea(new Dimension(5, 0)) );\r
+ add( deleteSequenceButton );\r
+ add( Box.createRigidArea(new Dimension(5, 0)) );\r
+ }};\r
+ buttonPanel.add(new SequencerSpeedSlider(deviceModelList.speedSliderModel));\r
+\r
+ JPanel playlistPanel = new JPanel() {{\r
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));\r
+ add(new JScrollPane(sequenceListTableView));\r
+ add(Box.createRigidArea(new Dimension(0, 10)));\r
+ }};\r
+ playlistPanel.add( buttonPanel );\r
+ playlistPanel.add( Box.createRigidArea(new Dimension(0, 10)) );\r
\r
sequenceSelectionChanged();\r
- totalTimeLabel.setText( seqListModel.getTotalLength() );\r
+ totalTimeLabel.setText( sequenceListTableModel.getTotalLength() );\r
\r
try {\r
fileChooser = new JFileChooser();\r
}\r
if( fileChooser == null ) {\r
// Applet cannot access local files\r
- add_midi_file_button.setVisible(false);\r
- save_midi_file_button.setVisible(false);\r
- }\r
- //\r
- // Lists and input panel\r
- //\r
- JPanel track_list_panel = new JPanel();\r
- track_list_panel.setLayout(new BoxLayout( track_list_panel, BoxLayout.PAGE_AXIS ));\r
- track_list_panel.add( tracks_label );\r
- track_list_panel.add( Box.createRigidArea(new Dimension(0, 5)) );\r
- track_list_panel.add( scrollable_track_table_view );\r
- track_list_panel.add( Box.createRigidArea(new Dimension(0, 5)) );\r
- track_list_panel.add( track_button_panel );\r
- //\r
- JPanel event_list_panel = new JPanel();\r
- event_list_panel.add( midi_events_label = new JLabel("No track selected") );\r
- event_list_panel.add(scrollable_event_table_view);\r
- //\r
- JPanel event_button_panel = new JPanel();\r
- event_button_panel.add(pair_note_checkbox);\r
- event_button_panel.add(jump_event_button);\r
- event_button_panel.add(add_event_button);\r
- event_button_panel.add(copy_event_button);\r
- event_button_panel.add(cut_event_button);\r
- event_button_panel.add(paste_event_button);\r
- event_button_panel.add(remove_event_button);\r
- //\r
- event_list_panel.add( event_button_panel );\r
- event_list_panel.setLayout(\r
- new BoxLayout( event_list_panel, BoxLayout.Y_AXIS )\r
+ addMidiFileButton.setVisible(false);\r
+ saveMidiFileButton.setVisible(false);\r
+ }\r
+ JPanel trackListPanel = new JPanel() {{\r
+ setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));\r
+ add( tracksLabel);\r
+ add( Box.createRigidArea(new Dimension(0, 5)) );\r
+ add( new JScrollPane(trackListTableView));\r
+ add( Box.createRigidArea(new Dimension(0, 5)) );\r
+ add( new JPanel() {{\r
+ add(addTrackButton);\r
+ add(removeTrackButton);\r
+ }});\r
+ }};\r
+ JPanel eventListPanel = new JPanel() {{\r
+ add(midiEventsLabel);\r
+ add(scrollableEventTableView = new JScrollPane(eventListTableView));\r
+ add(new JPanel() {{\r
+ add(\r
+ pairNoteCheckbox = new JCheckBox("Pair NoteON/OFF") {{\r
+ setModel(eventCellEditor.pairNoteOnOffModel);\r
+ }}\r
);\r
- //\r
- track_split_pane = new JSplitPane(\r
- JSplitPane.HORIZONTAL_SPLIT,\r
- track_list_panel, event_list_panel\r
- );\r
- track_split_pane.setDividerLocation(300);\r
- sequence_split_pane = new JSplitPane(\r
- JSplitPane.VERTICAL_SPLIT,\r
- playlist_panel, track_split_pane\r
- );\r
- sequence_split_pane.setDividerLocation(160);\r
+ add(jumpEventButton);\r
+ add(addEventButton);\r
+ add(copyEventButton);\r
+ add(cutEventButton);\r
+ add(pasteEventButton);\r
+ add(removeEventButton);\r
+ }});\r
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));\r
+ }};\r
+\r
Container cp = getContentPane();\r
- cp.setLayout( new BoxLayout( cp, BoxLayout.Y_AXIS ) );\r
+ cp.setLayout(new BoxLayout(cp, BoxLayout.Y_AXIS));\r
cp.add(Box.createVerticalStrut(2));\r
- cp.add(sequence_split_pane);\r
- //\r
+ cp.add(\r
+ new JSplitPane(JSplitPane.VERTICAL_SPLIT, playlistPanel,\r
+ new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, trackListPanel, eventListPanel) {{\r
+ setDividerLocation(300);\r
+ }}\r
+ ) {{\r
+ setDividerLocation(160);\r
+ }}\r
+ );\r
seqSelectionModel.setSelectionInterval(0,0);\r
updateButtonStatus();\r
}\r
boolean is_adjusting = e.getValueIsAdjusting();\r
if( is_adjusting ) return;\r
Object src = e.getSource();\r
- if( src == track_selection_model ) {\r
+ if( src == trackSelectionModel ) {\r
if(\r
- seqListModel.getSequenceModel(seqSelectionModel) == null\r
+ sequenceListTableModel.getSequenceModel(seqSelectionModel) == null\r
||\r
- track_selection_model.isSelectionEmpty()\r
+ trackSelectionModel.isSelectionEmpty()\r
) {\r
- midi_events_label.setText("MIDI Events (No track selected)");\r
- event_table_view.setModel(new MidiTrackTableModel());\r
+ midiEventsLabel.setText("MIDI Events (No track selected)");\r
+ eventListTableView.setModel(new MidiTrackTableModel());\r
}\r
else {\r
- int sel_index = track_selection_model.getMinSelectionIndex();\r
+ int sel_index = trackSelectionModel.getMinSelectionIndex();\r
MidiTrackTableModel track_model\r
- = seqListModel.getSequenceModel(seqSelectionModel).getTrackModel(sel_index);\r
+ = sequenceListTableModel.getSequenceModel(seqSelectionModel).getTrackModel(sel_index);\r
if( track_model == null ) {\r
- midi_events_label.setText("MIDI Events (No track selected)");\r
- event_table_view.setModel(new MidiTrackTableModel());\r
+ midiEventsLabel.setText("MIDI Events (No track selected)");\r
+ eventListTableView.setModel(new MidiTrackTableModel());\r
}\r
else {\r
- midi_events_label.setText(\r
+ midiEventsLabel.setText(\r
String.format("MIDI Events (in track No.%d)", sel_index)\r
);\r
- event_table_view.setModel(track_model);\r
- TableColumnModel tcm = event_table_view.getColumnModel();\r
+ eventListTableView.setModel(track_model);\r
+ TableColumnModel tcm = eventListTableView.getColumnModel();\r
track_model.sizeColumnWidthToFit(tcm);\r
- tcm.getColumn( MidiTrackTableModel.COLUMN_MESSAGE ).setCellEditor(event_cell_editor);\r
+ tcm.getColumn( MidiTrackTableModel.COLUMN_MESSAGE ).setCellEditor(eventCellEditor);\r
}\r
}\r
updateButtonStatus();\r
- event_selection_model.setSelectionInterval(0,0);\r
+ eventSelectionModel.setSelectionInterval(0,0);\r
}\r
- else if( src == event_selection_model ) {\r
- if( ! event_selection_model.isSelectionEmpty() ) {\r
+ else if( src == eventSelectionModel ) {\r
+ if( ! eventSelectionModel.isSelectionEmpty() ) {\r
MidiTrackTableModel track_model\r
- = (MidiTrackTableModel)event_table_view.getModel();\r
- int min_index = event_selection_model.getMinSelectionIndex();\r
+ = (MidiTrackTableModel)eventListTableView.getModel();\r
+ int min_index = eventSelectionModel.getMinSelectionIndex();\r
if( track_model.hasTrack() ) {\r
MidiEvent midi_event = track_model.getMidiEvent(min_index);\r
MidiMessage msg = midi_event.getMessage();\r
}\r
}\r
}\r
- if( pair_note_checkbox.isSelected() ) {\r
- int max_index = event_selection_model.getMaxSelectionIndex();\r
+ if( pairNoteCheckbox.isSelected() ) {\r
+ int max_index = eventSelectionModel.getMaxSelectionIndex();\r
int partner_index;\r
for( int i=min_index; i<=max_index; i++ ) {\r
if(\r
- event_selection_model.isSelectedIndex(i)\r
- &&\r
- (partner_index = track_model.getIndexOfPartnerFor(i)) >= 0\r
- &&\r
- ! event_selection_model.isSelectedIndex(partner_index)\r
- ) {\r
- event_selection_model.addSelectionInterval(\r
- partner_index, partner_index\r
- );\r
+ eventSelectionModel.isSelectedIndex(i)\r
+ &&\r
+ (partner_index = track_model.getIndexOfPartnerFor(i)) >= 0\r
+ &&\r
+ ! eventSelectionModel.isSelectedIndex(partner_index)\r
+ ) {\r
+ eventSelectionModel.addSelectionInterval(\r
+ partner_index, partner_index\r
+ );\r
}\r
}\r
}\r
}\r
public void sequenceSelectionChanged() {\r
MidiSequenceTableModel seq_model\r
- = seqListModel.getSequenceModel(seqSelectionModel);\r
- jump_sequence_button.setEnabled( seq_model != null );\r
- save_midi_file_button.setEnabled( seq_model != null );\r
- add_track_button.setEnabled( seq_model != null );\r
- if( base64_encode_button != null )\r
- base64_encode_button.setEnabled( seq_model != null );\r
+ = sequenceListTableModel.getSequenceModel(seqSelectionModel);\r
+ jumpSequenceButton.setEnabled( seq_model != null );\r
+ saveMidiFileButton.setEnabled( seq_model != null );\r
+ addTrackButton.setEnabled( seq_model != null );\r
+ if( base64EncodeButton != null )\r
+ base64EncodeButton.setEnabled( seq_model != null );\r
\r
if( seq_model != null ) {\r
int sel_index = seqSelectionModel.getMinSelectionIndex();\r
- delete_sequence_button.setEnabled(true);\r
- track_table_view.setModel(seq_model);\r
- TableColumnModel tcm = track_table_view.getColumnModel();\r
+ deleteSequenceButton.setEnabled(true);\r
+ trackListTableView.setModel(seq_model);\r
+ TableColumnModel tcm = trackListTableView.getColumnModel();\r
seq_model.sizeColumnWidthToFit(tcm);\r
tcm.getColumn(MidiSequenceTableModel.COLUMN_RECORD_CHANNEL).setCellEditor(\r
seq_model.new RecordChannelCellEditor()\r
);\r
- track_selection_model.setSelectionInterval(0,0);\r
- tracks_label.setText(\r
- String.format("Tracks (in MIDI file No.%d)", sel_index)\r
- );\r
+ trackSelectionModel.setSelectionInterval(0,0);\r
+ tracksLabel.setText(String.format("Tracks (in MIDI file No.%d)", sel_index));\r
// event_cell_editor.setSequenceModel(seq_model);\r
}\r
else {\r
- delete_sequence_button.setEnabled(false);\r
- track_table_view.setModel(new MidiSequenceTableModel(seqListModel));\r
- tracks_label.setText("Tracks (No MIDI file selected)");\r
+ deleteSequenceButton.setEnabled(false);\r
+ trackListTableView.setModel(new MidiSequenceTableModel(sequenceListTableModel));\r
+ tracksLabel.setText("Tracks (No MIDI file selected)");\r
}\r
updateButtonStatus();\r
}\r
public void updateButtonStatus() {\r
boolean is_track_selected = (\r
- ! track_selection_model.isSelectionEmpty()\r
- &&\r
- seqListModel.getSequenceModel(seqSelectionModel) != null\r
- &&\r
- seqListModel.getSequenceModel(seqSelectionModel).getRowCount() > 0\r
- );\r
+ ! trackSelectionModel.isSelectionEmpty()\r
+ &&\r
+ sequenceListTableModel.getSequenceModel(seqSelectionModel) != null\r
+ &&\r
+ sequenceListTableModel.getSequenceModel(seqSelectionModel).getRowCount() > 0\r
+ );\r
//\r
// Track list\r
- remove_track_button.setEnabled( is_track_selected );\r
+ removeTrackButton.setEnabled( is_track_selected );\r
//\r
- TableModel tm = event_table_view.getModel();\r
+ TableModel tm = eventListTableView.getModel();\r
if( ! (tm instanceof MidiTrackTableModel) ) return;\r
//\r
MidiTrackTableModel track_model = (MidiTrackTableModel)tm;\r
- jump_sequence_button.setEnabled(\r
- track_model != null && track_model.getRowCount() > 0\r
- );\r
+ jumpSequenceButton.setEnabled(track_model != null && track_model.getRowCount() > 0);\r
// Event list\r
boolean is_event_selected = (\r
!(\r
- event_selection_model.isSelectionEmpty() ||\r
+ eventSelectionModel.isSelectionEmpty() ||\r
track_model == null || track_model.getRowCount() == 0\r
) && is_track_selected\r
);\r
- copy_event_button.setEnabled( is_event_selected );\r
- remove_event_button.setEnabled( is_event_selected );\r
- cut_event_button.setEnabled( is_event_selected );\r
- jump_event_button.setEnabled(\r
- track_model != null && is_track_selected\r
- );\r
- add_event_button.setEnabled(\r
- track_model != null && is_track_selected\r
- );\r
- paste_event_button.setEnabled(\r
- track_model != null && is_track_selected &&\r
- copied_events != null && copied_events.length > 0\r
- );\r
+ copyEventButton.setEnabled( is_event_selected );\r
+ removeEventButton.setEnabled( is_event_selected );\r
+ cutEventButton.setEnabled( is_event_selected );\r
+ jumpEventButton.setEnabled( track_model != null && is_track_selected );\r
+ addEventButton.setEnabled( track_model != null && is_track_selected );\r
+ pasteEventButton.setEnabled(\r
+ track_model != null && is_track_selected &&\r
+ copiedEventsToPaste != null && copiedEventsToPaste.length > 0\r
+ );\r
}\r
public String getMIDIdataBase64() {\r
base64Dialog.setMIDIData(\r
- deviceManager.timeRangeModel.getSequenceTableModel().getMIDIdata()\r
+ deviceModelList.timeRangeModel.getSequenceTableModel().getMIDIdata()\r
);\r
return base64Dialog.getBase64Data();\r
}\r
return addSequence(newSequenceDialog.getMidiSequence());\r
}\r
public int addSequence(Sequence seq) {\r
- int lastIndex = seqListModel.addSequence(seq);\r
- totalTimeLabel.setText( seqListModel.getTotalLength() );\r
- if( ! deviceManager.getSequencer().isRunning() ) {\r
+ int lastIndex = sequenceListTableModel.addSequence(seq);\r
+ totalTimeLabel.setText( sequenceListTableModel.getTotalLength() );\r
+ if( ! deviceModelList.getSequencer().isRunning() ) {\r
loadAndPlay(lastIndex);\r
}\r
return lastIndex;\r
public int addSequenceFromMidiData(byte[] data, String filename) {\r
int last_index;\r
try {\r
- last_index = seqListModel.addSequence(data,filename);\r
+ last_index = sequenceListTableModel.addSequence(data,filename);\r
} catch( InvalidMidiDataException e ) {\r
showWarning("MIDI data invalid");\r
return -1;\r
}\r
- totalTimeLabel.setText( seqListModel.getTotalLength() );\r
+ totalTimeLabel.setText( sequenceListTableModel.getTotalLength() );\r
return last_index;\r
}\r
public int addSequenceFromMidiFile(File midi_file) {\r
int last_index;\r
try {\r
- last_index = seqListModel.addSequence(midi_file);\r
+ last_index = sequenceListTableModel.addSequence(midi_file);\r
} catch( FileNotFoundException e ) {\r
showWarning( midi_file.getName() + " : not found" );\r
return -1;\r
e.printStackTrace();\r
return -1;\r
}\r
- totalTimeLabel.setText( seqListModel.getTotalLength() );\r
+ totalTimeLabel.setText( sequenceListTableModel.getTotalLength() );\r
return last_index;\r
}\r
public int addSequenceFromURL(String midi_file_url) {\r
int last_index;\r
try {\r
- last_index = seqListModel.addSequence(midi_file_url);\r
+ last_index = sequenceListTableModel.addSequence(midi_file_url);\r
} catch( InvalidMidiDataException e ) {\r
showWarning( midi_file_url + " : MIDI data invalid" );\r
return -1;\r
e.printStackTrace();\r
return -1;\r
}\r
- totalTimeLabel.setText( seqListModel.getTotalLength() );\r
+ totalTimeLabel.setText( sequenceListTableModel.getTotalLength() );\r
return last_index;\r
}\r
public void load(int index) {\r
- seqListModel.loadToSequencer(index);\r
+ sequenceListTableModel.loadToSequencer(index);\r
sequenceSelectionChanged();\r
}\r
public boolean loadNext(int offset) {\r
- boolean retval = seqListModel.loadNext(offset);\r
+ boolean retval = sequenceListTableModel.loadNext(offset);\r
sequenceSelectionChanged();\r
return retval;\r
}\r
public void loadAndPlay(int index) {\r
load(index);\r
- deviceManager.timeRangeModel.start();\r
+ deviceModelList.timeRangeModel.start();\r
}\r
public void loadAndPlay() {\r
loadAndPlay( seqSelectionModel.getMinSelectionIndex() );\r
lastIndex = addSequenceFromMidiFile(f);\r
if( nextIndex == -1 ) nextIndex = lastIndex;\r
}\r
- if( deviceManager.getSequencer().isRunning() ) {\r
+ if( deviceModelList.getSequencer().isRunning() ) {\r
setVisible(true);\r
}\r
else if( nextIndex >= 0 ) {\r
}\r
}\r
public boolean isModified() {\r
- return seqListModel.isModified();\r
+ return sequenceListTableModel.isModified();\r
}\r
public boolean isRecordable() {\r
MidiSequenceTableModel seq_model =\r
- seqListModel.getSequenceModel(seqSelectionModel);\r
+ sequenceListTableModel.getSequenceModel(seqSelectionModel);\r
return seq_model == null ? false : seq_model.isRecordable();\r
}\r
public void scrollToEventAt( long tick ) {\r
- MidiTrackTableModel track_model = (MidiTrackTableModel)event_table_view.getModel();\r
+ MidiTrackTableModel track_model = (MidiTrackTableModel)eventListTableView.getModel();\r
scrollToEventAt( track_model.tickToIndex(tick) );\r
}\r
public void scrollToEventAt( int index ) {\r
- scrollable_event_table_view.getVerticalScrollBar().setValue(\r
- index * event_table_view.getRowHeight()\r
- );\r
- event_selection_model.setSelectionInterval( index, index );\r
+ scrollableEventTableView.getVerticalScrollBar().setValue(\r
+ index * eventListTableView.getRowHeight()\r
+ );\r
+ eventSelectionModel.setSelectionInterval( index, index );\r
}\r
}\r
\r
}\r
}\r
}\r
- public MidiSequenceTableModel getSequenceModel(ListSelectionModel sel_model) {\r
- if( sel_model.isSelectionEmpty() ) return null;\r
- int sel_index = sel_model.getMinSelectionIndex();\r
- if( sel_index >= sequenceList.size() ) return null;\r
- return sequenceList.get(sel_index);\r
+ /**\r
+ * 選択されたMIDIシーケンスのテーブルモデルを返します。\r
+ * @param selectionModel 選択状態\r
+ * @return 選択されたMIDIシーケンスのテーブルモデル\r
+ */\r
+ public MidiSequenceTableModel getSequenceModel(ListSelectionModel selectionModel) {\r
+ if( selectionModel.isSelectionEmpty() )\r
+ return null;\r
+ int selectedIndex = selectionModel.getMinSelectionIndex();\r
+ if( selectedIndex >= sequenceList.size() )\r
+ return null;\r
+ return sequenceList.get(selectedIndex);\r
}\r
public void fireSequenceChanged( ListSelectionModel sel_model ) {\r
if( sel_model.isSelectionEmpty() ) return;\r
* Copyright (C) 2006-2013 @きよし - Akiyoshi Kamide\r
* http://www.yk.rim.or.jp/~kamide/music/chordhelper/\r
*/\r
-class MidiEventDialog extends JDialog {\r
+class MidiEventDialog extends JDialog implements ActionListener {\r
MidiMessageForm midiMessageForm = new MidiMessageForm();\r
- TickPositionForm tick_position_form = new TickPositionForm();\r
+ TickPositionForm tickPositionForm = new TickPositionForm();\r
JButton okButton = new JButton("OK");\r
- JButton cancel_button = new JButton("Cancel");\r
+ JButton cancelButton = new JButton("Cancel");\r
public MidiEventDialog() {\r
setLayout(new FlowLayout());\r
- add( tick_position_form );\r
+ add( tickPositionForm );\r
add( midiMessageForm );\r
- JPanel ok_cancel_panel = new JPanel();\r
- ok_cancel_panel.add( okButton );\r
- ok_cancel_panel.add( cancel_button );\r
- add( ok_cancel_panel );\r
- cancel_button.addActionListener(\r
- new ActionListener() {\r
- public void actionPerformed(ActionEvent e) {\r
- setVisible(false);\r
- }\r
- }\r
- );\r
+ add( new JPanel() {{ add(okButton); add(cancelButton); }} );\r
+ cancelButton.addActionListener(this);\r
+ }\r
+ public void actionPerformed(ActionEvent e) {\r
+ setVisible(false);\r
}\r
public void openTickForm() {\r
- tick_position_form.setVisible(true);\r
+ tickPositionForm.setVisible(true);\r
midiMessageForm.setVisible(false);\r
setBounds( 200, 300, 500, 120 );\r
setVisible(true);\r
}\r
public void openEventForm() {\r
- tick_position_form.setVisible(true);\r
+ tickPositionForm.setVisible(true);\r
midiMessageForm.setVisible(true);\r
midiMessageForm.setDurationVisible(true);\r
setBounds( 200, 300, 630, 320 );\r
setVisible(true);\r
}\r
public void openMessageForm() {\r
- tick_position_form.setVisible(false);\r
+ tickPositionForm.setVisible(false);\r
midiMessageForm.setVisible(true);\r
midiMessageForm.setDurationVisible(false);\r
setBounds( 200, 300, 630, 270 );\r
}\r
}\r
);\r
- minor_checkbox.addItemListener(\r
+ minorCheckbox.addItemListener(\r
new ItemListener() {\r
public void itemStateChanged(ItemEvent e) {\r
dataText.setValue(getKey().getBytes());\r
}\r
\r
\r
-///////////////////////////////////////\r
-//\r
-// Hex value: [0x00 0x00 0x00 ... ]\r
-//\r
-///////////////////////////////////////\r
+/**\r
+ * 16進数テキスト入力フォーム [0x00 0x00 0x00 ... ]\r
+ */\r
class HexTextForm extends JPanel {\r
public JTextArea text_area;\r
public JLabel title_label;\r
}\r
public void clear() { text_area.setText(""); }\r
}\r
-\r
-///////////////////////////////////////\r
-//\r
-// Hex value: [0x00 0x00 0x00 ... ] v -> Select\r
-//\r
-///////////////////////////////////////\r
+/**\r
+ * 16進数選択 [0x00 0x00 0x00 ... ] v -> Select\r
+ */\r
class HexSelecter extends JPanel {\r
private JComboBox<String> comboBox = new JComboBox<String>();\r
private JLabel title;\r
}\r
}\r
\r
-///////////////////////////////////////\r
-//\r
-// MIDI Channel Selecter (ComboBox or List)\r
-//\r
-///////////////////////////////////////\r
+/**\r
+ * MIDIチャンネル選択コンボボックスモデル\r
+ */\r
interface MidiChannelComboBoxModel extends ComboBoxModel<Integer> {\r
int getSelectedChannel();\r
void setSelectedChannel(int channel);\r
}\r
+/**\r
+ * MIDIチャンネル選択コンボボックスモデルのデフォルト実装\r
+ */\r
class DefaultMidiChannelComboBoxModel extends DefaultComboBoxModel<Integer>\r
implements MidiChannelComboBoxModel\r
{\r
setSelectedItem(getElementAt(channel));\r
}\r
}\r
+/**\r
+ * MIDIチャンネル選択ビュー(コンボボックス)\r
+ */\r
class MidiChannelComboSelecter extends JPanel {\r
JComboBox<Integer> comboBox = new JComboBox<>();\r
public MidiChannelComboSelecter( String title ) {\r
- this( title, new DefaultMidiChannelComboBoxModel() );\r
+ this(title, new DefaultMidiChannelComboBoxModel());\r
}\r
- public MidiChannelComboSelecter(\r
- String title, MidiChannelComboBoxModel model\r
- ) {\r
+ public MidiChannelComboSelecter(String title, MidiChannelComboBoxModel model) {\r
setLayout(new FlowLayout());\r
if( title != null ) add( new JLabel(title) );\r
comboBox.setModel(model);\r
comboBox.setSelectedIndex(channel);\r
}\r
}\r
-class MidiChannelButtonSelecter extends JList<Integer> {\r
+/**\r
+ * MIDIチャンネル選択ビュー(リストボタン)\r
+ */\r
+class MidiChannelButtonSelecter extends JList<Integer>\r
+ implements ListDataListener, ListSelectionListener\r
+{\r
private PianoKeyboard keyboard = null;\r
public MidiChannelButtonSelecter(MidiChannelComboBoxModel model) {\r
super(model);\r
setVisibleRowCount(1);\r
setCellRenderer(new MyCellRenderer());\r
setSelectedIndex(model.getSelectedChannel());\r
- model.addListDataListener(new ListDataListener() {\r
- public void contentsChanged(ListDataEvent e) {\r
- MidiChannelButtonSelecter.this.setSelectedIndex(\r
- MidiChannelButtonSelecter.this.getModel().getSelectedChannel()\r
- );\r
- }\r
- public void intervalAdded(ListDataEvent e) {}\r
- public void intervalRemoved(ListDataEvent e) {}\r
- });\r
- addListSelectionListener(new ListSelectionListener() {\r
- public void valueChanged(ListSelectionEvent e) {\r
- MidiChannelButtonSelecter.this.getModel().setSelectedChannel(\r
- MidiChannelButtonSelecter.this.getSelectedIndex()\r
- );\r
- }\r
- });\r
+ model.addListDataListener(this);\r
+ addListSelectionListener(this);\r
+ }\r
+ @Override\r
+ public void contentsChanged(ListDataEvent e) {\r
+ setSelectedIndex(getModel().getSelectedChannel());\r
+ }\r
+ @Override\r
+ public void intervalAdded(ListDataEvent e) {}\r
+ @Override\r
+ public void intervalRemoved(ListDataEvent e) {}\r
+ @Override\r
+ public void valueChanged(ListSelectionEvent e) {\r
+ getModel().setSelectedChannel(getSelectedIndex());\r
}\r
public MidiChannelButtonSelecter(PianoKeyboard keyboard) {\r
this(keyboard.midiChComboboxModel);\r
setPianoKeyboard(keyboard);\r
}\r
+ @Override\r
public MidiChannelComboBoxModel getModel() {\r
return (MidiChannelComboBoxModel)(super.getModel());\r
}\r
setHorizontalAlignment(CENTER);\r
setSelectionBackground(Color.yellow);\r
}\r
+ @Override\r
public Component getListCellRendererComponent(\r
JList<? extends Integer> list,\r
Integer value, int index,\r
setFont(list.getFont());\r
return this;\r
}\r
+ @Override\r
protected void paintComponent(Graphics g) {\r
super.paintComponent(g);\r
if( cellHasFocus ) {\r
}\r
}\r
\r
-////////////////////////////////////\r
-//\r
-// Tick Position\r
-//\r
-// Mesausre:[xxxx] Beat:[xx] ExTick:[xxx]\r
-//\r
-////////////////////////////////////\r
+/**\r
+ * tick位置 Mesausre:[xxxx] Beat:[xx] ExTick:[xxx]\r
+ */\r
class TickPositionModel implements ChangeListener {\r
- private SequenceTickIndex seq_index;\r
- private boolean is_changing = false;\r
- public SpinnerNumberModel\r
- tick_model, measure_model, beat_model, extra_tick_model;\r
- //\r
- // Constuctor\r
- //\r
+ public SpinnerNumberModel tickModel = new SpinnerNumberModel(0L, 0L, 999999L, 1L);\r
+ public SpinnerNumberModel measureModel = new SpinnerNumberModel(1, 1, 9999, 1);\r
+ public SpinnerNumberModel beatModel = new SpinnerNumberModel(1, 1, 32, 1);\r
+ public SpinnerNumberModel extraTickModel = new SpinnerNumberModel(0, 0, 4*960-1, 1);\r
+ /**\r
+ * 新しい {@link TickPositionModel} を構築します。\r
+ */\r
public TickPositionModel() {\r
- tick_model = new SpinnerNumberModel(0L, 0L, 999999L, 1L);\r
- tick_model.addChangeListener(this);\r
- measure_model = new SpinnerNumberModel(1, 1, 9999, 1);\r
- measure_model.addChangeListener(this);\r
- beat_model = new SpinnerNumberModel(1, 1, 32, 1);\r
- beat_model.addChangeListener(this);\r
- extra_tick_model = new SpinnerNumberModel(0, 0, 4*960-1, 1);\r
- extra_tick_model.addChangeListener(this);\r
- }\r
- // ChangeListener\r
- //\r
+ tickModel.addChangeListener(this);\r
+ measureModel.addChangeListener(this);\r
+ beatModel.addChangeListener(this);\r
+ extraTickModel.addChangeListener(this);\r
+ }\r
+ private SequenceTickIndex sequenceTickIndex;\r
+ private boolean isChanging = false;\r
+ @Override\r
public void stateChanged(ChangeEvent e) {\r
- if( seq_index == null ) return;\r
- Object src = e.getSource();\r
- if( src == tick_model ) {\r
- is_changing = true;\r
- measure_model.setValue(\r
- 1 + seq_index.tickToMeasure(\r
- tick_model.getNumber().longValue()\r
- )\r
- );\r
- beat_model.setValue( seq_index.lastBeat + 1 );\r
- is_changing = false;\r
- extra_tick_model.setValue( seq_index.lastExtraTick );\r
+ if( sequenceTickIndex == null )\r
+ return;\r
+ Object changedAt = e.getSource();\r
+ if( changedAt == tickModel ) {\r
+ isChanging = true;\r
+ long newTick = tickModel.getNumber().longValue();\r
+ int newMeasure = 1 + sequenceTickIndex.tickToMeasure(newTick);\r
+ measureModel.setValue(newMeasure);\r
+ beatModel.setValue( sequenceTickIndex.lastBeat + 1 );\r
+ isChanging = false;\r
+ extraTickModel.setValue( sequenceTickIndex.lastExtraTick );\r
return;\r
}\r
- if( is_changing ) return;\r
- tick_model.setValue(\r
- seq_index.measureToTick(\r
- measure_model.getNumber().intValue() - 1,\r
- beat_model.getNumber().intValue() - 1,\r
- extra_tick_model.getNumber().intValue()\r
- )\r
- );\r
- }\r
- // Methods\r
- //\r
- public SequenceTickIndex getSequenceIndex() {\r
- return seq_index;\r
+ if( isChanging )\r
+ return;\r
+ long newTick = sequenceTickIndex.measureToTick(\r
+ measureModel.getNumber().intValue() - 1,\r
+ beatModel.getNumber().intValue() - 1,\r
+ extraTickModel.getNumber().intValue()\r
+ );\r
+ tickModel.setValue(newTick);\r
}\r
- public void setSequenceIndex( SequenceTickIndex seq_index ) {\r
- this.seq_index = seq_index;\r
- extra_tick_model.setMaximum( 4 * seq_index.getResolution() - 1 );\r
+ public void setSequenceIndex(SequenceTickIndex sequenceTickIndex) {\r
+ this.sequenceTickIndex = sequenceTickIndex;\r
+ extraTickModel.setMaximum( 4 * sequenceTickIndex.getResolution() - 1 );\r
}\r
public long getTickPosition() {\r
- return tick_model.getNumber().longValue();\r
+ return tickModel.getNumber().longValue();\r
}\r
public void setTickPosition( long tick ) {\r
- tick_model.setValue(tick);\r
+ tickModel.setValue(tick);\r
}\r
}\r
\r
+/**\r
+ * tick位置入力フォーム\r
+ */\r
class TickPositionForm extends JPanel {\r
- JSpinner\r
- tick_spinner = new JSpinner(),\r
- measure_spinner = new JSpinner(),\r
- beat_spinner = new JSpinner(),\r
- extra_tick_spinner = new JSpinner();\r
-\r
+ JSpinner tickSpinner = new JSpinner();\r
+ JSpinner measureSpinner = new JSpinner();\r
+ JSpinner beatSpinner = new JSpinner();\r
+ JSpinner extraTickSpinner = new JSpinner();\r
public TickPositionForm() {\r
setLayout(new GridLayout(2,4));\r
add( new JLabel() );\r
add( new JLabel("Beat:") );\r
add( new JLabel("ExTick:") );\r
add( new JLabel("Tick position : ",JLabel.RIGHT) );\r
- add( tick_spinner );\r
- add( measure_spinner );\r
- add( beat_spinner );\r
- add( extra_tick_spinner );\r
- }\r
- public TickPositionForm( TickPositionModel tpm ) {\r
- this(); setModel(tpm);\r
+ add( tickSpinner );\r
+ add( measureSpinner );\r
+ add( beatSpinner );\r
+ add( extraTickSpinner );\r
}\r
- public void setModel( TickPositionModel tpm ) {\r
- tick_spinner.setModel(tpm.tick_model);\r
- measure_spinner.setModel(tpm.measure_model);\r
- beat_spinner.setModel(tpm.beat_model);\r
- extra_tick_spinner.setModel(tpm.extra_tick_model);\r
+ public void setModel(TickPositionModel model) {\r
+ tickSpinner.setModel(model.tickModel);\r
+ measureSpinner.setModel(model.measureModel);\r
+ beatSpinner.setModel(model.beatModel);\r
+ extraTickSpinner.setModel(model.extraTickModel);\r
}\r
}\r
\r
/**\r
- * 音の長さフォーム\r
+ * 音長入力フォーム\r
*/\r
class DurationForm extends JPanel implements ActionListener, ChangeListener {\r
class NoteIcon extends ButtonIcon {\r
}\r
class NoteRenderer extends JLabel implements ListCellRenderer<NoteIcon> {\r
public NoteRenderer() { setOpaque(true); }\r
+ @Override\r
public Component getListCellRendererComponent(\r
JList<? extends NoteIcon> list,\r
NoteIcon icon,\r
add( spinner = new JSpinner( model ) );\r
add( unit_label = new JLabel("[Ticks]") );\r
}\r
- // ActionListener\r
- //\r
+ @Override\r
public void actionPerformed(ActionEvent e) {\r
int duration = note_combo.getDuration();\r
if( duration < 0 ) return;\r
model.setDuration( duration );\r
}\r
- // ChangeListener\r
- //\r
+ @Override\r
public void stateChanged(ChangeEvent e) {\r
note_combo.setDuration( model.getDuration() );\r
}\r
- // Methods\r
- //\r
+ @Override\r
public void setEnabled( boolean enabled ) {\r
super.setEnabled(enabled);\r
title_label.setEnabled(enabled);\r
}\r
}\r
\r
-//////////////////////////////\r
-//\r
-// Tempo in QPM\r
-//\r
-//////////////////////////////\r
+/**\r
+ * テンポ選択(QPM: Quarter Per Minute)\r
+ */\r
class TempoSelecter extends JPanel implements MouseListener {\r
+ static final int DEFAULT_QPM = 120;\r
JSpinner tempo_spinner;\r
SpinnerNumberModel tempoSpinnerModel;\r
JLabel tempo_label, tempo_value_label;\r
private boolean editable;\r
- static final int DEFAULT_QPM = 120;\r
private long prev_beat_us_pos = 0;\r
\r
public TempoSelecter() {\r
setEditable(true);\r
tempo_label.addMouseListener(this);\r
}\r
- //\r
- // MouseListener\r
- //\r
public void mousePressed(MouseEvent e) {\r
Component obj = e.getComponent();\r
if( obj == tempo_label && isEditable() ) {\r
public void mouseEntered(MouseEvent e) { }\r
public void mouseExited(MouseEvent e) { }\r
public void mouseClicked(MouseEvent e) { }\r
- //\r
- // Methods\r
- //\r
- public boolean isEditable() {\r
- return editable;\r
- }\r
+ public boolean isEditable() { return editable; }\r
public void setEditable( boolean editable ) {\r
this.editable = editable;\r
tempo_spinner.setVisible( editable );\r
}\r
}\r
\r
-/////////////////////////////\r
-//\r
-// Key Signature - 調性選択\r
-//\r
-/////////////////////////////\r
+/**\r
+ * 調性選択\r
+ */\r
class KeySignatureSelecter extends JPanel implements ActionListener {\r
JComboBox<String> keysigCombobox = new JComboBox<String>() {\r
{\r
setMaximumRowCount(15);\r
}\r
};\r
- JCheckBox minor_checkbox = null;\r
+ JCheckBox minorCheckbox = null;\r
\r
- public KeySignatureSelecter() {\r
- this(true);\r
- }\r
+ public KeySignatureSelecter() { this(true); }\r
public KeySignatureSelecter(boolean use_minor_checkbox) {\r
add(new JLabel("Key:"));\r
add(keysigCombobox);\r
if( use_minor_checkbox ) {\r
- add( minor_checkbox = new JCheckBox("minor") );\r
- minor_checkbox.addActionListener(this);\r
+ add( minorCheckbox = new JCheckBox("minor") );\r
+ minorCheckbox.addActionListener(this);\r
}\r
keysigCombobox.addActionListener(this);\r
clear();\r
}\r
- // ActionListener\r
- //\r
- public void actionPerformed(ActionEvent e) {\r
- updateToolTipText();\r
- }\r
- //\r
- // Methods\r
- //\r
+ public void actionPerformed(ActionEvent e) { updateToolTipText(); }\r
private void updateToolTipText() {\r
Music.Key key = getKey();\r
keysigCombobox.setToolTipText(\r
+ " (" + key.signatureDescription() + ")"\r
);\r
}\r
- public void clear() {\r
- setKey( new Music.Key("C") );\r
- }\r
+ public void clear() { setKey(new Music.Key("C")); }\r
public void setKey( Music.Key key ) {\r
if( key == null ) {\r
clear();\r
return;\r
}\r
keysigCombobox.setSelectedIndex( key.toCo5() + 7 );\r
- if( minor_checkbox == null )\r
+ if( minorCheckbox == null )\r
return;\r
switch( key.majorMinor() ) {\r
- case Music.Key.MINOR : minor_checkbox.setSelected(true); break;\r
- case Music.Key.MAJOR : minor_checkbox.setSelected(false); break;\r
+ case Music.Key.MINOR : minorCheckbox.setSelected(true); break;\r
+ case Music.Key.MAJOR : minorCheckbox.setSelected(false); break;\r
}\r
}\r
public Music.Key getKey() {\r
int minor = (\r
- minor_checkbox == null ? Music.Key.MAJOR_OR_MINOR :\r
- isMinor() ? Music.Key.MINOR : Music.Key.MAJOR\r
+ minorCheckbox == null ? Music.Key.MAJOR_OR_MINOR :\r
+ isMinor() ? Music.Key.MINOR :\r
+ Music.Key.MAJOR\r
);\r
return new Music.Key(getKeyCo5(),minor);\r
}\r
return keysigCombobox.getSelectedIndex() - 7;\r
}\r
public boolean isMinor() {\r
- return ( minor_checkbox != null && minor_checkbox.isSelected() );\r
+ return minorCheckbox != null && minorCheckbox.isSelected();\r
}\r
}\r
+/**\r
+ * 調表示ラベル\r
+ */\r
class KeySignatureLabel extends JLabel {\r
private Music.Key key;\r
public KeySignatureLabel() { clear(); }\r
}\r
setText( "key:" + key.toString() );\r
setToolTipText(\r
- "Key: " + key.toStringIn(Music.SymbolLanguage.NAME)\r
- + " " + key.toStringIn(Music.SymbolLanguage.IN_JAPANESE)\r
- + " (" + key.signatureDescription() + ")"\r
- );\r
+ "Key: " + key.toStringIn(Music.SymbolLanguage.NAME)\r
+ + " " + key.toStringIn(Music.SymbolLanguage.IN_JAPANESE)\r
+ + " (" + key.signatureDescription() + ")"\r
+ );\r
setEnabled(true);\r
}\r
public void clear() { setKeySignature( (Music.Key)null ); }\r
}\r
\r
-///////////////////////////////////////////////\r
-//\r
-// Velocity\r
-//\r
-///////////////////////////////////////////////\r
+/**\r
+ * ベロシティ値範囲モデル\r
+ */\r
class VelocityModel extends DefaultBoundedRangeModel {\r
public VelocityModel() { super( 64, 0, 0, 127 ); }\r
}\r
-class VelocitySelecter extends JPanel {\r
+/**\r
+ * ベロシティ選択ビュー\r
+ */\r
+class VelocitySelecter extends JPanel implements ChangeListener {\r
private static final String LABEL_PREFIX = "Velocity=";\r
- public JSlider slider = null;\r
+ public JSlider slider;\r
public JLabel label;\r
- public VelocitySelecter( VelocityModel model ) {\r
- slider = new JSlider(model);\r
- slider.addChangeListener(new ChangeListener() {\r
- public void stateChanged(ChangeEvent e) {\r
- label.setText( LABEL_PREFIX + getValue() );\r
- }\r
- });\r
- slider.setToolTipText("Velocity");\r
- label = new JLabel( LABEL_PREFIX + model.getValue(), Label.RIGHT );\r
- label.setToolTipText("Velocity");\r
- setLayout( new BoxLayout( this, BoxLayout.X_AXIS ) );\r
- add(label);\r
- add(slider);\r
+ public VelocitySelecter(VelocityModel model) {\r
+ setLayout(new BoxLayout(this, BoxLayout.X_AXIS));\r
+ add(label = new JLabel(LABEL_PREFIX + model.getValue(), Label.RIGHT) {{\r
+ setToolTipText("Velocity");\r
+ }});\r
+ add(slider = new JSlider(model) {{ setToolTipText("Velocity"); }});\r
+ slider.addChangeListener(this);\r
+ }\r
+ public void stateChanged(ChangeEvent e) {\r
+ label.setText( LABEL_PREFIX + getValue() );\r
}\r
+ @Override\r
public void setBackground(Color c) {\r
super.setBackground(c);\r
+ // このクラスが構築される前にスーパークラスの\r
+ // Look & Feel からここが呼ばれることがあるため\r
+ // null チェックが必要\r
if( slider != null ) slider.setBackground(c);\r
}\r
- public int getValue() {\r
- return slider.getValue();\r
- }\r
- public void setValue(int velocity) {\r
- slider.setValue(velocity);\r
- }\r
+ public int getValue() { return slider.getValue(); }\r
+ public void setValue(int velocity) { slider.setValue(velocity); }\r
}\r
\r
-///////////////////////////////////////////////\r
-//\r
-// MIDI Instrument (Program) - 音色選択\r
-//\r
-///////////////////////////////////////////////\r
+/**\r
+ * MIDI Instrument (Program) - 音色選択\r
+ */\r
class MidiProgramSelecter extends JComboBox<String> {\r
private int family;\r
private MidiProgramFamilySelecter family_selecter = null;\r
}\r
}\r
}\r
+/**\r
+ * MIDI Instrument (Program) Family - 音色ファミリーの選択\r
+ */\r
class MidiProgramFamilySelecter extends JComboBox<String> implements ActionListener {\r
- private MidiProgramSelecter program_selecter = null;\r
+ private MidiProgramSelecter programSelecter = null;\r
public MidiProgramFamilySelecter() { this(null); }\r
public MidiProgramFamilySelecter( MidiProgramSelecter mps ) {\r
- program_selecter = mps;\r
+ programSelecter = mps;\r
setMaximumRowCount(17);\r
addItem("Program:");\r
for( int i=0; i < MIDISpec.instrument_family_names.length; i++ ) {\r
setSelectedIndex(0);\r
addActionListener(this);\r
}\r
- public void actionPerformed(ActionEvent evt) {\r
- if( program_selecter == null ) return;\r
+ public void actionPerformed(ActionEvent event) {\r
+ if( programSelecter == null ) return;\r
int i = getSelectedIndex();\r
- program_selecter.setFamily( i < 0 ? i : i-1 );\r
+ programSelecter.setFamily( i < 0 ? i : i-1 );\r
}\r
public int getProgram() {\r
int i = getSelectedIndex();\r
else return (i-1)*8;\r
}\r
public String getProgramFamilyName() { return (String)( getSelectedItem() ); }\r
- public void setProgram( int program_no ) {\r
- if( program_no < 0 ) program_no = 0;\r
- else program_no = program_no / 8 + 1;\r
- setSelectedIndex( program_no );\r
+ public void setProgram( int programNumber ) {\r
+ if( programNumber < 0 ) programNumber = 0;\r
+ else programNumber = programNumber / 8 + 1;\r
+ setSelectedIndex( programNumber );\r
}\r
}\r
import javax.swing.event.EventListenerList;\r
\r
/**\r
- * 時間または小節の表示形式\r
- */\r
-enum TimeLabelFormat {\r
- /**\r
- * 時間位置\r
- */\r
- POSITION,\r
- /**\r
- * 時間の長さ\r
- */\r
- LENGTH {\r
- @Override\r
- public String toTimeString(int sec) {\r
- return "/"+super.toTimeString(sec);\r
- }\r
- };\r
- /**\r
- * この形式で時間の文字列を返します。\r
- * @param sec 時間の秒数\r
- * @return この形式での時間の文字列\r
- */\r
- public String toTimeString(int sec) {\r
- return String.format("%02d:%02d", sec/60, sec%60);\r
- }\r
-}\r
-\r
-/**\r
* シーケンサの現在位置(分:秒)を表示するビュー\r
*/\r
class TimeIndicator extends JPanel implements ChangeListener {\r
- /**\r
- * 時間(分:秒)表示ラベル\r
- */\r
- private static class TimeLabel extends JLabel {\r
- /**\r
- * 時間表示の形式\r
- */\r
- private TimeLabelFormat formatType;\r
+ private static abstract class TimeLabel extends JLabel {\r
/**\r
* 時間の値(秒)\r
*/\r
private int valueInSec;\r
/**\r
- * 時間表示ラベルを構築します。\r
- * @param formatType 表示形式\r
+ * 時間の値を秒単位で設定します。\r
+ * @param sec 秒単位の時間\r
*/\r
- public TimeLabel(TimeLabelFormat formatType) {\r
- super();\r
- if( (this.formatType = formatType) == TimeLabelFormat.POSITION ) {\r
- setFont( getFont().deriveFont(getFont().getSize2D() + 4) );\r
- setForeground( new Color(0x80,0x00,0x00) );\r
- setToolTipText("Time position - 現在位置(分:秒)");\r
- }\r
- else {\r
- setToolTipText("Time length - 曲の長さ(分:秒)");\r
- }\r
- setText(formatType.toTimeString(valueInSec));\r
+ public void setTimeInSecond(int sec) {\r
+ if(valueInSec != sec) setText(toTimeString(valueInSec = sec));\r
}\r
/**\r
- * 時間の値を秒単位で設定します。\r
+ * 時間の値を文字列に変換します。\r
* @param sec 秒単位の時間\r
+ * @return 変換結果(分:秒)\r
*/\r
- public void setTimeInSecond(int sec) {\r
- if( valueInSec == sec )\r
- return;\r
- setText(formatType.toTimeString(sec));\r
+ protected String toTimeString(int sec) {\r
+ return String.format("%02d:%02d", sec/60, sec%60);\r
+ }\r
+ }\r
+ private static class TimePositionLabel extends TimeLabel {\r
+ public TimePositionLabel() {\r
+ setFont( getFont().deriveFont(getFont().getSize2D() + 4) );\r
+ setForeground( new Color(0x80,0x00,0x00) );\r
+ setToolTipText("Time position - 現在位置(分:秒)");\r
+ setText(toTimeString(0));\r
}\r
}\r
- private TimeLabel timePositionLabel = new TimeLabel(TimeLabelFormat.POSITION);\r
- private TimeLabel timeLengthLabel = new TimeLabel(TimeLabelFormat.LENGTH);\r
+ private static class TimeLengthLabel extends TimeLabel {\r
+ public TimeLengthLabel() {\r
+ setToolTipText("Time length - 曲の長さ(分:秒)");\r
+ setText(toTimeString(0));\r
+ }\r
+ @Override\r
+ protected String toTimeString(int sec) {\r
+ return "/"+super.toTimeString(sec);\r
+ }\r
+ }\r
+ private TimeLabel timePositionLabel = new TimePositionLabel();\r
+ private TimeLabel timeLengthLabel = new TimeLengthLabel();\r
private SequencerTimeRangeModel model;\r
/**\r
* シーケンサの現在位置(分:秒)を表示するビューを構築します。\r
add(timeLengthLabel);\r
(this.model = model).addChangeListener(this);\r
}\r
+ @Override\r
public void stateChanged(ChangeEvent e) {\r
timeLengthLabel.setTimeInSecond(model.getMaximum()/1000);\r
timePositionLabel.setTimeInSecond(model.getValue()/1000);\r
* 小節表示ビュー\r
*/\r
class MeasureIndicator extends JPanel implements ChangeListener {\r
- /**\r
- * 小節表示ラベル\r
- */\r
- private static class MeasureLabel extends JLabel {\r
- private TimeLabelFormat formatType;\r
- private int measure = -1;\r
- private int beat = 0;\r
- public MeasureLabel(TimeLabelFormat formatType) {\r
- if( (this.formatType = formatType) == TimeLabelFormat.POSITION ) {\r
- setFont( getFont().deriveFont(getFont().getSize2D() + 4) );\r
- setForeground( new Color(0x80,0x00,0x00) );\r
- setText( "0001:01" );\r
- setToolTipText("Measure:beat position - 何小節目:何拍目");\r
- }\r
- else {\r
- setText( "/0000" );\r
- setToolTipText("Measure length - 小節の数");\r
- }\r
+ private static abstract class MeasureLabel extends JLabel {\r
+ protected int measure = -1;\r
+ public boolean setMeasure(int measure) {\r
+ if( this.measure == measure ) return false;\r
+ this.measure = measure;\r
+ return true;\r
}\r
- public void setMeasure(int measure) {\r
- setMeasure(measure,0);\r
+ }\r
+ private static class MeasurePositionLabel extends MeasureLabel {\r
+ protected int beat = 0;\r
+ public MeasurePositionLabel() {\r
+ setFont( getFont().deriveFont(getFont().getSize2D() + 4) );\r
+ setForeground( new Color(0x80,0x00,0x00) );\r
+ setText( "0001:01" );\r
+ setToolTipText("Measure:beat position - 何小節目:何拍目");\r
}\r
- public void setMeasure(int measure, int beat) {\r
- if( this.measure == measure && this.beat == beat ) {\r
- return;\r
- }\r
- this.beat = beat;\r
- this.measure = measure;\r
- if( formatType == TimeLabelFormat.LENGTH )\r
- setText(String.format("/%04d", measure));\r
- else\r
- setText(String.format("%04d:%02d", measure+1, beat+1));\r
+ public boolean setMeasure(int measure, int beat) {\r
+ if( ! super.setMeasure(measure) && this.beat == beat )\r
+ return false;\r
+ setText(String.format("%04d:%02d", measure+1, beat+1));\r
+ return true;\r
+ }\r
+ }\r
+ private static class MeasureLengthLabel extends MeasureLabel {\r
+ public MeasureLengthLabel() {\r
+ setText( "/0000" );\r
+ setToolTipText("Measure length - 小節の数");\r
+ }\r
+ public boolean setMeasure(int measure) {\r
+ if( ! super.setMeasure(measure) )\r
+ return false;\r
+ setText(String.format("/%04d", measure));\r
+ return true;\r
}\r
}\r
- private MeasureLabel measurePositionLabel = new MeasureLabel(TimeLabelFormat.POSITION);\r
- private MeasureLabel measureLengthLabel = new MeasureLabel(TimeLabelFormat.LENGTH);\r
+ private MeasurePositionLabel measurePositionLabel;\r
+ private MeasureLengthLabel measureLengthLabel;\r
private SequencerTimeRangeModel model;\r
/**\r
* シーケンサの現在の小節位置を表示するビューを構築します。\r
*/\r
public MeasureIndicator(SequencerTimeRangeModel model) {\r
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));\r
- add(measurePositionLabel);\r
- add(measureLengthLabel);\r
+ add(measurePositionLabel = new MeasurePositionLabel());\r
+ add(measureLengthLabel = new MeasureLengthLabel());\r
(this.model = model).addChangeListener(this);\r
}\r
@Override\r
public void stateChanged(ChangeEvent e) {\r
Sequencer sequencer = model.deviceModelList.getSequencer();\r
- MidiSequenceTableModel seqModel =\r
+ MidiSequenceTableModel sequenceTableModel =\r
model.deviceModelList.timeRangeModel.getSequenceTableModel();\r
- SequenceTickIndex seqIndex = (\r
- seqModel == null ? null : seqModel.getSequenceTickIndex()\r
+ SequenceTickIndex tickIndex = (\r
+ sequenceTableModel == null ? null : sequenceTableModel.getSequenceTickIndex()\r
);\r
if( ! sequencer.isRunning() || sequencer.isRecording() ) {\r
- measureLengthLabel.setMeasure(\r
- seqIndex == null ? 0 : seqIndex.tickToMeasure(\r
- sequencer.getTickLength()\r
- )\r
- );\r
+ // 停止中または録音中の場合、長さが変わることがあるので表示を更新\r
+ if( tickIndex == null ) {\r
+ measureLengthLabel.setMeasure(0);\r
+ }\r
+ else {\r
+ long tickLength = sequencer.getTickLength();\r
+ int measureLength = tickIndex.tickToMeasure(tickLength);\r
+ measureLengthLabel.setMeasure(measureLength);\r
+ }\r
}\r
- if( seqIndex == null ) {\r
- measurePositionLabel.setMeasure( 0, 0 );\r
+ // 小節位置の表示を更新\r
+ if( tickIndex == null ) {\r
+ measurePositionLabel.setMeasure(0, 0);\r
}\r
else {\r
- int measurePosition = seqIndex.tickToMeasure(\r
- sequencer.getTickPosition()\r
- );\r
- measurePositionLabel.setMeasure(\r
- measurePosition, seqIndex.lastBeat\r
- );\r
+ long tickPosition = sequencer.getTickPosition();\r
+ int measurePosition = tickIndex.tickToMeasure(tickPosition);\r
+ measurePositionLabel.setMeasure(measurePosition, tickIndex.lastBeat);\r
}\r
}\r
}\r
/**\r
* シーケンサーの再生スピード調整スライダビュー\r
*/\r
-class SpeedSlider extends JPanel implements ActionListener {\r
+class SequencerSpeedSlider extends JPanel implements ActionListener {\r
static String items[] = {\r
"x 1.0",\r
"x 1.5",\r
JSlider slider;\r
JLabel title_label;\r
JComboBox<String> scale_combo_box;\r
- public SpeedSlider( SpeedSliderModel model ) {\r
+ public SequencerSpeedSlider( SpeedSliderModel model ) {\r
add( title_label = new JLabel("Speed:") );\r
add( slider = new JSlider(model) );\r
add( scale_combo_box = new JComboBox<String>(items) );\r
}\r
\r
/**\r
- * ã\82¹ã\83©ã\82¤ã\83\80ã\83¼ç\94¨ã\81®æ\99\82é\96\93ç¯\84å\9b²ã\83\87ã\83¼ã\82¿ã\83¢ã\83\87ã\83«\r
+ * ã\82·ã\83¼ã\82±ã\83³ã\82µã\83¼ã\81®ã\83\9fã\83ªç§\92ä½\8dç½®ã\82\92表ã\81\99ç¯\84å\9b²ã\83\87ã\83¼ã\82¿ã\83¢ã\83\87ã\83«ã\81§ã\81\99ã\80\82\r
*/\r
class SequencerTimeRangeModel\r
implements BoundedRangeModel, MetaEventListener, ActionListener\r
*/\r
MidiDeviceModelList deviceModelList;\r
/**\r
- * シーケンサ\r
+ * シーケンサに同期させるためのサンプリングタイマー更新\r
*/\r
- private Sequencer sequencer;\r
+ private class Updater extends javax.swing.Timer {\r
+ public Updater(ActionListener actionListener) {\r
+ super(INTERVAL_MS, actionListener);\r
+ }\r
+ @Override\r
+ public void start() {\r
+ startStopAction.setRunning(true);\r
+ super.start();\r
+ }\r
+ @Override\r
+ public void stop() {\r
+ startStopAction.setRunning(false);\r
+ super.stop();\r
+ }\r
+ }\r
/**\r
* このデータモデルをシーケンサに同期させるためのサンプリングタイマー\r
*/\r
- javax.swing.Timer timer = new javax.swing.Timer(INTERVAL_MS, this);\r
+ private Updater updater = new Updater(this);\r
/**\r
* 開始終了アクション\r
*/\r
}\r
@Override\r
public void actionPerformed(ActionEvent event) {\r
- if(timer.isRunning()) stop(); else start();\r
+ if(isRunning()) stop(); else start();\r
}\r
/**\r
* 開始されているかどうかを設定します。\r
public void actionPerformed(ActionEvent event) { moveMeasure(1); }\r
};\r
/**\r
- * 小節位置を移動します。\r
- * @param measureOffset 小節位置の移動量(負数も指定可)\r
+ * 小節単位で位置を移動します。\r
+ * @param measureOffset 何小節進めるか(戻したいときは負数を指定)\r
*/\r
private void moveMeasure(int measureOffset) {\r
if( measureOffset == 0 || seqModel == null )\r
public void actionPerformed(ActionEvent event) { }\r
};\r
/**\r
+ * シーケンサ\r
+ */\r
+ private Sequencer sequencer;\r
+ /**\r
* 新しい {@link SequencerTimeRangeModel} を構築します。\r
* @param deviceModelList MIDIデバイスモデルリスト\r
*/\r
}\r
@Override\r
public void meta(MetaMessage msg) {\r
- if( msg.getType() != 0x2F ) return;\r
- /* End-Of-Track */\r
- timer.stop();\r
- startStopAction.setRunning(false);\r
- sequencer.setMicrosecondPosition(0);\r
- if(\r
- (Boolean)toggleRepeatAction.getValue(Action.SELECTED_KEY)\r
- ||\r
- deviceModelList.editorDialog.loadNext(1)\r
- )\r
- start();\r
- else\r
- fireStateChanged();\r
+ if( msg.getType() == 0x2F ) { // EOT (End Of Track) を受信した場合\r
+ updater.stop();\r
+ // 先頭に戻す\r
+ sequencer.setMicrosecondPosition(0);\r
+ // リピートモードの場合、同じ曲をもう一度再生する。\r
+ // そうでない場合、次の曲へ進んで再生する。\r
+ // 次の曲がなければ、そこで終了。\r
+ boolean isRepeatMode = (Boolean)toggleRepeatAction.getValue(Action.SELECTED_KEY);\r
+ if( isRepeatMode || deviceModelList.editorDialog.loadNext(1) )\r
+ start();\r
+ else\r
+ fireStateChanged();\r
+ }\r
}\r
@Override\r
public int getExtent() { return 0; }\r
@Override\r
+ public void setExtent(int newExtent) {}\r
+ @Override\r
public int getMinimum() { return 0; }\r
+ @Override\r
+ public void setMinimum(int newMinimum) {}\r
private long getMicrosecondLength() {\r
//\r
// Sequencer.getMicrosecondLength() returns NEGATIVE value\r
public int getMaximum() {\r
return (int)(getMicrosecondLength()/1000L);\r
}\r
+ @Override\r
+ public void setMaximum(int newMaximum) {}\r
private long getMicrosecondPosition() {\r
long usPosition = sequencer.getMicrosecondPosition();\r
return usPosition < 0 ? 0x100000000L + usPosition : usPosition ;\r
return (int)(getMicrosecondPosition()/1000L);\r
}\r
@Override\r
- public void setExtent(int newExtent) {}\r
- @Override\r
- public void setMaximum(int newMaximum) {}\r
- @Override\r
- public void setMinimum(int newMinimum) {}\r
- @Override\r
- public void setRangeProperties(int value, int extent, int min, int max, boolean adjusting) {\r
- sequencer.setMicrosecondPosition( 1000L * (long)value );\r
- valueIsAdjusting = adjusting;\r
- fireStateChanged();\r
- }\r
- @Override\r
public void setValue(int newValue) {\r
sequencer.setMicrosecondPosition( 1000L * (long)newValue );\r
fireStateChanged();\r
valueIsAdjusting = b;\r
}\r
@Override\r
+ public void setRangeProperties(int value, int extent, int min, int max, boolean adjusting) {\r
+ sequencer.setMicrosecondPosition( 1000L * (long)value );\r
+ valueIsAdjusting = adjusting;\r
+ fireStateChanged();\r
+ }\r
+ @Override\r
public void actionPerformed(ActionEvent e) {\r
if( ! valueIsAdjusting ) fireStateChanged();\r
}\r
fireStateChanged();\r
return true;\r
}\r
-\r
public void start() {\r
if( ! sequencer.isOpen() || sequencer.getSequence() == null ) {\r
- startStopAction.setRunning(false);\r
+ updater.stop();\r
return;\r
}\r
- startStopAction.setRunning(true);\r
- timer.start();\r
+ updater.start();\r
if( deviceModelList.isRecordable() ) {\r
for( MidiConnecterListModel model : deviceModelList )\r
model.resetMicrosecondPosition();\r
sequencer.startRecording();\r
}\r
else {\r
- System.gc(); sequencer.start();\r
+ System.gc();\r
+ sequencer.start();\r
}\r
fireStateChanged();\r
}\r
public void stop() {\r
- if( sequencer.isOpen() )\r
- sequencer.stop();\r
- timer.stop();\r
- startStopAction.setRunning(false);\r
+ if(sequencer.isOpen()) sequencer.stop();\r
+ updater.stop();\r
fireStateChanged();\r
}\r
+ /**\r
+ * サンプリングタイマーが実行中の場合trueを返します。\r
+ * @return 実行中の場合true\r
+ */\r
+ public boolean isRunning() { return updater.isRunning(); }\r
}\r