OSDN Git Service

・MIDIデバイスダイアログに時間リセットボタン追加
authorAkiyoshi Kamide <kamide@yk.rim.or.jp>
Sat, 4 Jun 2016 17:05:23 +0000 (02:05 +0900)
committerAkiyoshi Kamide <kamide@yk.rim.or.jp>
Sat, 4 Jun 2016 17:05:23 +0000 (02:05 +0900)
・再生速度の目盛りに倍率を入れるようにした

src/camidion/chordhelper/ChordHelperApplet.java
src/camidion/chordhelper/mididevice/MidiDeviceDialog.java
src/camidion/chordhelper/mididevice/MidiDeviceTreeView.java
src/camidion/chordhelper/mididevice/MidiSequencerModel.java
src/camidion/chordhelper/mididevice/MidiTransceiverListModel.java
src/camidion/chordhelper/mididevice/MidiTransceiverListModelList.java
src/camidion/chordhelper/midieditor/SequencerSpeedSlider.java

index 0bfed88..9d82d13 100644 (file)
@@ -285,7 +285,7 @@ public class ChordHelperApplet extends JApplet {
         */
        public static class VersionInfo {
                public static final String      NAME = "MIDI Chord Helper";
-               public static final String      VERSION = "Ver.20160530.1";
+               public static final String      VERSION = "Ver.20160604.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/";
index 5b9820b..b44a51e 100644 (file)
@@ -1,10 +1,14 @@
 package camidion.chordhelper.mididevice;
 
 import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 
 import javax.swing.AbstractAction;
 import javax.swing.Action;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
 import javax.swing.JDialog;
+import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.JSplitPane;
 
@@ -15,24 +19,48 @@ import camidion.chordhelper.ButtonIcon;
  */
 public class MidiDeviceDialog extends JDialog {
        /**
+        * MIDIデバイスダイアログを開くアクション
+        */
+       public Action openAction = new AbstractAction() {
+               {
+                       putValue(NAME, "MIDI device connection");
+                       putValue(SHORT_DESCRIPTION, "MIDIデバイス間の接続を編集");
+                       putValue(LARGE_ICON_KEY, new ButtonIcon(ButtonIcon.MIDI_CONNECTOR_ICON));
+               }
+               @Override
+               public void actionPerformed(ActionEvent event) { setVisible(true); }
+       };
+       /**
         * MIDIデバイスダイアログを構築します。
         * @param deviceModelList デバイスモデル(MIDIコネクタリストモデル)のリスト
         */
-       public MidiDeviceDialog(MidiTransceiverListModelList deviceModelList) {
+       public MidiDeviceDialog(final MidiTransceiverListModelList deviceModelList) {
                setTitle(openAction.getValue(Action.NAME).toString());
                setBounds( 300, 300, 800, 500 );
                MidiDeviceTreeModel deviceTreeModel = new MidiDeviceTreeModel(deviceModelList);
                MidiDeviceTreeView deviceTreeView = new MidiDeviceTreeView(deviceTreeModel);
-               MidiDeviceInfoPane deviceInfoPane = new MidiDeviceInfoPane();
+               final MidiDeviceInfoPane deviceInfoPane = new MidiDeviceInfoPane();
                MidiOpenedDevicesView desktopPane = new MidiOpenedDevicesView(deviceTreeView, deviceInfoPane, this);
                deviceTreeView.addTreeSelectionListener(deviceInfoPane);
                deviceTreeView.addTreeSelectionListener(desktopPane);
+               deviceTreeView.setSelectionRow(0);
                add(new JSplitPane(
                        JSplitPane.HORIZONTAL_SPLIT,
                        new JSplitPane(
                                JSplitPane.VERTICAL_SPLIT,
                                new JScrollPane(deviceTreeView),
-                               new JScrollPane(deviceInfoPane)
+                               new JPanel() {{
+                                       add(new JScrollPane(deviceInfoPane));
+                                       add(new JButton("Reset time on MIDI devices") {{
+                                               addActionListener(new ActionListener() {
+                                                       @Override
+                                                       public void actionPerformed(ActionEvent e) {
+                                                               deviceModelList.resetMicrosecondPosition();
+                                                       }
+                                               });
+                                       }});
+                                       setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
+                               }}
                        ){{
                                setDividerLocation(260);
                        }},
@@ -42,16 +70,4 @@ public class MidiDeviceDialog extends JDialog {
                        setDividerLocation(250);
                }});
        }
-       /**
-        * MIDIデバイスダイアログを開くアクション
-        */
-       public Action openAction = new AbstractAction() {
-               {
-                       putValue(NAME, "MIDI device connection");
-                       putValue(SHORT_DESCRIPTION, "MIDIデバイス間の接続を編集");
-                       putValue(LARGE_ICON_KEY, new ButtonIcon(ButtonIcon.MIDI_CONNECTOR_ICON));
-               }
-               @Override
-               public void actionPerformed(ActionEvent event) { setVisible(true); }
-       };
 }
index 8a93741..e8bd6a0 100644 (file)
@@ -108,10 +108,11 @@ public class MidiDeviceTreeView extends JTree {
                                return this;
                        }
                });
-               // 初期状態でツリーノードを開いた状態にする
+               // ツリーノードを開き、ルートを選択した状態にする
                for( int row = 0; row < getRowCount() ; row++ ) expandRow(row);
                //
                // ツリーノードのToolTipを有効化
                ToolTipManager.sharedInstance().registerComponent(this);
+
        }
 }
index f6da069..8fa2cf2 100644 (file)
@@ -23,6 +23,7 @@ import javax.swing.event.ListDataListener;
 import camidion.chordhelper.ButtonIcon;
 import camidion.chordhelper.midieditor.SequenceTickIndex;
 import camidion.chordhelper.midieditor.SequenceTrackListTableModel;
+import camidion.chordhelper.midieditor.SequencerSpeedSlider;
 
 /**
  * MIDIシーケンサモデル
@@ -43,10 +44,7 @@ public class MidiSequencerModel extends MidiTransceiverListModel implements Boun
                addChangeListener(new ChangeListener() {
                        @Override
                        public void stateChanged(ChangeEvent e) {
-                               int val = getValue();
-                               getSequencer().setTempoFactor((float)(
-                                       val == 0 ? 1.0 : Math.pow( 2.0, ((double)val)/12.0 )
-                               ));
+                               getSequencer().setTempoFactor(SequencerSpeedSlider.tempoFactorOf(getValue()));
                        }
                });
        }};
@@ -92,8 +90,7 @@ public class MidiSequencerModel extends MidiTransceiverListModel implements Boun
        /**
         * シーケンサに合わせてミリ秒位置を更新するタイマー
         */
-       private javax.swing.Timer timeRangeUpdater = new javax.swing.Timer(
-               20,
+       private javax.swing.Timer timeRangeUpdater = new javax.swing.Timer( 20,
                new ActionListener(){
                        @Override
                        public void actionPerformed(ActionEvent e) {
@@ -126,7 +123,7 @@ public class MidiSequencerModel extends MidiTransceiverListModel implements Boun
                timeRangeUpdater.start();
                SequenceTrackListTableModel sequenceTableModel = getSequenceTrackListTableModel();
                if( sequenceTableModel != null && sequenceTableModel.hasRecordChannel() ) {
-                       for(MidiTransceiverListModel m : deviceModelList) m.resetMicrosecondPosition();
+                       deviceModelList.resetMicrosecondPosition();
                        System.gc();
                        sequencer.startRecording();
                }
@@ -266,12 +263,8 @@ public class MidiSequencerModel extends MidiTransceiverListModel implements Boun
                if( sequenceTableModel != null || getSequencer().isOpen() ) {
                        getSequencer().setSequence(sequenceTableModel == null ? null : sequenceTableModel.getSequence());
                }
-               if( this.sequenceTableModel != null ) {
-                       this.sequenceTableModel.fireTableDataChanged();
-               }
-               if( sequenceTableModel != null ) {
-                       sequenceTableModel.fireTableDataChanged();
-               }
+               if( this.sequenceTableModel != null ) this.sequenceTableModel.fireTableDataChanged();
+               if( sequenceTableModel != null ) sequenceTableModel.fireTableDataChanged();
                this.sequenceTableModel = sequenceTableModel;
                fireStateChanged();
        }
index b261a88..6783565 100644 (file)
@@ -197,14 +197,13 @@ public class MidiTransceiverListModel extends AbstractListModel<AutoCloseable> {
                if( ! txSupported() || device instanceof Sequencer ) return;
                //
                // デバイスを閉じる前に接続相手の情報を保存
-               List<Transmitter> txList = device.getTransmitters();
+               List<Transmitter> myTxList = device.getTransmitters();
                List<Receiver> peerRxList = new Vector<Receiver>();
-               for( Transmitter tx : txList ) {
-                       Receiver rx = tx.getReceiver();
-                       if( rx != null ) peerRxList.add(rx);
+               Receiver rx;
+               for( Transmitter tx : myTxList ) {
+                       if( (rx = tx.getReceiver()) != null ) peerRxList.add(rx);
                }
                List<Transmitter> peerTxList = null;
-               Receiver rx = null;
                if( rxSupported() ) {
                        rx = device.getReceivers().get(0);
                        peerTxList = new Vector<Transmitter>();
index 70d713c..1c3fc70 100644 (file)
@@ -118,4 +118,11 @@ public class MidiTransceiverListModelList extends Vector<MidiTransceiverListMode
                        sequencerModel.connectToReceiverOf(firstMidiOutModel);
                }
        }
-}
\ No newline at end of file
+       /**
+        * すべてのデバイスについて、{@link MidiTransceiverListModel#resetMicrosecondPosition()}
+        * でマイクロ秒位置をリセットします。
+        */
+       public void resetMicrosecondPosition() {
+               for(MidiTransceiverListModel m : this) m.resetMicrosecondPosition();
+       }
+}
index 73f23ff..2c63dc8 100644 (file)
@@ -1,58 +1,86 @@
 package camidion.chordhelper.midieditor;
 
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
 
+import javax.swing.AbstractSpinnerModel;
 import javax.swing.BoundedRangeModel;
 import javax.swing.BoxLayout;
-import javax.swing.JComboBox;
+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;
 
 /**
  * シーケンサーの再生スピード調整スライダビュー
  */
 public class SequencerSpeedSlider extends JPanel {
-       private static final String items[] = {
-               "x 1.0",
-               "x 1.5",
-               "x 2",
-               "x 4",
-               "x 8",
-               "x 16",
-       };
+       public static float tempoFactorOf(int val) {
+               return (float) Math.pow( 2, ((double)val)/12.0 );
+       }
+       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 JLabel titleLabel;
        private JSlider slider;
        public SequencerSpeedSlider(BoundedRangeModel model) {
                setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
-               add(titleLabel = new JLabel("Speed:"));
+               add(titleLabel = new JLabel("Speed: "));
                add(slider = new JSlider(model){{
                        setPaintTicks(true);
                        setMajorTickSpacing(12);
                        setMinorTickSpacing(1);
+                       setPaintLabels(true);
                        setVisible(false);
                }});
-               add(new JComboBox<String>(items) {{
-                       addActionListener(new ActionListener() {
+               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();
+                       }
+                       @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 actionPerformed(ActionEvent e) {
-                                       int index = getSelectedIndex();
+                               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;
                                        }
-                                       else {
-                                               int maxValue = ( index == 1 ? 7 : (index-1)*12 );
-                                               model.setMinimum(-maxValue);
-                                               model.setMaximum(maxValue);
-                                               slider.setMajorTickSpacing( index == 1 ? 7 : 12 );
-                                               slider.setMinorTickSpacing( index > 3 ? 12 : 1 );
-                                               slider.setVisible(true);
-                                               titleLabel.setVisible(false);
-                                       }
+                                       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);
                                }
                        });
                }});