*/
public static class VersionInfo {
public static final String NAME = "MIDI Chord Helper";
- public static final String VERSION = "Ver.20160604.1";
+ public static final String VERSION = "Ver.20160605.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/";
private JLabel songTitleLabel = new JLabel();
private AnoGakkiPane anoGakkiPane;
private JToggleButton anoGakkiToggleButton;
+ private MidiTransceiverListModelList deviceModelList;
public void init() {
//
VirtualMidiDevice guiMidiDevice = keyboardPanel.keyboardCenterPanel.keyboard.midiDevice;
//
// MIDIデバイス一覧を構築
- MidiTransceiverListModelList deviceModelList = new MidiTransceiverListModelList(Arrays.asList(guiMidiDevice));
+ deviceModelList = new MidiTransceiverListModelList(Arrays.asList(guiMidiDevice));
(midiDeviceDialog = new MidiDeviceDialog(deviceModelList)).setIconImage(iconImage);
//
// MIDIデバイス一覧のシーケンサと連携するプレイリストを構築
setPreferredSize(new Dimension(750,470));
}
@Override
+ public void destroy() {
+ deviceModelList.closeAllDevices();
+ super.destroy();
+ }
+ @Override
public void start() {
//
// コードボタンで設定されている現在の調を
if( ! applet.playlistModel.isModified() || applet.midiEditor.confirm(
"MIDI file not saved, exit anyway ?\n"+
"保存されていないMIDIファイルがありますが、終了してよろしいですか?"
- )) System.exit(0);
+ )) {
+ applet.destroy();
+ System.exit(0);
+ }
}
});
applet.sequencerModel.addChangeListener(new ChangeListener() {
int col = event.getColumn();
if( col == PlaylistTableModel.Column.FILENAME.ordinal() || col == TableModelEvent.ALL_COLUMNS ) {
PlaylistTableModel pl = (PlaylistTableModel) event.getSource();
- setFilenameToTitle(pl.sequencerModel.getSequenceTrackListTableModel());
+ setFilenameToTitle(pl.getSequencerModel().getSequenceTrackListTableModel());
}
}
});
public void resetMicrosecondPosition() {
for(MidiTransceiverListModel m : this) m.resetMicrosecondPosition();
}
+ /**
+ * すべてのMIDIデバイスを閉じます。
+ */
+ public void closeAllDevices() {
+ for(MidiTransceiverListModel m : this) m.device.close();
+ }
}
import javax.swing.JTable;
import javax.swing.JToggleButton;
import javax.swing.ListSelectionModel;
+import javax.swing.border.EtchedBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
showError(e.getMessage());
e.printStackTrace();
}
- if( playlist.sequencerModel.getSequencer().isRunning() ) {
+ MidiSequencerModel sequencerModel = playlist.getSequencerModel();
+ if( sequencerModel.getSequencer().isRunning() ) {
String command = (String)openAction.getValue(Action.NAME);
openAction.actionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, command));
return;
showError(ex.getMessage());
return;
}
- playlist.sequencerModel.start();
+ sequencerModel.start();
}
}
/**
implements TableCellEditor, TableCellRenderer
{
private JToggleButton playButton = new JToggleButton(
- getModel().sequencerModel.startStopAction
+ getModel().getSequencerModel().startStopAction
) {
{ setMargin(ZERO_INSETS); }
};
* @param model シーケンス(トラックリスト)データモデル
*/
public TrackListTable(SequenceTrackListTableModel model) {
- super(model, null, model.trackListSelectionModel);
+ super(model, null, model.getSelectionModel());
//
// 録音対象のMIDIチャンネルをコンボボックスで選択できるようにする
int colIndex = SequenceTrackListTableModel.Column.RECORD_CHANNEL.ordinal();
}}));
setAutoCreateColumnsFromModel(false);
//
- trackSelectionListener = new TrackSelectionListener();
titleLabel = new TitleLabel();
- model.sequenceListTableModel.sequenceListSelectionModel.addListSelectionListener(titleLabel);
+ model.getParent().sequenceListSelectionModel.addListSelectionListener(titleLabel);
TableColumnModel colModel = getColumnModel();
for( SequenceTrackListTableModel.Column c : SequenceTrackListTableModel.Column.values() )
colModel.getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth);
public void valueChanged(ListSelectionEvent event) {
if( event.getValueIsAdjusting() ) return;
SequenceTrackListTableModel oldModel = getModel();
- SequenceTrackListTableModel newModel = oldModel.sequenceListTableModel.getSelectedSequenceModel();
+ SequenceTrackListTableModel newModel = oldModel.getParent().getSelectedSequenceModel();
if( oldModel == newModel ) return;
//
// MIDIチャンネル選択中のときはキャンセルする
cancelCellEditing();
//
- int index = oldModel.sequenceListTableModel.sequenceListSelectionModel.getMinSelectionIndex();
+ int index = oldModel.getParent().sequenceListSelectionModel.getMinSelectionIndex();
String text = TITLE;
if( index >= 0 ) text = String.format(text+" - MIDI file No.%d", index);
setText(text);
if( newModel == null ) {
- newModel = oldModel.sequenceListTableModel.emptyTrackListTableModel;
+ newModel = oldModel.getParent().emptyTrackListTableModel;
addTrackAction.setEnabled(false);
}
else {
addTrackAction.setEnabled(true);
}
- oldModel.trackListSelectionModel.removeListSelectionListener(trackSelectionListener);
+ oldModel.getSelectionModel().removeListSelectionListener(trackSelectionListener);
setModel(newModel);
- setSelectionModel(newModel.trackListSelectionModel);
- newModel.trackListSelectionModel.addListSelectionListener(trackSelectionListener);
+ setSelectionModel(newModel.getSelectionModel());
+ newModel.getSelectionModel().addListSelectionListener(trackSelectionListener);
trackSelectionListener.valueChanged(null);
}
}
/**
* トラック選択リスナー
*/
- TrackSelectionListener trackSelectionListener;
- /**
- * 選択トラックの変更に反応するリスナー
- */
- private class TrackSelectionListener implements ListSelectionListener {
+ ListSelectionListener trackSelectionListener = new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if( e != null && e.getValueIsAdjusting() ) return;
- ListSelectionModel tlsm = getModel().trackListSelectionModel;
+ ListSelectionModel tlsm = getModel().getSelectionModel();
deleteTrackAction.setEnabled(! tlsm.isSelectionEmpty());
eventListTable.titleLabel.update(tlsm, getModel());
}
- }
+ };
/**
* {@inheritDoc}
*
* @param model トラック(イベントリスト)データモデル
*/
public EventListTable(TrackEventListTableModel model) {
- super(model, null, model.eventSelectionModel);
+ super(model, null, model.getSelectionModel());
//
// 列モデルにセルエディタを設定
eventCellEditor = new MidiEventCellEditor();
if( oldTrackModel == newTrackModel )
return;
if( newTrackModel == null ) {
- newTrackModel = getModel().sequenceTrackListTableModel.sequenceListTableModel.emptyEventListTableModel;
+ newTrackModel = getModel().getParent().getParent().emptyEventListTableModel;
queryJumpEventAction.setEnabled(false);
queryAddEventAction.setEnabled(false);
queryJumpEventAction.setEnabled(true);
queryAddEventAction.setEnabled(true);
}
- oldTrackModel.eventSelectionModel.removeListSelectionListener(eventSelectionListener);
+ oldTrackModel.getSelectionModel().removeListSelectionListener(eventSelectionListener);
setModel(newTrackModel);
- setSelectionModel(newTrackModel.eventSelectionModel);
- newTrackModel.eventSelectionModel.addListSelectionListener(eventSelectionListener);
+ setSelectionModel(newTrackModel.getSelectionModel());
+ newTrackModel.getSelectionModel().addListSelectionListener(eventSelectionListener);
}
}
*/
private class EventSelectionListener implements ListSelectionListener {
public EventSelectionListener() {
- getModel().eventSelectionModel.addListSelectionListener(this);
+ getModel().getSelectionModel().addListSelectionListener(this);
}
@Override
public void valueChanged(ListSelectionEvent e) {
*/
private void setSelectedEvent(TrackEventListTableModel trackModel) {
this.trackModel = trackModel;
- SequenceTrackListTableModel sequenceTableModel = trackModel.sequenceTrackListTableModel;
+ SequenceTrackListTableModel sequenceTableModel = trackModel.getParent();
int ppq = sequenceTableModel.getSequence().getResolution();
eventDialog.midiMessageForm.durationForm.setPPQ(ppq);
tickPositionModel.setSequenceIndex(sequenceTableModel.getSequenceTickIndex());
- selectedIndex = trackModel.eventSelectionModel.getMinSelectionIndex();
+ selectedIndex = trackModel.getSelectionModel().getMinSelectionIndex();
selectedMidiEvent = selectedIndex < 0 ? null : trackModel.getMidiEvent(selectedIndex);
currentTick = selectedMidiEvent == null ? 0 : selectedMidiEvent.getTick();
tickPositionModel.setTickPosition(currentTick);
MidiEvent partnerEvent = null;
eventDialog.midiMessageForm.setMessage(
selectedMidiEvent.getMessage(),
- trackModel.sequenceTrackListTableModel.charset
+ trackModel.getParent().charset
);
if( eventDialog.midiMessageForm.isNote() ) {
int partnerIndex = trackModel.getIndexOfPartnerFor(selectedIndex);
clipBoard.paste(trackModel, tick);
scrollToEventAt(tick);
// ペーストで曲の長さが変わったことをプレイリストに通知
- SequenceTrackListTableModel seqModel = trackModel.sequenceTrackListTableModel;
- seqModel.sequenceListTableModel.fireSequenceModified(seqModel);
+ SequenceTrackListTableModel seqModel = trackModel.getParent();
+ seqModel.getParent().fireSequenceModified(seqModel);
eventDialog.setVisible(false);
trackModel = null;
}
private boolean applyEvent() {
long tick = tickPositionModel.getTickPosition();
MidiMessageForm form = eventDialog.midiMessageForm;
- SequenceTrackListTableModel seqModel = trackModel.sequenceTrackListTableModel;
+ SequenceTrackListTableModel seqModel = trackModel.getParent();
MidiEvent newMidiEvent = new MidiEvent(form.getMessage(seqModel.charset), tick);
if( midiEventsToBeOverwritten != null ) {
// 上書き消去するための選択済イベントがあった場合
scrollToEventAt(partnerTick > tick ? partnerTick : tick);
}
}
- seqModel.sequenceListTableModel.fireSequenceModified(seqModel);
+ seqModel.getParent().fireSequenceModified(seqModel);
eventDialog.setVisible(false);
return true;
}
private int copiedEventsPPQ = 0;
public void copy(TrackEventListTableModel model, boolean withRemove) {
copiedEventsToPaste = model.getSelectedMidiEvents();
- copiedEventsPPQ = model.sequenceTrackListTableModel.getSequence().getResolution();
+ copiedEventsPPQ = model.getParent().getSequence().getResolution();
if( withRemove ) model.removeMidiEvents(copiedEventsToPaste);
boolean en = (copiedEventsToPaste != null && copiedEventsToPaste.length > 0);
queryPasteEventAction.setEnabled(en);
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); }});
add( Box.createRigidArea(new Dimension(5, 0)) );
- add(new SequencerSpeedSlider(playlistTableModel.sequencerModel.speedSliderModel));
+ add(new SequencerSpeedSlider(playlistTableModel.getSequencerModel().speedSliderModel));
add( Box.createRigidArea(new Dimension(5, 0)) );
add(new JPanel() {{
- MidiSequencerModel sequencerModel = sequenceListTable.getModel().sequencerModel;
- add(new JLabel("SyncMode:"));
- add(new JLabel("Master"));
+ setBorder(new EtchedBorder());
+ MidiSequencerModel sequencerModel = sequenceListTable.getModel().getSequencerModel();
+ add(new JLabel("Sync Master"));
add(new JComboBox<Sequencer.SyncMode>(sequencerModel.masterSyncModeModel));
add(new JLabel("Slave"));
add(new JComboBox<Sequencer.SyncMode>(sequencerModel.slaveSyncModeModel));
* プレイリスト(MIDIシーケンスリスト)のテーブルデータモデル
*/
public class PlaylistTableModel extends AbstractTableModel {
+ private MidiSequencerModel sequencerModel;
/**
- * MIDIシーケンサモデル
+ * このプレイリストと連携しているMIDIシーケンサモデルを返します。
*/
- public MidiSequencerModel sequencerModel;
+ public MidiSequencerModel getSequencerModel() { return sequencerModel; }
/**
* 空のトラックリストモデル
*/
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
};
+ /** 再生中のシーケンサーの秒位置リスナー */
+ private ChangeListener secondPosition = new ChangeListener() {
+ private int value = 0;
+ @Override
+ public void stateChanged(ChangeEvent event) {
+ Object src = event.getSource();
+ if( src instanceof MidiSequencerModel ) {
+ int newValue = ((MidiSequencerModel)src).getValue() / 1000;
+ if(value == newValue) return;
+ value = newValue;
+ int rowIndex = indexOfSequenceOnSequencer();
+ fireTableCellUpdated(rowIndex, Column.POSITION.ordinal());
+ }
+ }
+ @Override
+ public String toString() {
+ return String.format("%02d:%02d", value/60, value%60);
+ }
+ };
/**
* 新しいプレイリストのテーブルモデルを構築します。
* @param sequencerModel 連携するMIDIシーケンサーモデル
*/
public PlaylistTableModel(MidiSequencerModel sequencerModel) {
this.sequencerModel = sequencerModel;
- sequencerModel.addChangeListener(secondPosition = new SecondPosition());
+ sequencerModel.addChangeListener(secondPosition);
sequencerModel.getSequencer().addMetaEventListener(
new MetaEventListener() {
/**
public void actionPerformed(ActionEvent event) { }
};
/**
- * 再生中のシーケンサーの秒位置
- */
- private class SecondPosition implements ChangeListener {
- private int value = 0;
- /**
- * 再生中のシーケンサーの秒位置が変わったときに表示を更新します。
- * @param event 変更イベント
- */
- @Override
- public void stateChanged(ChangeEvent event) {
- Object src = event.getSource();
- if( src instanceof MidiSequencerModel ) {
- int newValue = ((MidiSequencerModel)src).getValue() / 1000;
- if(value == newValue) return;
- value = newValue;
- int rowIndex = indexOfSequenceOnSequencer();
- fireTableCellUpdated(rowIndex, Column.POSITION.ordinal());
- }
- }
- @Override
- public String toString() {
- return String.format("%02d:%02d", value/60, value%60);
- }
- }
- /**
* 曲の先頭または前の曲へ戻るアクション
*/
public Action moveToTopAction = new AbstractAction() {
public boolean isCellEditable() { return true; } // ダブルクリックだけ有効
@Override
public Object getValueOf(SequenceTrackListTableModel sequenceModel) {
- return sequenceModel.isOnSequencer()
- ? sequenceModel.sequenceListTableModel.secondPosition : "";
+ return sequenceModel.isOnSequencer() ? sequenceModel.getParent().secondPosition : "";
}
},
/** シーケンスの時間長(分:秒) */
public boolean isCellEditable(int row, int column) {
return Column.values()[column].isCellEditable();
}
- /** 再生中のシーケンサーの秒位置 */
- private SecondPosition secondPosition;
@Override
public Object getValueAt(int row, int column) {
PlaylistTableModel.Column c = Column.values()[column];
this.preferredWidth = preferredWidth;
}
}
+ private PlaylistTableModel sequenceListTableModel;
/**
- * 親のプレイリスト
+ * このモデルを収容している親のプレイリストを返します。
*/
- PlaylistTableModel sequenceListTableModel;
+ public PlaylistTableModel getParent() { return sequenceListTableModel; }
/**
* ラップされたMIDIシーケンス
*/
* トラックリスト
*/
private List<TrackEventListTableModel> trackModelList = new ArrayList<>();
- /**
- * 選択されているトラックのインデックス
- */
- ListSelectionModel trackListSelectionModel = new DefaultListSelectionModel(){
+ private ListSelectionModel trackListSelectionModel = new DefaultListSelectionModel(){
{
setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
};
/**
+ * 選択状態を返します。
+ */
+ public ListSelectionModel getSelectionModel() { return trackListSelectionModel; }
+ /**
* MIDIシーケンスとファイル名から {@link SequenceTrackListTableModel} を構築します。
* @param sequenceListTableModel 親のプレイリスト
* @param sequence MIDIシーケンス
case TRACK_NUMBER: return row;
case EVENTS: return sequence.getTracks()[row].size();
case MUTE:
- return isOnSequencer() ? sequenceListTableModel.sequencerModel.getSequencer().getTrackMute(row) : "";
+ return isOnSequencer() ? sequenceListTableModel.getSequencerModel().getSequencer().getTrackMute(row) : "";
case SOLO:
- return isOnSequencer() ? sequenceListTableModel.sequencerModel.getSequencer().getTrackSolo(row) : "";
+ return isOnSequencer() ? sequenceListTableModel.getSequencerModel().getSequencer().getTrackSolo(row) : "";
case RECORD_CHANNEL:
return isOnSequencer() ? trackModelList.get(row).getRecordingChannel() : "";
case CHANNEL: {
SequenceTrackListTableModel.Column c = Column.values()[column];
switch(c) {
case MUTE:
- sequenceListTableModel.sequencerModel.getSequencer().setTrackMute(row, ((Boolean)val).booleanValue());
+ sequenceListTableModel.getSequencerModel().getSequencer().setTrackMute(row, ((Boolean)val).booleanValue());
break;
case SOLO:
- sequenceListTableModel.sequencerModel.getSequencer().setTrackSolo(row, ((Boolean)val).booleanValue());
+ sequenceListTableModel.getSequencerModel().getSequencer().setTrackSolo(row, ((Boolean)val).booleanValue());
break;
case RECORD_CHANNEL:
trackModelList.get(row).setRecordingChannel((String)val);
private void setSequence(Sequence sequence) {
//
// 旧シーケンスの録音モードを解除
- sequenceListTableModel.sequencerModel.getSequencer().recordDisable(null); // The "null" means all tracks
+ sequenceListTableModel.getSequencerModel().getSequencer().recordDisable(null); // The "null" means all tracks
//
// トラックリストをクリア
int oldSize = trackModelList.size();
* @return シーケンサーが操作していたらtrue
*/
public boolean isOnSequencer() {
- return sequence == sequenceListTableModel.sequencerModel.getSequencer().getSequence();
+ return sequence == sequenceListTableModel.getSequencerModel().getSequencer().getSequence();
}
/**
* 録音しようとしているチャンネルの設定されたトラックがあるか調べます。
package camidion.chordhelper.midieditor;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.text.NumberFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;
-import javax.swing.AbstractSpinnerModel;
import javax.swing.BoundedRangeModel;
import javax.swing.BoxLayout;
+import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
-import javax.swing.JSpinner;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
+import javax.swing.border.EtchedBorder;
+
+import camidion.chordhelper.ChordHelperApplet;
/**
* シーケンサーの再生スピード調整スライダビュー
*/
public class SequencerSpeedSlider extends JPanel {
+ private static int RESOLUTION = 1200;
+ private static final List<String> maxFactors = Arrays.asList(
+ "x1", "x1.2", "x1.25", "x1.5", "x2", "x3", "x4", "x5", "x6",
+ "x8", "x12", "x16", "x24", "x32");
public static float tempoFactorOf(int val) {
- return (float) Math.pow( 2, ((double)val)/12.0 );
+ return (float) Math.pow( 2, ((double)val)/RESOLUTION );
}
- private static final List<Hashtable<Integer,JComponent>> labeltables = new ArrayList<Hashtable<Integer,JComponent>>() {{
- for( int i = 0; i < 5; i++ ) {
- Hashtable<Integer,JComponent> e = new Hashtable<>();
- add(e);
- e.put(-i * 12, new JLabel( "x" + Double.toString(Math.pow( 2, (double)(-i) )) ));
- e.put(0, new JLabel( "x1.0" ));
- e.put(i * 12, new JLabel( "x" + Double.toString(Math.pow( 2, (double)i )) ));
+ private static final List<Hashtable<Integer,JComponent>>
+ tickLabeltables = new ArrayList<Hashtable<Integer,JComponent>>()
+ {
+ {
+ NumberFormat formetter = NumberFormat.getInstance();
+ for( String maxFactorString : maxFactors ) {
+ Hashtable<Integer,JComponent> e = new Hashtable<>();
+ Double maxFactor = Double.parseDouble(maxFactorString.substring(1));
+ add(e);
+ int maxValue = (int) Math.round(Math.log(maxFactor) / Math.log(2) * RESOLUTION);
+ if( maxFactorString.equals("x1") ) {
+ e.put(0, new JLabel("Play speed : x1 (Original)"));
+ } else {
+ e.put(-maxValue, new JLabel("x" + formetter.format(1/maxFactor)));
+ e.put(0, new JLabel("x1"));
+ e.put(maxValue, new JLabel(maxFactorString));
+ }
+ }
}
- }};
- private JLabel titleLabel;
+ };
private JSlider slider;
+ private void changeSliderScale(String maxFactorString) {
+ int index = maxFactors.indexOf(maxFactorString);
+ slider.setLabelTable(tickLabeltables.get(index));
+ BoundedRangeModel sliderModel = slider.getModel();
+ Double maxFactor = Double.parseDouble(maxFactorString.substring(1));
+ int maxValue = (int) Math.round(Math.log(maxFactor) / Math.log(2) * RESOLUTION);
+ slider.setMajorTickSpacing((int) Math.round((double)maxValue / 2.0));
+ if( index > 0 ) {
+ sliderModel.setMinimum(-maxValue);
+ sliderModel.setMaximum(maxValue);
+ slider.setEnabled(true);
+ } else {
+ sliderModel.setMinimum(-1);
+ sliderModel.setValue(0);
+ sliderModel.setMaximum(1);
+ slider.setEnabled(false);
+ }
+ }
public SequencerSpeedSlider(BoundedRangeModel model) {
+ setBorder(new EtchedBorder());
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
- add(titleLabel = new JLabel("Speed: "));
- add(slider = new JSlider(model){{
- setPaintTicks(true);
- setMajorTickSpacing(12);
- setMinorTickSpacing(1);
- setPaintLabels(true);
- setVisible(false);
- }});
- add(new JLabel("x"));
- add(new JSpinner(new AbstractSpinnerModel() {
- private int index = 0;
- @Override
- public Object getValue() { return Math.pow( 2, (double)index ); }
- @Override
- public void setValue(Object value) {
- index = (int) Math.round( Math.log((Double)value) / Math.log(2) );
- fireStateChanged();
+ add(slider = new JSlider(model){
+ {
+ setPaintTicks(true);
+ setMajorTickSpacing(RESOLUTION/2);
+ setPaintLabels(true);
+ setLabelTable(tickLabeltables.get(0));
+ setEnabled(false);
}
- @Override
- public Object getNextValue() {
- return index >= 4 ? null : Math.pow( 2, (double)(++index) );
- }
- @Override
- public Object getPreviousValue() {
- return index <= 0 ? null : Math.pow( 2, (double)(--index) );
- }
- }) {{
- addChangeListener(new ChangeListener() {
- @Override
- public void stateChanged(ChangeEvent e) {
- int index = (int) Math.round( Math.log((Double)getValue()) / Math.log(2) );
- BoundedRangeModel model = slider.getModel();
- if( index == 0 ) {
- model.setValue(0);
- slider.setVisible(false);
- titleLabel.setVisible(true);
- return;
+ });
+ add(new JPanel() {
+ private int index = 0;
+ private JButton push, pull;
+ {
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ add(pull = new JButton("=>|") {
+ {
+ setSize(new Dimension(20,20));
+ setMargin(ChordHelperApplet.ZERO_INSETS);
+ addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ int max = maxFactors.size() - 1;
+ if( index >= max ) return;
+ changeSliderScale(maxFactors.get(++index));
+ if( index >= max ) {
+ setEnabled(false);
+ push.requestFocusInWindow();
+ return;
+ }
+ push.setEnabled(true);
+ }
+ });
}
- int maxValue = index * 12;
- model.setMinimum(-maxValue);
- model.setMaximum(maxValue);
- slider.setMajorTickSpacing(12);
- slider.setMinorTickSpacing(index > 2 ? 12 : 1);
- slider.setLabelTable(labeltables.get(index));
- slider.setVisible(true);
- titleLabel.setVisible(false);
- }
- });
- }});
+ });
+ add(push = new JButton("<=|") {
+ {
+ setSize(new Dimension(20,20));
+ setMargin(ChordHelperApplet.ZERO_INSETS);
+ setEnabled(false);
+ addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if( index <= 0 ) return;
+ changeSliderScale(maxFactors.get(--index));
+ if( index <= 0 ) {
+ setEnabled(false);
+ pull.requestFocusInWindow();
+ return;
+ }
+ pull.setEnabled(true);
+ }
+ });
+ }
+ });
+ }
+ });
}
-}
\ No newline at end of file
+}
* ラップされているMIDIトラック
*/
private Track track;
+ private SequenceTrackListTableModel sequenceTrackListTableModel;
/**
- * 親のシーケンスモデル
+ * このトラックモデルを収容している親のシーケンスモデルを返します。
*/
- SequenceTrackListTableModel sequenceTrackListTableModel;
- /**
- * 選択されているイベントのインデックス
- */
- ListSelectionModel eventSelectionModel = new DefaultListSelectionModel() {
+ public SequenceTrackListTableModel getParent() {
+ return sequenceTrackListTableModel;
+ }
+ private ListSelectionModel eventSelectionModel = new DefaultListSelectionModel() {
{
setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
};
/**
+ * 選択状態を返します。
+ */
+ public ListSelectionModel getSelectionModel() { return eventSelectionModel; }
+ /**
* シーケンスを親にして、その特定のトラックに連動する
* MIDIトラックモデルを構築します。
*
fireTableDataChanged();
if( MIDISpec.isEOT(msg) ) {
// EOTの場所が変わると曲の長さが変わるので、親モデルへ通知する。
- sequenceTrackListTableModel.sequenceListTableModel.fireSequenceModified(sequenceTrackListTableModel);
+ sequenceTrackListTableModel.getParent().fireSequenceModified(sequenceTrackListTableModel);
}
}
/**
if( ! MIDISpec.setNameBytesOf(track, b) )
return false;
sequenceTrackListTableModel.setModified(true);
- sequenceTrackListTableModel.sequenceListTableModel.fireSequenceModified(sequenceTrackListTableModel);
+ sequenceTrackListTableModel.getParent().fireSequenceModified(sequenceTrackListTableModel);
fireTableDataChanged();
return true;
}
* @param recordingChannel 録音中のMIDIチャンネル
*/
public void setRecordingChannel(String recordingChannel) {
- Sequencer sequencer = sequenceTrackListTableModel.sequenceListTableModel.sequencerModel.getSequencer();
+ Sequencer sequencer = sequenceTrackListTableModel.getParent().getSequencerModel().getSequencer();
if( recordingChannel.equals("OFF") ) {
sequencer.recordDisable( track );
}
int oldLastIndex = lastIndex + midiEvents.length;
if(lastIndex < 0) lastIndex = 0;
fireTableRowsDeleted(oldLastIndex, lastIndex);
- sequenceTrackListTableModel.sequenceListTableModel.fireSelectedSequenceModified();
+ sequenceTrackListTableModel.getParent().fireSelectedSequenceModified();
}
/**
* 引数の選択内容が示すMIDIイベントを除去します。