Java tutorial
/* * MIDITriggersPage.java * * copyright (c) 2008, tom dinchak * * This file is part of pages. * * pages is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * pages is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with pages; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.monome.pages; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.sound.midi.InvalidMidiDataException; import javax.sound.midi.MidiMessage; import javax.sound.midi.Receiver; import javax.sound.midi.ShortMessage; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JTextField; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import org.apache.commons.lang.StringEscapeUtils; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * This code was edited or generated using CloudGarden's Jigloo * SWT/Swing GUI Builder, which is free for non-commercial * use. If Jigloo is being used commercially (ie, by a corporation, * company or business for any purpose whatever) then you * should purchase a license for each developer using Jigloo. * Please visit www.cloudgarden.com for details. * Use of Jigloo implies acceptance of these licensing terms. * A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR * THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED * LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE. */ /** * The MIDI Triggers page. Usage information is available at: * * http://code.google.com/p/monome-pages/wiki/MIDITriggersPage * * @author Tom Dinchak * */ public class MIDITriggersPage implements Page, ActionListener { /** * Toggles mode constant */ private static final int MODE_TOGGLES = 0; /** * Triggers mode constant */ private static final int MODE_TRIGGERS = 1; /** * Rows orientation constant */ private static final int ORIENTATION_ROWS = 2; /** * Columns orientation constant */ private static final int ORIENTATION_COLUMNS = 3; /** * Checkboxes to enable toggle mode on or off for each row/col */ private JCheckBox[] toggles = new JCheckBox[16]; /** * The toggled state of each button (on or off) */ private int[][] toggleValues = new int[16][16]; /** * The MonomeConfiguration object this page belongs to */ MonomeConfiguration monome; /** * The index of this page (the page number) */ private int index; /** * The GUI for this page */ private JPanel panel; /** * the Add MIDI Output button */ private JButton addMidiOutButton; /** * Columns mode radio button */ private JRadioButton colRB; /** * Rows mode radio button */ private JRadioButton rowRB; /** * Rows/columns radio button group */ private ButtonGroup rowColBG; /** * The selected MIDI output device */ private Receiver recv; /** * The name of the selected MIDI output device */ private String midiDeviceName; // GUI elements private JLabel row13Label; private JLabel row14Label; private JLabel row15Label; private JLabel row16Label; private JLabel row7Label; private JLabel row11Label; private JLabel row10Label; private JLabel row9Label; private JLabel row8Label; private JLabel row6Label; private JLabel row12Label; private JLabel row5Label; private JLabel row4Label; private JLabel jLabel1; private JLabel row3Label; private JLabel row2Label; private JLabel row1Label; // tilt stuff private ADCOptions pageADCOptions = new ADCOptions(); /** * The name of the page */ private String pageName = "MIDI Triggers"; private JLabel pageNameLBL; /** * @param monome The MonomeConfiguration this page belongs to * @param index The index of this page (the page number) */ public MIDITriggersPage(MonomeConfiguration monome, int index) { this.monome = monome; this.index = index; for (int i = 0; i < 16; i++) { toggles[i] = new JCheckBox(); toggles[i].setText("Toggles"); } } /* (non-Javadoc) * @see org.monome.pages.Page#actionPerformed(java.awt.event.ActionEvent) */ public void actionPerformed(ActionEvent e) { System.out.println(e.getActionCommand()); if (e.getActionCommand().equals("Set MIDI Output")) { String[] midiOutOptions = this.monome.getMidiOutOptions(); String deviceName = (String) JOptionPane.showInputDialog(this.monome, "Choose a MIDI Output to add", "Add MIDI Output", JOptionPane.PLAIN_MESSAGE, null, midiOutOptions, ""); if (deviceName == null) { return; } this.addMidiOutDevice(deviceName); } else if (e.getActionCommand().equals("Columns")) { row1Label.setText("Col 1"); row2Label.setText("Col 2"); row3Label.setText("Col 3"); row4Label.setText("Col 4"); row5Label.setText("Col 5"); row6Label.setText("Col 6"); row7Label.setText("Col 7"); row8Label.setText("Col 8"); row9Label.setText("Col 9"); row10Label.setText("Col 10"); row11Label.setText("Col 11"); row12Label.setText("Col 12"); row13Label.setText("Col 13"); row14Label.setText("Col 14"); row15Label.setText("Col 15"); row16Label.setText("Col 16"); this.redrawMonome(); } else if (e.getActionCommand().equals("Rows")) { row1Label.setText("Row 1"); row2Label.setText("Row 2"); row3Label.setText("Row 3"); row4Label.setText("Row 4"); row5Label.setText("Row 5"); row6Label.setText("Row 6"); row7Label.setText("Row 7"); row8Label.setText("Row 8"); row9Label.setText("Row 9"); row10Label.setText("Row 10"); row11Label.setText("Row 11"); row12Label.setText("Row 12"); row13Label.setText("Row 13"); row14Label.setText("Row 14"); row15Label.setText("Row 15"); row16Label.setText("Row 16"); this.redrawMonome(); } } /* (non-Javadoc) * @see org.monome.pages.Page#addMidiOutDevice(java.lang.String) */ public void addMidiOutDevice(String deviceName) { this.recv = this.monome.getMidiReceiver(deviceName); this.midiDeviceName = deviceName; this.addMidiOutButton.removeActionListener(this); this.panel.removeAll(); this.panel = null; this.monome.redrawPanel(); } /* (non-Javadoc) * @see org.monome.pages.Page#getName() */ public String getName() { return pageName; } /* (non-Javadoc) * @see org.monome.pages.Page#setName() */ public void setName(String name) { this.pageName = name; this.pageNameLBL.setText("Page " + (this.index + 1) + ": " + pageName); this.monome.setJMenuBar(this.monome.createMenuBar()); } /** * Find out of toggle mode is enabled for a row/column. * * @param index The index of the row/column * @return The mode of the checkbox (toggles or triggers) */ private int getToggleMode(int index) { if (this.toggles[index].isSelected()) { return MODE_TOGGLES; } else { return MODE_TRIGGERS; } } /** * Get the current orientation setting. * * @return The current orientation (rows or columns) */ private int getOrientation() { // default to rows if (this.rowRB == null) { return ORIENTATION_ROWS; } if (this.rowRB.isSelected()) { return ORIENTATION_ROWS; } else { return ORIENTATION_COLUMNS; } } /* (non-Javadoc) * @see org.monome.pages.Page#handlePress(int, int, int) */ public void handlePress(int x, int y, int value) { int a = x; int b = y; if (this.getOrientation() == ORIENTATION_COLUMNS) { a = y; b = x; } if (this.getToggleMode(b) == MODE_TOGGLES) { if (value == 1) { if (this.toggleValues[a][b] == 1) { this.toggleValues[a][b] = 0; this.monome.led(x, y, 0, this.index); // note on } else { this.toggleValues[a][b] = 1; this.monome.led(x, y, 1, this.index); // note off } this.playNote(a, b, 1); this.playNote(a, b, 0); } } else { this.monome.led(x, y, value, this.index); this.playNote(a, b, value); // note on // note off } } /** * Converts a button press into a MIDI note event * * @param x The x value of the button pressed * @param y The y value of the button pressed * @param value The state, 1 = pressed, 0 = released */ public void playNote(int x, int y, int value) { int note_num = x + 12; int channel = y; int velocity = value * 127; ShortMessage note_out = new ShortMessage(); try { if (velocity == 0) { note_out.setMessage(ShortMessage.NOTE_OFF, channel, note_num, velocity); } else { note_out.setMessage(ShortMessage.NOTE_ON, channel, note_num, velocity); } } catch (InvalidMidiDataException e) { e.printStackTrace(); } if (this.recv != null) { this.recv.send(note_out, -1); } } /* (non-Javadoc) * @see org.monome.pages.Page#handleReset() */ public void handleReset() { return; } /* (non-Javadoc) * @see org.monome.pages.Page#handleTick() */ public void handleTick() { return; } /* (non-Javadoc) * @see org.monome.pages.Page#redrawMonome() */ public void redrawMonome() { for (int x = 0; x < this.monome.sizeX; x++) { for (int y = 0; y < this.monome.sizeY; y++) { int a = x; int b = y; if (this.getOrientation() == ORIENTATION_COLUMNS) { a = y; b = x; } if (this.getToggleMode(b) == MODE_TOGGLES) { if (this.toggleValues[a][b] == 1) { this.monome.led(x, y, 1, this.index); } else { this.monome.led(x, y, 0, this.index); } } else { this.monome.led(x, y, 0, this.index); } } } } /* (non-Javadoc) * @see org.monome.pages.Page#send(javax.sound.midi.MidiMessage, long) */ public void send(MidiMessage message, long timeStamp) { ShortMessage msg = (ShortMessage) message; int x = msg.getData1() - 12; int y = msg.getChannel(); if (x >= 0 && x < this.monome.sizeX && y >= 0 && y < this.monome.sizeY) { int velocity = msg.getData2(); if (velocity == 127) { this.toggleValues[x][y] = 1; } else { this.toggleValues[x][y] = 0; } this.redrawMonome(); } return; } /* (non-Javadoc) * @see org.monome.pages.Page#toXml() */ public String toXml() { String mode; if (this.rowRB.isSelected()) { mode = "rows"; } else { mode = "columns"; } String xml = ""; xml += " <name>MIDI Triggers</name>\n"; xml += " <pageName>" + this.pageName + "</pageName>\n"; xml += " <selectedmidioutport>" + StringEscapeUtils.escapeXml(this.midiDeviceName) + "</selectedmidioutport>\n"; xml += " <mode>" + mode + "</mode>\n"; xml += " <ccoffset>" + this.pageADCOptions.getCcOffset() + "</ccoffset>\n"; xml += " <sendADC>" + this.pageADCOptions.isSendADC() + "</sendADC>\n"; xml += " <midiChannelADC>" + this.pageADCOptions.getMidiChannel() + "</midiChannelADC>\n"; xml += " <adcTranspose>" + this.pageADCOptions.getAdcTranspose() + "</adcTranspose>\n"; xml += " <recv>" + this.pageADCOptions.getRecv() + "</recv>\n"; for (int i = 0; i < 16; i++) { String state; if (this.toggles[i].isSelected()) { state = "on"; } else { state = "off"; } xml += " <toggles>" + state + "</toggles>\n"; } return xml; } /** * @return The rows/columns radio button group */ private ButtonGroup getRowColBG() { if (rowColBG == null) { rowColBG = new ButtonGroup(); } return rowColBG; } /* (non-Javadoc) * @see org.monome.pages.Page#getPanel() */ public JPanel getPanel() { if (this.panel != null) { return this.panel; } JPanel panel = new JPanel(); panel.setLayout(null); panel.setPreferredSize(new java.awt.Dimension(531, 180)); pageNameLBL = new JLabel("Page " + (this.index + 1) + ": MIDI Triggers"); row16Label = new JLabel(); row16Label.setText("Row 16"); row15Label = new JLabel(); row15Label.setText("Row 15"); row14Label = new JLabel(); row14Label.setText("Row 14"); row13Label = new JLabel(); row13Label.setText("Row 13"); rowRB = new JRadioButton(); rowRB.setText("Rows"); colRB = new JRadioButton(); colRB.setText("Columns"); this.getRowColBG().add(rowRB); this.getRowColBG().add(colRB); addMidiOutButton = new JButton(); addMidiOutButton.addActionListener(this); panel.add(addMidiOutButton); panel.add(colRB); panel.add(rowRB); rowRB.setBounds(19, 104, 86, 18); colRB.setBounds(19, 123, 86, 18); addMidiOutButton.setText("Set MIDI Output"); addMidiOutButton.setBounds(285, 120, 164, 21); row5Label = new JLabel(); row5Label.setText("Row 5"); row6Label = new JLabel(); row6Label.setText("Row 6"); row7Label = new JLabel(); row7Label.setText("Row 7"); row8Label = new JLabel(); row8Label.setText("Row 8"); row9Label = new JLabel(); row9Label.setText("Row 9"); row10Label = new JLabel(); row10Label.setText("Row 10"); row11Label = new JLabel(); row11Label.setText("Row 11"); row12Label = new JLabel(); row12Label.setText("Row 12"); panel.add(toggles[3]); toggles[3].setBounds(58, 78, 74, 18); row3Label = new JLabel(); row3Label.setText("Row 3"); row4Label = new JLabel(); panel.add(row4Label); panel.add(toggles[7]); panel.add(row8Label); panel.add(toggles[11]); panel.add(row12Label); panel.add(toggles[15]); panel.add(row16Label); panel.add(toggles[2]); panel.add(row3Label); panel.add(toggles[6]); panel.add(row7Label); panel.add(toggles[10]); panel.add(row11Label); panel.add(toggles[14]); panel.add(row15Label); row15Label.setBounds(405, 60, 46, 14); toggles[14].setBounds(451, 58, 74, 18); row11Label.setBounds(274, 60, 46, 14); toggles[10].setBounds(320, 58, 74, 18); row7Label.setBounds(143, 60, 46, 14); toggles[6].setBounds(189, 58, 74, 18); row3Label.setBounds(12, 60, 46, 14); toggles[2].setBounds(58, 58, 74, 18); row16Label.setBounds(405, 80, 46, 14); toggles[15].setBounds(451, 78, 74, 18); row12Label.setBounds(274, 80, 46, 14); toggles[11].setBounds(320, 78, 74, 18); row8Label.setBounds(143, 80, 46, 14); toggles[7].setBounds(189, 78, 74, 18); row4Label.setText("Row 4"); row4Label.setBounds(12, 80, 46, 14); row2Label = new JLabel(); row2Label.setText("Row 2"); panel.add(toggles[1]); panel.add(row2Label); panel.add(toggles[5]); panel.add(row6Label); panel.add(toggles[9]); panel.add(row10Label); panel.add(toggles[13]); panel.add(row14Label); row14Label.setBounds(405, 40, 46, 14); toggles[13].setBounds(451, 38, 74, 18); row10Label.setBounds(274, 40, 46, 14); toggles[9].setBounds(320, 38, 74, 18); row6Label.setBounds(143, 40, 46, 14); toggles[5].setBounds(189, 38, 74, 18); row2Label.setBounds(12, 40, 46, 14); toggles[1].setBounds(58, 38, 74, 18); row1Label = new JLabel(); row1Label.setText("Row 1"); panel.add(toggles[0]); panel.add(row1Label); panel.add(toggles[4]); panel.add(row5Label); panel.add(toggles[8]); panel.add(row9Label); panel.add(toggles[12]); panel.add(row13Label); panel.add(pageNameLBL); panel.add(getJLabel1()); pageNameLBL.setBounds(0, 0, 189, 14); row13Label.setBounds(405, 20, 46, 14); toggles[12].setBounds(451, 18, 74, 18); row9Label.setBounds(274, 20, 46, 14); toggles[8].setBounds(320, 18, 74, 18); row5Label.setBounds(143, 20, 46, 14); toggles[4].setBounds(189, 18, 74, 18); row1Label.setBounds(12, 20, 63, 14); toggles[0].setBounds(58, 18, 74, 18); rowRB.setSelected(true); rowRB.addActionListener(this); colRB.addActionListener(this); this.panel = panel; return panel; } /** * Sets the mode / orientation of the page to rows or columns mode * * @param mode "rows" for row mode, "columns" for column mode */ public void setMode(String mode) { if (mode.equals("rows")) { this.rowRB.doClick(); } else if (mode.equals("columns")) { this.colRB.doClick(); } } /** * Used when loading configuration to enable checkboxes for rows/columns that should be toggles. * * @param l */ public void enableToggle(int l) { this.toggles[l].doClick(); } /* (non-Javadoc) * @see org.monome.pages.Page#getCacheDisabled() */ public boolean getCacheDisabled() { return false; } /* (non-Javadoc) * @see org.monome.pages.Page#destroyPage() */ public void destroyPage() { return; } private JLabel getJLabel1() { jLabel1 = new JLabel(); jLabel1.setText("MIDI Out: " + this.midiDeviceName); jLabel1.setBounds(254, 0, 227, 14); return jLabel1; } public void clearPanel() { this.panel = null; } public void setIndex(int index) { this.index = index; } public void handleADC(int adcNum, float value) { if (this.pageADCOptions.isSendADC() && this.monome.adcObj.isEnabled()) { int midi = this.pageADCOptions.getMidiChannel(); if (midi == -1) { this.monome.adcObj.sendCC(this.recv, 0, this.pageADCOptions.getCcADC(), monome, adcNum, value); } else { this.monome.adcObj.sendCC(this.recv, midi, this.pageADCOptions.getCcADC(), monome, adcNum, value); } } } public void handleADC(float x, float y) { if (this.pageADCOptions.isSendADC() && this.monome.adcObj.isEnabled()) { int midi = this.pageADCOptions.getMidiChannel(); if (midi == -1) { this.monome.adcObj.sendCC(this.recv, 0, this.pageADCOptions.getCcADC(), monome, x, y); } else { this.monome.adcObj.sendCC(this.recv, midi, this.pageADCOptions.getCcADC(), monome, x, y); } } } public boolean isTiltPage() { return true; } public ADCOptions getAdcOptions() { return this.pageADCOptions; } public void setAdcOptions(ADCOptions options) { this.pageADCOptions = options; } public void configure(Element pageElement) { NodeList nameNL = pageElement.getElementsByTagName("pageName"); Element el = (Element) nameNL.item(0); if (el != null) { NodeList nl = el.getChildNodes(); String name = ((Node) nl.item(0)).getNodeValue(); this.setName(name); } NodeList nl = pageElement.getElementsByTagName("mode"); el = (Element) nl.item(0); if (el != null) { nl = el.getChildNodes(); String mode = ((Node) nl.item(0)).getNodeValue(); this.setMode(mode); } NodeList seqNL = pageElement.getElementsByTagName("toggles"); for (int l = 0; l < seqNL.getLength(); l++) { el = (Element) seqNL.item(l); if (el != null) { nl = el.getChildNodes(); String mode = ((Node) nl.item(0)).getNodeValue(); if (mode.equals("on")) { this.enableToggle(l); } } } nl = pageElement.getElementsByTagName("ccoffset"); el = (Element) nl.item(0); if (el != null) { nl = el.getChildNodes(); String ccOffset = ((Node) nl.item(0)).getNodeValue(); this.pageADCOptions.setCcOffset(Integer.parseInt(ccOffset)); } nl = pageElement.getElementsByTagName("sendADC"); el = (Element) nl.item(0); if (el != null) { nl = el.getChildNodes(); String sendADC = ((Node) nl.item(0)).getNodeValue(); this.pageADCOptions.setSendADC(Boolean.parseBoolean(sendADC)); } nl = pageElement.getElementsByTagName("adcTranspose"); el = (Element) nl.item(0); if (el != null) { nl = el.getChildNodes(); String adcTranspose = ((Node) nl.item(0)).getNodeValue(); this.pageADCOptions.setAdcTranspose(Integer.parseInt(adcTranspose)); } nl = pageElement.getElementsByTagName("midiChannelADC"); el = (Element) nl.item(0); if (el != null) { nl = el.getChildNodes(); String midiChannelADC = ((Node) nl.item(0)).getNodeValue(); this.pageADCOptions.setMidiChannel(Integer.parseInt(midiChannelADC)); } nl = pageElement.getElementsByTagName("recv"); el = (Element) nl.item(0); if (el != null) { nl = el.getChildNodes(); String recv = ((Node) nl.item(0)).getNodeValue(); this.pageADCOptions.setRecv(recv); if (recv != null) this.addMidiOutDevice(recv); } this.redrawMonome(); } }