import javax.swing.*; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.io.IOException; import java.io.File; import java.util.*; import java.awt.*; import java.awt.event.*; import java.io.*; import javax.sound.midi.*; import javax.swing.tree.*; import javax.swing.table.*; import javax.swing.event.*; //TreeSelectionListener, -event /** * Created by IntelliJ IDEA. * User: kaur * Date: 15.09.2003 * Time: 1:50:27 * To change this template use Options | File Templates. */ public class KMidi extends JPanel implements ActionListener, TreeSelectionListener { Sequence sekvents; Sequencer sekventser; JButton btnPlay, btnStop, btnNew, btnCopy, btnCut, btnPaste, btnDelete; JScrollPane treeView; final JTree tree; final JTable table; File file; DefaultMutableTreeNode rootNode; DefaultTreeModel treeModel; public void play() { try { Object src = tree.getLastSelectedPathComponent(); if (!(src instanceof DefaultMutableTreeNode)) return; DefaultMutableTreeNode node = (DefaultMutableTreeNode) src; if (node.getUserObject() == null) return; if ( node.getUserObject() instanceof NodeObjectHolder) { sekvents = (Sequence) ((NodeObjectHolder)node.getUserObject()).userObject; } else if( node.getUserObject() instanceof Track) { Track algrada = (Track)node.getUserObject(); sekvents = (Sequence) ((NodeObjectHolder) ((DefaultMutableTreeNode)node.getParent()).getUserObject() ).userObject; sekvents = new Sequence(sekvents.getDivisionType(), sekvents.getResolution()); Track uusrada = sekvents.createTrack(); for (int nr = 0; nr < algrada.size(); nr++) uusrada.add(algrada.get(nr)); } else return; //root sekventser.setSequence(sekvents); sekventser.start(); } catch (InvalidMidiDataException e) {e.printStackTrace();}; } public void stop() { sekventser.stop(); } public KMidi() { super(new BorderLayout()); JToolBar toolbar = new JToolBar(); btnPlay = new JButton("Play"); //btnPlay.setEnabled(false); btnPlay.addActionListener(this); toolbar.add(btnPlay); btnStop = new JButton("Stop"); btnStop.addActionListener(this); toolbar.add(btnStop); btnNew = new JButton("Uus"); btnNew.addActionListener(this); toolbar.add(btnNew); btnCopy = new JButton("Kopeeri"); btnCopy.addActionListener(this); toolbar.add(btnCopy); btnCut = new JButton("Lõika"); btnCut.addActionListener(this); toolbar.add(btnCut); btnPaste = new JButton("Kleebi"); btnPaste.addActionListener(this); toolbar.add(btnPaste); btnDelete = new JButton("Kustuta"); btnDelete.addActionListener(this); toolbar.add(btnDelete); toolbar.setOrientation(JToolBar.HORIZONTAL); add(toolbar, BorderLayout.NORTH); rootNode = new DefaultMutableTreeNode("MidiSystem"); treeModel = new DefaultTreeModel(rootNode); //tree = new JTree(rootNode); tree = new JTree(treeModel); tree.addTreeSelectionListener(this); treeView = new JScrollPane(tree); treeView.setPreferredSize(new Dimension(300,200)); add(treeView, BorderLayout.WEST); table = new JTable(); JScrollPane scrollpane = new JScrollPane(table); add(scrollpane, BorderLayout.CENTER); try { sekventser = MidiSystem.getSequencer(); if (!sekventser.isOpen()) { System.out.print("avatakse sekventser..."); sekventser.open(); System.out.println(" ok"); } } catch (MidiUnavailableException e) {e.printStackTrace();}; } public void valueChanged(TreeSelectionEvent e) { Object src = e.getPath().getLastPathComponent(); if (!(src instanceof DefaultMutableTreeNode)) return; DefaultMutableTreeNode node = (DefaultMutableTreeNode) src; if (node.getUserObject() == null) return; if(!( node.getUserObject() instanceof Track)) return; final Track track = (Track) node.getUserObject(); final String[] columnNames = {"Tiks", "Kanal", "Teade", "kõrgus", "valjus", "Meta tüüp"}; TableModel dataModel = new AbstractTableModel() { public String getColumnName(int column) { return columnNames[column];} public int getColumnCount() { return columnNames.length; } public int getRowCount() { return track.size();} public Object getValueAt(int row, int col) { MidiEvent me = track.get(row); Long tick = new Long(me.getTick()); MidiMessage msg = me.getMessage(); if (msg instanceof ShortMessage){ ShortMessage sm = (ShortMessage)msg; switch (col) { case 0: return tick; case 1: return new Integer(sm.getChannel()); case 2: return new Integer(sm.getCommand()); case 3: return new Integer(sm.getData1()); case 4: return new Integer(sm.getData2()); default: return ""; } } else if (msg instanceof MetaMessage){ MetaMessage mm = (MetaMessage)msg; switch (col) { case 0: return tick; case 5: return new Integer(mm.getType()); default: return ""; } } else if (col == 0) return tick; else return ""; } public Class getColumnClass(int c) { //return getValueAt(0, c).getClass(); //return Class.forName("Integer"); return (new Long(0)).getClass(); } public void setValueAt(Object aValue, int row, int col) { System.out.println("set value "+row+","+ col); MidiEvent me = track.get(row); Long tick = new Long(me.getTick()); MidiMessage msg = me.getMessage(); if (col == 0) { me.setTick(((Long)aValue).longValue()); return; } int val = ((Long)aValue).intValue(); if (msg instanceof ShortMessage){ ShortMessage sm = (ShortMessage)msg; int command = sm.getCommand(); int channel = sm.getChannel(); int data1 = sm.getData1(); int data2 = sm.getData2(); int status = sm.getStatus(); System.out.println("enne muutmist: "+command+","+channel+","+data1+","+ data2); switch (col) { //case 0: me.setTick(val); case 1: channel = val; break; case 2: command = val; break; case 3: data1 = val; break; case 4: data2 = val; break; } System.out.println("muudetakse: "+command+","+channel+","+data1+","+ data2); try { //millegipärast paneb data2 väärtuseks kah data1 väärtuse... //sm.setMessage(command, channel, data1, data2); //sm.setMessage(command, channel, 9, 0); //workaround: ShortMessage sm2 = new ShortMessage(); sm2.setMessage(command, channel, data1, data2); MidiEvent me2 = new MidiEvent(sm2, me.getTick()); track.remove(me); track.add(me2); } catch (InvalidMidiDataException ex) { ex.printStackTrace(); } } } public boolean isCellEditable(int row, int col) { if (col == 5) return false; else return true; } }; table.setModel(dataModel); } Track tempTrack = null; public void copyTrack() { if (tree.getLastSelectedPathComponent() == null) return; DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if( node.getUserObject() instanceof Track) { tempTrack = (Track)node.getUserObject(); } else return; //root } private Sequence getCurrentSequence() { Sequence seq = null; if (tree.getLastSelectedPathComponent() == null) return null; DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if ( node.getUserObject() instanceof NodeObjectHolder) { seq = (Sequence) ((NodeObjectHolder)node.getUserObject()).userObject; } else if( node.getUserObject() instanceof Track) { Track algrada = (Track)node.getUserObject(); seq = (Sequence) ((NodeObjectHolder) ((DefaultMutableTreeNode)node.getParent()).getUserObject() ).userObject; } return seq; } private int jnr = 0; public void newSequence() { sekvents = getCurrentSequence(); if (sekvents == null) return; try{ sekvents = new Sequence(sekvents.getDivisionType(), sekvents.getResolution()); //addSeqenceToTree(sekvents, "uus-"+(new Integer(jnr++)).toString()+".mid"); addSeqenceToTree(sekvents, "uus-"+(jnr++)+".mid"); }catch (InvalidMidiDataException e) {e.printStackTrace();} } public void cutTrack() { copyTrack(); deleteTrack(); } public void pasteTrack() { if (tree.getLastSelectedPathComponent() == null) return; DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if ( node.getUserObject() instanceof Track) node = (DefaultMutableTreeNode)node.getParent(); if (!( node.getUserObject() instanceof NodeObjectHolder)) return; sekvents = (Sequence) ((NodeObjectHolder) node.getUserObject() ).userObject; Track uusrada = sekvents.createTrack(); for (int nr = 0; nr < tempTrack.size(); nr++) uusrada.add(tempTrack.get(nr)); //NB! ei tee uusi eksemplare DefaultMutableTreeNode trackNode = new DefaultMutableTreeNode(uusrada); node.add(trackNode); treeModel.insertNodeInto(trackNode, node, 0); } public void deleteTrack() { if (tree.getLastSelectedPathComponent() == null) return; DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if( node.getUserObject() instanceof Track) { Sequence sekvents = (Sequence) ((NodeObjectHolder) ((DefaultMutableTreeNode)node.getParent()).getUserObject() ).userObject; Track track = (Track)node.getUserObject(); sekvents.deleteTrack(track); treeModel.removeNodeFromParent(node); } else return; //root } public void addTrackToSequence(Sequence seq, Track track) { // } public void addSeqenceToTree(Sequence seq, String name) { DefaultMutableTreeNode sequenceNode = null; DefaultMutableTreeNode trackNode = null; NodeObjectHolder noh = new NodeObjectHolder("" + name + "", seq); sequenceNode = new DefaultMutableTreeNode(noh); Track[] rajad = seq.getTracks(); System.out.println(rajad.length+" rada"); for (int nr = 0; nr < rajad.length; nr++){ trackNode = new DefaultMutableTreeNode(rajad[nr]); sequenceNode.add(trackNode); } treeModel.insertNodeInto(sequenceNode, rootNode, rootNode.getChildCount()); } public void actionPerformed(ActionEvent e) { if (e.getSource() == btnPlay) { play(); } else if (e.getSource() == btnStop) { stop(); } else if (e.getSource() == btnCopy) { copyTrack(); } else if (e.getSource() == btnNew) { newSequence(); } else if (e.getSource() == btnCut) { cutTrack(); } else if (e.getSource() == btnPaste) { pasteTrack(); } else if (e.getSource() == btnDelete) { deleteTrack(); } else if (e.getSource() == mnLoad) { loadFile(); } else if (e.getSource() == mnSave) { saveFile(); } } JFileChooser fc = new JFileChooser(); public void loadFile() { int returnVal = fc.showOpenDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { file = fc.getSelectedFile(); try { System.out.println("Opening: " + file.getCanonicalPath()); sekvents = MidiSystem.getSequence(file); addSeqenceToTree(sekvents, file.getName()); } catch (Exception ex) { ex.printStackTrace(); } } else { System.out.println("Open command cancelled by user."); } } public void saveFile() { sekvents = getCurrentSequence(); //millist faili salvestada if (sekvents == null) return; int returnVal = fc.showSaveDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { file = fc.getSelectedFile(); try { MidiSystem.write(sekvents, 1, new FileOutputStream(file.getCanonicalPath())); System.out.println("Saved: " + file.getCanonicalPath()); } catch (IOException ex) { ex.printStackTrace(); } } else { System.out.println("Save command cancelled by user."); } } JMenuItem mnUus, mnLoad, mnSave; public JMenuBar createMenuBar() { JMenuBar menuBar = new JMenuBar(); JMenu menu = null; JMenuItem menuItem = null; menu = new JMenu("Failid"); menuItem = new JMenuItem("Lae.."); menuItem.addActionListener(this); menu.add(menuItem); mnLoad = menuItem; menuItem = new JMenuItem("Salvesta.."); menuItem.addActionListener(this); menu.add(menuItem); mnSave = menuItem; menuBar.add(menu); return menuBar; } public static void main(String[] args) { //Make sure we have nice window decorations. JFrame.setDefaultLookAndFeelDecorated(true); //Create and set up the window. JFrame frame = new JFrame("KMidi"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. //JComponent newContentPane = new KObjectDraw(); KMidi kodContentPane = new KMidi(); kodContentPane.setOpaque(true); frame.setJMenuBar(kodContentPane.createMenuBar()); frame.setContentPane(kodContentPane); //Display the window. frame.pack(); frame.setSize(600, 400); frame.setVisible(true); } } class NodeObjectHolder { public String label = "no name"; public Object userObject = null; public NodeObjectHolder() { } public NodeObjectHolder(String label, Object userObject) { this.label = label; this.userObject = userObject; } public String toString() { return label; } }