import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MetaEventListener;
import javax.sound.midi.MetaMessage;
+import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.swing.AbstractAction;
import javax.swing.Action;
* 指定された小節数の曲を、乱数で自動作曲してプレイリストへ追加します。
* @param measureLength 小節数
* @return 追加先のインデックス値(0から始まる)。追加できなかったときは -1
+ * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
*/
- public int addRandomSongToPlaylist(int measureLength) {
+ public int addRandomSongToPlaylist(int measureLength) throws InvalidMidiDataException {
NewSequenceDialog d = midiEditor.newSequenceDialog;
d.setRandomChordProgression(measureLength);
return playlistModel.addSequenceAndPlay(d.getMidiSequence());
/**
* プレイリスト上で現在選択されているMIDIシーケンスを、
* シーケンサへロードして再生します。
+ * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
*/
- public void play() { play(playlistModel.sequenceListSelectionModel.getMinSelectionIndex()); }
+ public void play() throws InvalidMidiDataException { play(playlistModel.sequenceListSelectionModel.getMinSelectionIndex()); }
/**
* 指定されたインデックス値が示すプレイリスト上のMIDIシーケンスを、
* シーケンサへロードして再生します。
* @param index インデックス値(0から始まる)
+ * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
*/
- public void play(int index) { playlistModel.loadToSequencer(index); sequencerModel.start(); }
+ public void play(int index) throws InvalidMidiDataException {
+ playlistModel.loadToSequencer(index); sequencerModel.start();
+ }
/**
* シーケンサが実行中かどうかを返します。
* {@link Sequencer#isRunning()} の戻り値をそのまま返します。
*/
public static class VersionInfo {
public static final String NAME = "MIDI Chord Helper";
- public static final String VERSION = "Ver.20160528.1";
+ public static final String VERSION = "Ver.20160529.1";
public static final String COPYRIGHT = "Copyright (C) 2004-2016";
public static final String AUTHER = "@きよし - Akiyoshi Kamide";
public static final String URL = "http://www.yk.rim.or.jp/~kamide/music/chordhelper/";
}
public void chordChanged() { chordOn(); }
});
+ capoSelecter.checkbox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ chordOn();
+ keyboardPanel.keyboardCenterPanel.keyboard.chordDisplay.clear();
+ chordDiagram.clear();
+ }
+ });
+ capoSelecter.valueSelecter.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ chordOn();
+ keyboardPanel.keyboardCenterPanel.keyboard.chordDisplay.clear();
+ chordDiagram.clear();
+ }
+ });
}};
keysigLabel = new KeySignatureLabel() {{
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) { chordMatrix.setKeySignature(getKey()); }
});
}};
- chordMatrix.capoSelecter.checkbox.addItemListener(new ItemListener() {
- public void itemStateChanged(ItemEvent e) {
- chordOn();
- keyboardPanel.keyboardCenterPanel.keyboard.chordDisplay.clear();
- chordDiagram.clear();
- }
- });
- chordMatrix.capoSelecter.valueSelecter.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- chordOn();
- keyboardPanel.keyboardCenterPanel.keyboard.chordDisplay.clear();
- chordDiagram.clear();
- }
- });
keyboardPanel = new MidiKeyboardPanel(chordMatrix) {{
keyboardCenterPanel.keyboard.addPianoKeyboardListener(new PianoKeyboardAdapter() {
@Override
System.gc();
if( midi_url != null ) {
addToPlaylist(midi_url);
- play();
+ try {
+ play();
+ } catch (InvalidMidiDataException ex) {
+ ex.printStackTrace();
+ }
}
}
@Override
* MIDIトラックリストテーブルモデルをこのシーケンサーモデルにセットします。
* nullを指定してアンセットすることもできます。
* @param sequenceTableModel MIDIトラックリストテーブルモデル
- * @return 成功したらtrue
+ * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
*/
- public boolean setSequenceTrackListTableModel(SequenceTrackListTableModel sequenceTableModel) {
+ public void setSequenceTrackListTableModel(SequenceTrackListTableModel sequenceTableModel)
+ throws InvalidMidiDataException
+ {
// javax.sound.midi:Sequencer.setSequence() のドキュメントにある
// 「このメソッドは、Sequencer が閉じている場合でも呼び出すことができます。 」
// という記述は、null をセットする場合には当てはまらない。
// この現象を回避するため、あらかじめチェックしてから setSequence() を呼び出している。
//
if( sequenceTableModel != null || getSequencer().isOpen() ) {
- Sequence sequence = null;
- if( sequenceTableModel != null ) sequence = sequenceTableModel.getSequence();
- try {
- getSequencer().setSequence(sequence);
- } catch ( InvalidMidiDataException e ) {
- e.printStackTrace();
- return false;
- }
+ getSequencer().setSequence(sequenceTableModel == null ? null : sequenceTableModel.getSequence());
}
if( this.sequenceTableModel != null ) {
this.sequenceTableModel.fireTableDataChanged();
}
this.sequenceTableModel = sequenceTableModel;
fireStateChanged();
- return true;
}
-
/**
* 小節単位で位置を移動します。
* @param measureOffset 何小節進めるか(戻したいときは負数を指定)
import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiEvent;
import javax.sound.midi.MidiMessage;
+import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.ShortMessage;
import javax.swing.AbstractAction;
public void drop(DropTargetDropEvent event) {
event.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
try {
- int action = event.getDropAction();
- if ( (action & DnDConstants.ACTION_COPY_OR_MOVE) != 0 ) {
+ if ( (event.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) != 0 ) {
Transferable t = event.getTransferable();
if( t.isDataFlavorSupported(DataFlavor.javaFileListFlavor) ) {
loadAndPlay((List<File>)t.getTransferData(DataFlavor.javaFileListFlavor));
* すでに再生されていた場合、このエディタダイアログを表示します。
*
* @param fileList 読み込むMIDIファイルのリスト
+ * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
* @see #loadAndPlay(File)
*/
public void loadAndPlay(List<File> fileList) {
showError(e.getMessage());
e.printStackTrace();
}
- MidiSequencerModel sequencerModel = playlist.sequencerModel;
- if( sequencerModel.getSequencer().isRunning() ) {
+ if( playlist.sequencerModel.getSequencer().isRunning() ) {
String command = (String)openAction.getValue(Action.NAME);
openAction.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, command));
return;
}
if( indexOfAddedTop >= 0 ) {
- playlist.loadToSequencer(indexOfAddedTop);
- sequencerModel.start();
+ try {
+ playlist.loadToSequencer(indexOfAddedTop);
+ } catch (InvalidMidiDataException ex) {
+ ex.printStackTrace();
+ showError(ex.getMessage());
+ return;
+ }
+ playlist.sequencerModel.start();
}
}
/**
* すでに再生されていた場合、このエディタダイアログを表示します。
*
* @param file 読み込むMIDIファイル
+ * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
* @see #loadAndPlay(List) loadAndPlay(List<File>)
*/
- public void loadAndPlay(File file) { loadAndPlay(Arrays.asList(file)); }
+ public void loadAndPlay(File file) throws InvalidMidiDataException {
+ loadAndPlay(Arrays.asList(file));
+ }
private static final Insets ZERO_INSETS = new Insets(0,0,0,0);
private static final Icon deleteIcon = new ButtonIcon(ButtonIcon.X_ICON);
/**
* 時間位置表示セルエディタ(ダブルクリック専用)
*/
- private class PositionCellEditor extends AbstractCellEditor
- implements TableCellEditor
- {
+ private class PositionCellEditor extends AbstractCellEditor implements TableCellEditor {
public PositionCellEditor() {
int column = PlaylistTableModel.Column.POSITION.ordinal();
TableColumn tc = getColumnModel().getColumn(column);
*/
@Override
public Component getTableCellEditorComponent(
- JTable table, Object value, boolean isSelected,
- int row, int column
+ JTable table, Object value, boolean isSelected, int row, int column
) {
- getModel().loadToSequencer(row);
+ try {
+ getModel().loadToSequencer(row);
+ } catch (InvalidMidiDataException ex) {
+ ex.printStackTrace();
+ showError(ex.getMessage());
+ }
fireEditingStopped();
return null;
}
fireEditingStopped();
PlaylistTableModel model = getModel();
if( model.getSequenceList().get(row).isOnSequencer() ) return playButton;
- model.loadToSequencer(row);
+ try {
+ model.loadToSequencer(row);
+ } catch (InvalidMidiDataException ex) {
+ ex.printStackTrace();
+ showError(ex.getMessage());
+ }
return null;
}
@Override
"Delete selected MIDI sequence - 選択した曲をプレイリストから削除"
) {
@Override
- public void actionPerformed(ActionEvent e) {
+ public void actionPerformed(ActionEvent event) {
PlaylistTableModel model = getModel();
if( midiFileChooser != null ) {
if( model.getSelectedSequenceModel().isModified() ) {
if( ! confirm(message) ) return;
}
}
- model.removeSelectedSequence();
+ try {
+ model.removeSelectedSequence();
+ } catch (InvalidMidiDataException ex) {
+ ex.printStackTrace();
+ showError(ex.getMessage());
+ }
}
};
/**
@Override
public void actionPerformed(ActionEvent event) {
if( showOpenDialog((Component)event.getSource()) != JFileChooser.APPROVE_OPTION ) return;
- loadAndPlay(getSelectedFile());
+ try {
+ loadAndPlay(getSelectedFile());
+ } catch (InvalidMidiDataException ex) {
+ ex.printStackTrace();
+ showError(ex.getMessage());
+ }
}
};
};
this.outputMidiDevice = outputMidiDevice;
sequenceListTable = new SequenceListTable(playlistTableModel);
trackListTable = new TrackListTable(
- new SequenceTrackListTableModel(sequenceListTable.getModel(), null, null)
+ new SequenceTrackListTableModel(playlistTableModel, null, null)
);
eventListTable = new EventListTable(new TrackEventListTableModel(trackListTable.getModel(), null));
newSequenceDialog = new NewSequenceDialog(playlistTableModel, outputMidiDevice);
add(new JButton(newSequenceDialog.openAction) {{ setMargin(ZERO_INSETS); }});
if( sequenceListTable.midiFileChooser != null ) {
add( Box.createRigidArea(new Dimension(5, 0)) );
- add(new JButton(sequenceListTable.midiFileChooser.openMidiFileAction) {{
- setMargin(ZERO_INSETS);
- }});
+ add(new JButton(sequenceListTable.midiFileChooser.openMidiFileAction) {{ setMargin(ZERO_INSETS); }});
}
if(sequenceListTable.base64EncodeAction != null) {
add(Box.createRigidArea(new Dimension(5, 0)));
add(new JButton(playlistTableModel.moveToBottomAction) {{ setMargin(ZERO_INSETS); }});
if( sequenceListTable.midiFileChooser != null ) {
add(Box.createRigidArea(new Dimension(5, 0)));
- add(new JButton(sequenceListTable.midiFileChooser.saveMidiFileAction) {{
- setMargin(ZERO_INSETS);
- }});
+ add(new JButton(sequenceListTable.midiFileChooser.saveMidiFileAction) {{ setMargin(ZERO_INSETS); }});
}
add( Box.createRigidArea(new Dimension(5, 0)) );
add(new JButton(sequenceListTable.deleteSequenceAction) {{ setMargin(ZERO_INSETS); }});
import java.util.ArrayList;
import java.util.Vector;
+import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiChannel;
import javax.sound.midi.Sequence;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
+import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
* MIDIシーケンス生成アクション
*/
public Action generateAction = new AbstractAction(
- "Generate & Add to PlayList",
- new ButtonIcon(ButtonIcon.EJECT_ICON)
+ "Generate & Add to PlayList", new ButtonIcon(ButtonIcon.EJECT_ICON)
) {
@Override
- public void actionPerformed(ActionEvent e) {
- playlist.addSequenceAndPlay(getMidiSequence());
- NewSequenceDialog.this.setVisible(false);
+ public void actionPerformed(ActionEvent event) {
+ try {
+ playlist.addSequenceAndPlay(getMidiSequence());
+ } catch (InvalidMidiDataException ex) {
+ ex.printStackTrace();
+ JOptionPane.showMessageDialog(
+ NewSequenceDialog.this, ex.getMessage(),
+ ChordHelperApplet.VersionInfo.NAME, JOptionPane.ERROR_MESSAGE);
+ }
+ setVisible(false);
}
};
/**
import javax.sound.midi.MetaMessage;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Sequence;
+import javax.sound.midi.Sequencer;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultListSelectionModel;
import javax.swing.Icon;
+import javax.swing.JOptionPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.table.AbstractTableModel;
import camidion.chordhelper.ButtonIcon;
+import camidion.chordhelper.ChordHelperApplet;
import camidion.chordhelper.mididevice.MidiSequencerModel;
import camidion.chordhelper.music.ChordProgression;
private void goNext() {
// とりあえず曲の先頭へ戻る
sequencerModel.getSequencer().setMicrosecondPosition(0);
- if( (Boolean)toggleRepeatAction.getValue(Action.SELECTED_KEY) || loadNext(1)) {
+ if( (Boolean)toggleRepeatAction.getValue(Action.SELECTED_KEY) || loadNext(1) ) {
// リピートモードのときはもう一度同じ曲を、
// そうでない場合は次の曲を再生開始
sequencerModel.start();
this.preferredWidth = preferredWidth;
}
public boolean isCellEditable() { return false; }
- public Object getValueOf(SequenceTrackListTableModel sequenceModel) {
- return "";
- }
+ public Object getValueOf(SequenceTrackListTableModel sequenceModel) { return ""; }
}
@Override
* シーケンサーが停止中の場合、追加したシーケンスから再生を開始します。
* @param sequence MIDIシーケンス
* @return 追加先インデックス(先頭が 0)
+ * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
*/
- public int addSequenceAndPlay(Sequence sequence) {
+ public int addSequenceAndPlay(Sequence sequence) throws InvalidMidiDataException {
int lastIndex = addSequence(sequence,"");
if( ! sequencerModel.getSequencer().isRunning() ) {
loadToSequencer(lastIndex);
/**
* 選択されたシーケンスを除去します。
* 除去されたシーケンスがシーケンサーにロード済みの場合、アンロードします。
+ *
+ * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
*/
- public void removeSelectedSequence() {
+ public void removeSelectedSequence() throws InvalidMidiDataException {
if( sequenceListSelectionModel.isSelectionEmpty() ) return;
int selectedIndex = sequenceListSelectionModel.getMinSelectionIndex();
- if( sequenceList.remove(selectedIndex).isOnSequencer() )
- sequencerModel.setSequenceTrackListTableModel(null);
+ if( ! sequenceList.remove(selectedIndex).isOnSequencer() ) return;
+ sequencerModel.setSequenceTrackListTableModel(null);
fireTableRowsDeleted(selectedIndex, selectedIndex);
}
/**
- * 指定したインデックス位置のシーケンスをシーケンサーにロードします。
- * すでに同じIDのシーケンスがロードされていた場合はスキップします。
- * @param index シーケンスのインデックス位置(-1 を指定するとアンロードされます)
+ * テーブル内の指定したインデックス位置にあるシーケンスをシーケンサーにロードします。
+ * インデックスに -1 を指定するとアンロードされます。
+ * 変更点がある場合、リスナー(テーブルビュー)に通知します。
+ *
+ * @param index ロードするシーケンスのインデックス位置、アンロードするときは -1
+ * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
*/
- public void loadToSequencer(int index) {
+ public void loadToSequencer(int index) throws InvalidMidiDataException {
SequenceTrackListTableModel oldSeq = sequencerModel.getSequenceTrackListTableModel();
SequenceTrackListTableModel newSeq = (index < 0 ? null : sequenceList.get(index));
- if(oldSeq == newSeq) return;
+ if( oldSeq == newSeq ) return;
sequencerModel.setSequenceTrackListTableModel(newSeq);
- //
- // 変更点をテーブルビューに通知して再表示してもらう
int columnIndices[] = {
Column.PLAY.ordinal(),
Column.POSITION.ordinal(),
/**
* 引数で示された数だけ次へ進めたシーケンスをロードします。
* @param offset 進みたいシーケンス数
- * @return 成功したらtrue
+ * @return true:ロード成功、false:これ以上進めない
+ * @throws InvalidMidiDataException {@link Sequencer#setSequence(Sequence)} を参照
*/
public boolean loadNext(int offset) {
int loadedIndex = indexOfSequenceOnSequencer();
int index = (loadedIndex < 0 ? 0 : loadedIndex + offset);
if( index < 0 || index >= sequenceList.size() ) return false;
- loadToSequencer(index);
+ try {
+ loadToSequencer(index);
+ } catch (InvalidMidiDataException ex) {
+ ex.printStackTrace();
+ JOptionPane.showMessageDialog(
+ null, ex.getMessage(),
+ ChordHelperApplet.VersionInfo.NAME, JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
return true;
}
}