OSDN Git Service

曲選択動作の見直し
authorAkiyoshi Kamide <kamide@yk.rim.or.jp>
Thu, 27 Apr 2017 16:53:44 +0000 (01:53 +0900)
committerAkiyoshi Kamide <kamide@yk.rim.or.jp>
Thu, 27 Apr 2017 16:53:44 +0000 (01:53 +0900)
src/camidion/chordhelper/ChordHelperApplet.java
src/camidion/chordhelper/midieditor/MidiEventTable.java
src/camidion/chordhelper/midieditor/MidiEventTableModel.java
src/camidion/chordhelper/midieditor/MidiSequenceEditorDialog.java
src/camidion/chordhelper/midieditor/NewSequenceDialog.java
src/camidion/chordhelper/midieditor/PlaylistTable.java
src/camidion/chordhelper/midieditor/PlaylistTableModel.java
src/camidion/chordhelper/midieditor/SequenceTrackListTable.java
src/camidion/chordhelper/midieditor/SequenceTrackListTableModel.java

index 6ce9f19..1c683a3 100644 (file)
@@ -143,9 +143,7 @@ public class ChordHelperApplet extends JApplet {
        /**
         * プレイリスト上で現在選択されているMIDIシーケンスをシーケンサへロードして再生します。
         */
-       public void play() {
-               play(playlistModel.getSelectionModel().getMinSelectionIndex());
-       }
+       public void play() { midiEditor.play(); }
        /**
         * 指定されたインデックス値が示すプレイリスト上のMIDIシーケンスをシーケンサへロードして再生します。
         * @param index インデックス値(0から始まる)
@@ -266,7 +264,7 @@ public class ChordHelperApplet extends JApplet {
         */
        public static class VersionInfo {
                public static final String NAME = "MIDI Chord Helper";
-               public static final String VERSION = "Ver.20170423.1";
+               public static final String VERSION = "Ver.20170427.1";
                public static final String COPYRIGHT = "Copyright (C) 2004-2017";
                public static final String AUTHER = "@きよし - Akiyoshi Kamide";
                public static final String URL = "http://www.yk.rim.or.jp/~kamide/music/chordhelper/";
index 0f75ec0..3dbf94b 100644 (file)
@@ -23,7 +23,6 @@ import javax.swing.JOptionPane;
 import javax.swing.JScrollPane;
 import javax.swing.JTable;
 import javax.swing.JToggleButton;
-import javax.swing.event.ListSelectionListener;
 import javax.swing.table.TableCellEditor;
 import javax.swing.table.TableModel;
 
@@ -46,7 +45,7 @@ public class MidiEventTable extends JTable {
         * @param outputMidiDevice 操作音出力先MIDIデバイス
         */
        public MidiEventTable(MidiEventTableModel model, MidiEventDialog eventDialog, VirtualMidiDevice outputMidiDevice) {
-               super(model, null, model.getSelectionModel());
+               super(model);
                this.outputMidiDevice = outputMidiDevice;
                this.eventDialog = eventDialog;
                titleLabel = new TitleLabel();
@@ -61,7 +60,7 @@ public class MidiEventTable extends JTable {
                };
                eventCellEditor = new MidiEventCellEditor();
                setAutoCreateColumnsFromModel(false);
-               selectionModel.addListSelectionListener(selectionListener = event->{
+               selectionModel.addListSelectionListener(event->{
                        if( event.getValueIsAdjusting() ) return;
                        if( selectionModel.isSelectionEmpty() ) {
                                queryPasteEventAction.setEnabled(false);
@@ -113,10 +112,6 @@ public class MidiEventTable extends JTable {
         */
        private VirtualMidiDevice outputMidiDevice;
        /**
-        * イベント選択リスナー
-        */
-       private ListSelectionListener selectionListener;
-       /**
         * このテーブルビューが表示するデータを提供するトラック(イベントリスト)データモデルを返します。
         * @return トラック(イベントリスト)データモデル
         */
@@ -131,8 +126,7 @@ public class MidiEventTable extends JTable {
        public void setModel(MidiEventTableModel model) {
                if( dataModel == model ) return;
                if( model == null ) {
-                       PlaylistTableModel playlist = getModel().getParent().getParent();
-                       model = playlist.emptyEventListTableModel;
+                       model = getModel().getParent().getParent().emptyEventListTableModel;
                        queryJumpEventAction.setEnabled(false);
                        queryAddEventAction.setEnabled(false);
 
@@ -145,11 +139,7 @@ public class MidiEventTable extends JTable {
                        queryJumpEventAction.setEnabled(true);
                        queryAddEventAction.setEnabled(true);
                }
-               selectionModel.removeListSelectionListener(selectionListener);
                super.setModel(model);
-               setSelectionModel(model.getSelectionModel());
-               titleLabel.updateTrackNumber(model.getParent().getSelectionModel().getMinSelectionIndex());
-               selectionModel.addListSelectionListener(selectionListener);
        }
        /**
         * タイトルラベル
@@ -162,7 +152,7 @@ public class MidiEventTable extends JTable {
        class TitleLabel extends JLabel {
                private static final String TITLE = "MIDI Events";
                private TitleLabel() { super(TITLE); }
-               void updateTrackNumber(int index) {
+               void showTrackNumber(int index) {
                        String text = TITLE;
                        if( index >= 0 ) text = String.format(TITLE+" - track #%d", index);
                        setText(text);
index dc57c63..b953219 100644 (file)
@@ -9,7 +9,6 @@ import javax.sound.midi.MidiMessage;
 import javax.sound.midi.Sequencer;
 import javax.sound.midi.ShortMessage;
 import javax.sound.midi.Track;
-import javax.swing.DefaultListSelectionModel;
 import javax.swing.ListSelectionModel;
 import javax.swing.table.AbstractTableModel;
 
@@ -113,15 +112,6 @@ public class MidiEventTableModel extends AbstractTableModel {
                return sequenceTrackListTableModel;
        }
        /**
-        * 選択状態を返します。
-        */
-       public ListSelectionModel getSelectionModel() { return selectionModel; }
-       private ListSelectionModel selectionModel = new DefaultListSelectionModel() {
-               {
-                       setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-               }
-       };
-       /**
         * シーケンスを親にして、その特定のトラックに連動する
         * MIDIトラックモデルを構築します。
         *
index e9e697f..234045c 100644 (file)
@@ -112,6 +112,13 @@ public class MidiSequenceEditorDialog extends JDialog {
                        JOptionPane.showMessageDialog(this, e, ChordHelperApplet.VersionInfo.NAME, JOptionPane.ERROR_MESSAGE);
                }
        }
+       /**
+        * 現在選択されているMIDIシーケンスから再生します。
+        * すでに再生されていた場合、このエディタダイアログを表示します。
+        */
+       public void play() {
+               play(playlistTable.getSelectionModel().getMinSelectionIndex());
+       }
 
        static final Icon deleteIcon = new ButtonIcon(ButtonIcon.X_ICON);
        /**
index f089410..8eef34e 100644 (file)
@@ -103,7 +103,8 @@ public class NewSequenceDialog extends JDialog {
                @Override
                public void actionPerformed(ActionEvent event) {
                        try {
-                               playlist.getSequenceModelList().get(playlist.play(getMidiSequence())).setModified(true);
+                               int index = playlist.play(getMidiSequence());
+                               playlist.getSequenceModelList().get(index).setModified(true);
                        } catch (Exception ex) {
                                JOptionPane.showMessageDialog(
                                        NewSequenceDialog.this, ex,
index 9866963..276e58c 100644 (file)
@@ -21,6 +21,7 @@ import javax.swing.AbstractAction;
 import javax.swing.AbstractCellEditor;
 import javax.swing.Action;
 import javax.swing.DefaultCellEditor;
+import javax.swing.Icon;
 import javax.swing.JButton;
 import javax.swing.JComboBox;
 import javax.swing.JComponent;
@@ -29,6 +30,9 @@ import javax.swing.JOptionPane;
 import javax.swing.JRootPane;
 import javax.swing.JTable;
 import javax.swing.JToggleButton;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
 import javax.swing.event.TableModelEvent;
 import javax.swing.filechooser.FileNameExtensionFilter;
 import javax.swing.table.JTableHeader;
@@ -53,13 +57,49 @@ public class PlaylistTable extends JTable {
        /** MIDIデバイスダイアログを開くアクション */
        private Action midiDeviceDialogOpenAction;
        /**
+        * 選択されたMIDIシーケンスのテーブルモデルを返します。
+        * @return 選択されたMIDIシーケンスのテーブルモデル(非選択時はnull)
+        */
+       private SequenceTrackListTableModel getSelectedSequenceModel() {
+               if( selectionModel.isSelectionEmpty() ) return null;
+               int selectedIndex = selectionModel.getMinSelectionIndex();
+               List<SequenceTrackListTableModel> list = getModel().getSequenceModelList();
+               return selectedIndex >= list.size() ? null : list.get(selectedIndex);
+       }
+       /**
+        * 行が選択されているときだけイネーブルになるアクション
+        */
+       private abstract class SelectedSequenceAction extends AbstractAction implements ListSelectionListener {
+               public SelectedSequenceAction(String name, Icon icon, String tooltip) {
+                       super(name,icon); init(tooltip);
+               }
+               public SelectedSequenceAction(String name, String tooltip) {
+                       super(name); init(tooltip);
+               }
+               @Override
+               public void valueChanged(ListSelectionEvent e) {
+                       if( e.getValueIsAdjusting() ) return;
+                       setEnebledBySelection();
+               }
+               protected void setEnebledBySelection() {
+                       int index = selectionModel.getMinSelectionIndex();
+                       setEnabled(index >= 0);
+               }
+               private void init(String tooltip) {
+                       putValue(Action.SHORT_DESCRIPTION, tooltip);
+                       selectionModel.addListSelectionListener(this);
+                       setEnebledBySelection();
+               }
+       }
+       /**
         * プレイリストビューを構築します。
         * @param model プレイリストデータモデル
         * @param midiDeviceDialogOpenAction MIDIデバイスダイアログを開くアクション
         * @param trackListTable トラックリストテーブル(子テーブル)
         */
        public PlaylistTable(PlaylistTableModel model, Action midiDeviceDialogOpenAction, SequenceTrackListTable trackListTable) {
-               super(model, null, model.getSelectionModel());
+               super(model);
+               setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
                this.midiDeviceDialogOpenAction = midiDeviceDialogOpenAction;
                try {
                        midiFileChooser = new MidiFileChooser();
@@ -89,7 +129,7 @@ public class PlaylistTable extends JTable {
                        }
                        @Override
                        public void actionPerformed(ActionEvent e) {
-                               SequenceTrackListTableModel sequenceModel = getModel().getSelectedSequenceModel();
+                               SequenceTrackListTableModel sequenceModel = getSelectedSequenceModel();
                                byte[] data = null;
                                String filename = null;
                                if( sequenceModel != null ) {
@@ -114,7 +154,8 @@ public class PlaylistTable extends JTable {
                });
                selectionModel.addListSelectionListener(event->{
                        if( event.getValueIsAdjusting() ) return;
-                       trackListTable.setModel(getModel().getSelectedSequenceModel());
+                       trackListTable.setModel(getSelectedSequenceModel());
+                       trackListTable.titleLabel.showMidiFileNumber(selectionModel);
                });
        }
        private TableColumn lengthColumn;
@@ -280,13 +321,12 @@ public class PlaylistTable extends JTable {
         * @return 追加されたMIDIファイルのインデックス値(先頭が0、追加されなかった場合は-1)
         */
        public int add(List<File> fileList) {
-               PlaylistTableModel model = getModel();
                int firstIndex = -1;
                Iterator<File> itr = fileList.iterator();
                while(itr.hasNext()) {
                        File file = itr.next();
                        try (FileInputStream in = new FileInputStream(file)) {
-                               int lastIndex = model.add(MidiSystem.getSequence(in), file.getName());
+                               int lastIndex = ((PlaylistTableModel)dataModel).add(MidiSystem.getSequence(in), file.getName());
                                if( firstIndex < 0 ) firstIndex = lastIndex;
                        } catch(IOException|InvalidMidiDataException e) {
                                String message = "Could not open as MIDI file "+file+"\n"+e;
@@ -316,7 +356,7 @@ public class PlaylistTable extends JTable {
        /**
         * シーケンスを削除するアクション
         */
-       Action deleteSequenceAction = getModel().new SelectedSequenceAction(
+       Action deleteSequenceAction = new SelectedSequenceAction(
                "Delete", MidiSequenceEditorDialog.deleteIcon,
                "Delete selected MIDI sequence - 選択した曲をプレイリストから削除"
        ) {
@@ -327,8 +367,8 @@ public class PlaylistTable extends JTable {
                public void actionPerformed(ActionEvent event) {
                        PlaylistTableModel model = getModel();
                        if( midiFileChooser != null ) {
-                               SequenceTrackListTableModel seqModel = model.getSelectedSequenceModel();
-                               if( seqModel != null && seqModel.isModified() && JOptionPane.showConfirmDialog(
+                               SequenceTrackListTableModel sequenceModel = getSelectedSequenceModel();
+                               if( sequenceModel != null && sequenceModel.isModified() && JOptionPane.showConfirmDialog(
                                                ((JComponent)event.getSource()).getRootPane(),
                                                CONFIRM_MESSAGE,
                                                ChordHelperApplet.VersionInfo.NAME,
@@ -336,8 +376,8 @@ public class PlaylistTable extends JTable {
                                                JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION
                                ) return;
                        }
-                       if( ! model.getSelectionModel().isSelectionEmpty() ) try {
-                               model.remove(model.getSelectionModel().getMinSelectionIndex());
+                       if( ! selectionModel.isSelectionEmpty() ) try {
+                               model.remove(selectionModel.getMinSelectionIndex());
                        } catch (Exception ex) {
                                JOptionPane.showMessageDialog(
                                                ((JComponent)event.getSource()).getRootPane(), ex,
@@ -354,13 +394,13 @@ public class PlaylistTable extends JTable {
                /**
                 * ファイル保存アクション
                 */
-               public Action saveMidiFileAction = getModel().new SelectedSequenceAction(
+               public Action saveMidiFileAction = new SelectedSequenceAction(
                        "Save",
                        "Save selected MIDI sequence to file - 選択したMIDIシーケンスをファイルに保存"
                ) {
                        @Override
                        public void actionPerformed(ActionEvent event) {
-                               SequenceTrackListTableModel sequenceModel = getModel().getSelectedSequenceModel();
+                               SequenceTrackListTableModel sequenceModel = getSelectedSequenceModel();
                                if( sequenceModel == null ) return;
                                String fn = sequenceModel.getFilename();
                                if( fn != null && ! fn.isEmpty() ) setSelectedFile(new File(fn));
index 1aca48c..f265683 100644 (file)
@@ -13,14 +13,9 @@ 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.ListSelectionModel;
 import javax.swing.SwingUtilities;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
 import javax.swing.event.TableModelEvent;
 import javax.swing.table.AbstractTableModel;
 
@@ -46,15 +41,6 @@ public class PlaylistTableModel extends AbstractTableModel {
         */
        public final MidiEventTableModel emptyEventListTableModel = new MidiEventTableModel(emptyTrackListTableModel, null);
        /**
-        * このプレイリストの選択モデルを返します。
-        */
-       public ListSelectionModel getSelectionModel() { return selectionModel; }
-       private ListSelectionModel selectionModel = new DefaultListSelectionModel() {
-               {
-                       setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-               }
-       };
-       /**
         * テーブルモデルの変更を示すイベントが、ファイル名の変更によるものかどうかをチェックします。
         * @param event テーブルモデルの変更を示すイベント
         * @return ファイル名の変更による場合true
@@ -138,31 +124,6 @@ public class PlaylistTableModel extends AbstractTableModel {
                return sequenceModelList;
        }
        /**
-        * 行が選択されているときだけイネーブルになるアクション
-        */
-       public abstract class SelectedSequenceAction extends AbstractAction implements ListSelectionListener {
-               public SelectedSequenceAction(String name, Icon icon, String tooltip) {
-                       super(name,icon); init(tooltip);
-               }
-               public SelectedSequenceAction(String name, String tooltip) {
-                       super(name); init(tooltip);
-               }
-               @Override
-               public void valueChanged(ListSelectionEvent e) {
-                       if( e.getValueIsAdjusting() ) return;
-                       setEnebledBySelection();
-               }
-               protected void setEnebledBySelection() {
-                       int index = selectionModel.getMinSelectionIndex();
-                       setEnabled(index >= 0);
-               }
-               private void init(String tooltip) {
-                       putValue(Action.SHORT_DESCRIPTION, tooltip);
-                       selectionModel.addListSelectionListener(this);
-                       setEnebledBySelection();
-               }
-       }
-       /**
         * 繰り返し再生ON/OFF切り替えアクション
         */
        public Action getToggleRepeatAction() { return toggleRepeatAction; }
@@ -381,16 +342,6 @@ public class PlaylistTableModel extends AbstractTableModel {
                return (int)(sequenceModelList.stream().mapToLong(m -> m.getMicrosecondLength() / 1000L).sum() / 1000L);
        }
        /**
-        * 選択されたMIDIシーケンスのテーブルモデルを返します。
-        * @return 選択されたMIDIシーケンスのテーブルモデル(非選択時はnull)
-        */
-       public SequenceTrackListTableModel getSelectedSequenceModel() {
-               if( selectionModel.isSelectionEmpty() ) return null;
-               int selectedIndex = selectionModel.getMinSelectionIndex();
-               if( selectedIndex >= sequenceModelList.size() ) return null;
-               return sequenceModelList.get(selectedIndex);
-       }
-       /**
         * MIDIシーケンスを追加します。
         * @param sequence MIDIシーケンス(nullの場合、シーケンスを自動生成して追加)
         * @param filename ファイル名(nullの場合、ファイル名なし)
@@ -401,7 +352,6 @@ public class PlaylistTableModel extends AbstractTableModel {
                sequenceModelList.add(new SequenceTrackListTableModel(this, sequence, filename));
                int lastIndex = sequenceModelList.size() - 1;
                fireTableRowsInserted(lastIndex, lastIndex);
-               selectionModel.setSelectionInterval(lastIndex, lastIndex);
                return lastIndex;
        }
        /**
index 4409e9e..65bf5d7 100644 (file)
@@ -12,7 +12,6 @@ import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JTable;
 import javax.swing.ListSelectionModel;
-import javax.swing.event.ListSelectionListener;
 import javax.swing.event.TableModelEvent;
 import javax.swing.table.TableCellEditor;
 
@@ -65,7 +64,7 @@ public class SequenceTrackListTable extends JTable {
         * @param eventListTable イベントリストテーブル
         */
        public SequenceTrackListTable(SequenceTrackListTableModel model, MidiEventTable eventListTable) {
-               super(model, null, model.getSelectionModel());
+               super(model);
                getColumnModel()
                        .getColumn(SequenceTrackListTableModel.Column.RECORD_CHANNEL.ordinal())
                        .setCellEditor(new DefaultCellEditor(new JComboBox<String>(){{
@@ -77,17 +76,14 @@ public class SequenceTrackListTable extends JTable {
                Arrays.stream(SequenceTrackListTableModel.Column.values()).forEach(c->
                        getColumnModel().getColumn(c.ordinal()).setPreferredWidth(c.preferredWidth)
                );
-               selectionModel.addListSelectionListener(selectionListener = event->{
+               selectionModel.addListSelectionListener(event->{
                        if( event.getValueIsAdjusting() ) return;
                        deleteTrackAction.setEnabled(! selectionModel.isSelectionEmpty());
-                       eventListTable.setModel(getModel().getSelectedTrackModel());
+                       eventListTable.setModel(getModel().getSelectedTrackModel(selectionModel));
+                       eventListTable.titleLabel.showTrackNumber(selectionModel.getMinSelectionIndex());
                });
        }
        /**
-        * トラック選択リスナー
-        */
-       private ListSelectionListener selectionListener;
-       /**
         * このテーブルビューが表示するデータを提供するシーケンス(トラックリスト)データモデルを返します。
         * @return シーケンス(トラックリスト)データモデル
         */
@@ -109,12 +105,7 @@ public class SequenceTrackListTable extends JTable {
                else {
                        addTrackAction.setEnabled(true);
                }
-               selectionModel.clearSelection();
-               selectionModel.removeListSelectionListener(selectionListener);
                super.setModel(model);
-               setSelectionModel(model.getSelectionModel());
-               titleLabel.setSelection(model.getParent().getSelectionModel());
-               selectionModel.addListSelectionListener(selectionListener);
        }
        /**
         * 曲番号表示付きタイトルラベル
@@ -123,10 +114,10 @@ public class SequenceTrackListTable extends JTable {
        /**
         * 曲番号表示付きタイトルラベル
         */
-       private class TitleLabel extends JLabel {
+       class TitleLabel extends JLabel {
                private static final String TITLE = "Tracks";
                public TitleLabel() { setText(TITLE); }
-               public void setSelection(ListSelectionModel sequenceSelectionModel) {
+               public void showMidiFileNumber(ListSelectionModel sequenceSelectionModel) {
                        String text = TITLE;
                        if( ! sequenceSelectionModel.isSelectionEmpty() ) {
                                int index = sequenceSelectionModel.getMinSelectionIndex();
index b712467..8a9fe9b 100644 (file)
@@ -9,7 +9,6 @@ import java.util.List;
 import javax.sound.midi.MidiSystem;
 import javax.sound.midi.Sequence;
 import javax.sound.midi.Track;
-import javax.swing.DefaultListSelectionModel;
 import javax.swing.ListSelectionModel;
 import javax.swing.table.AbstractTableModel;
 
@@ -83,15 +82,6 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
         */
        private List<MidiEventTableModel> trackModelList = new ArrayList<>();
        /**
-        * このトラックリストの選択モデルを返します。
-        */
-       public ListSelectionModel getSelectionModel() { return selectionModel; }
-       private ListSelectionModel selectionModel = new DefaultListSelectionModel(){
-               {
-                       setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
-               }
-       };
-       /**
         * MIDIシーケンスとファイル名から {@link SequenceTrackListTableModel} を構築します。
         * @param sequenceListTableModel 親のプレイリスト
         * @param sequence MIDIシーケンス
@@ -337,7 +327,7 @@ public class SequenceTrackListTableModel extends AbstractTableModel {
         * @param index トラックのインデックス
         * @return トラックモデル(見つからない場合null)
         */
-       public MidiEventTableModel getSelectedTrackModel() {
+       public MidiEventTableModel getSelectedTrackModel(ListSelectionModel selectionModel) {
                if( selectionModel.isSelectionEmpty() ) return null;
                Track tracks[] = sequence.getTracks();
                if( tracks.length == 0 ) return null;