/* * JSampler - a java front-end for LinuxSampler * * Copyright (C) 2005-2006 Grigor Iliev * * This file is part of JSampler. * * JSampler is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * JSampler 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 JSampler; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package org.jsampler.view; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.logging.Level; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JComponent; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.TransferHandler; import javax.swing.table.TableCellRenderer; import org.jsampler.CC; import org.jsampler.DefaultOrchestraModel; import org.jsampler.HF; import org.jsampler.Instrument; import org.jsampler.event.OrchestraAdapter; import org.jsampler.event.OrchestraEvent; import static javax.swing.KeyStroke.*; /** * A table for representing instruments. * @author Grigor Iliev */ public class InstrumentTable extends JTable { private boolean performingDnD = false; /** Creates a new instance of InstrumentTable. */ public InstrumentTable() { this(new InstrumentTableModel(new DefaultOrchestraModel())); } /** * Creates a new instance of InstrumentTable using the specified data model. * @param dataModel The data model to be represented by this table. */ public InstrumentTable(InstrumentTableModel dataModel) { super(dataModel); setSelectionMode(ListSelectionModel.SINGLE_SELECTION); //setColumnSelectionAllowed(false); //setCellSelectionEnabled(false); //setRowSelectionAllowed(false); addMouseListener(new MouseAdapter() { public void mouseExited(MouseEvent e) { int b1 = e.BUTTON1_DOWN_MASK; if((e.getModifiersEx() & b1) != b1) return; JComponent c = (JComponent)e.getSource(); TransferHandler handler = c.getTransferHandler(); handler.exportAsDrag(c, e, TransferHandler.COPY); performingDnD = true; } }); setTransferHandler(new TransferHandler("instrument") { public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) { if(isPerformingDnD()) return false; return super.canImport(comp, transferFlavors); } protected void exportDone(JComponent source, Transferable data, int action) { performingDnD = false; } }); installKeyboardListeners(); } private void installKeyboardListeners() { KeyStroke k = getKeyStroke(KeyEvent.VK_ESCAPE, 0); getInputMap(JComponent.WHEN_FOCUSED).put(k, Actions.CLEAR_SELECTION); getActionMap().put(Actions.CLEAR_SELECTION, new Actions(Actions.CLEAR_SELECTION)); k = getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_MASK | KeyEvent.SHIFT_MASK); getInputMap(JComponent.WHEN_FOCUSED).put(k, Actions.MOVE_ON_TOP); getActionMap().put(Actions.MOVE_ON_TOP, new Actions(Actions.MOVE_ON_TOP)); k = getKeyStroke(KeyEvent.VK_UP, KeyEvent.ALT_MASK); getInputMap(JComponent.WHEN_FOCUSED).put(k, Actions.MOVE_UP); getActionMap().put(Actions.MOVE_UP, new Actions(Actions.MOVE_UP)); k = getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_MASK); getInputMap(JComponent.WHEN_FOCUSED).put(k, Actions.MOVE_DOWN); getActionMap().put(Actions.MOVE_DOWN, new Actions(Actions.MOVE_DOWN)); k = getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.ALT_MASK | KeyEvent.SHIFT_MASK); getInputMap(JComponent.WHEN_FOCUSED).put(k, Actions.MOVE_AT_BOTTOM); getActionMap().put(Actions.MOVE_AT_BOTTOM, new Actions(Actions.MOVE_AT_BOTTOM)); } /** * Gets the InstrumentTableModel that * provides the data displayed by this InstrumentTable. * @return The InstrumentTableModel that * provides the data displayed by this InstrumentTable. */ public InstrumentTableModel getModel() { return (InstrumentTableModel) super.getModel(); } /** * Sets the data model for this table to dataModel. * @param dataModel The new data source for this table. */ public void setModel(InstrumentTableModel dataModel) { super.setModel(dataModel); } /** * Gets the selected instrument. * @return The selected instrument, or null if no instrument is selected. */ public Instrument getSelectedInstrument() { int i = getSelectedRow(); if(i == -1) return null; return getModel().getOrchestraModel().getInstrument(i); } /** * Selects the specified instrument. If instr is * null or is not in the table the current selection is cleared. * @param instr The instrument to select. */ public void setSelectedInstrument(Instrument instr) { int i = getModel().getOrchestraModel().getInstrumentIndex(instr); if(i < 0) { clearSelection(); return; } setRowSelectionInterval(i, i); } /** * Gets the selected instrument. * @return The selected instrument, or null if no instrument is selected. */ public String getInstrument() { int i = getSelectedRow(); if(i == -1) return null; return getModel().getOrchestraModel().getInstrument(i).getDnDString(); } /** * Creates new instrument using the specified * drag & drop string representation of the instrument. * @param instr The drag & drop string representation of the instrument. * @see Instrument#getDnDString */ public void setInstrument(String instr) { if(!Instrument.isDnDString(instr)) return; Instrument instrument = new Instrument(); try { instrument.setDnDString(instr); } catch(Exception x) { CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x); return; } int idx; idx = getModel().getOrchestraModel().getInstrumentIndex(getSelectedInstrument()); if(idx < 0) getModel().getOrchestraModel().addInstrument(instrument); else getModel().getOrchestraModel().insertInstrument(instrument, idx); setSelectedInstrument(instrument); } /** * Returns an appropriate renderer for the cell specified by * row and column. * @param row The row of the cell to render, where 0 is the first row. * @param column The column of the cell to render, where 0 is the first column. */ public TableCellRenderer getCellRenderer(int row, int column) { TableCellRenderer r = super.getCellRenderer(row, column); if(r instanceof JComponent) { String s; s = getModel().getOrchestraModel().getInstrument(row).getDescription(); if(s != null && s.length() == 0) s = null; ((JComponent)r).setToolTipText(s); } return r; } /** * Determines whether drag and drop is initiated from this table and hasn't finished yet. * @return true if drag and drop is performing * at the moment, false otherwise. */ public boolean isPerformingDnD() { return performingDnD; } private class Actions extends AbstractAction { private static final String CLEAR_SELECTION = "clearSelection"; private static final String MOVE_ON_TOP = "moveInstrumentOnTop"; private static final String MOVE_UP = "moveInstrumentUp"; private static final String MOVE_DOWN = "moveInstrumentDown"; private static final String MOVE_AT_BOTTOM = "moveInstrumentAtBottom"; Actions(String name) { super(name); } public void actionPerformed(ActionEvent e) { String key = getValue(Action.NAME).toString(); if(key == CLEAR_SELECTION) { clearSelection(); } else if(key == MOVE_ON_TOP) { Instrument instr = getSelectedInstrument(); getModel().getOrchestraModel().moveInstrumentOnTop(instr); setSelectedInstrument(instr); } else if(key == MOVE_UP) { Instrument instr = getSelectedInstrument(); getModel().getOrchestraModel().moveInstrumentUp(instr); setSelectedInstrument(instr); } else if(key == MOVE_DOWN) { Instrument instr = getSelectedInstrument(); getModel().getOrchestraModel().moveInstrumentDown(instr); setSelectedInstrument(instr); } else if(key == MOVE_AT_BOTTOM) { Instrument instr = getSelectedInstrument(); getModel().getOrchestraModel().moveInstrumentAtBottom(instr); setSelectedInstrument(instr); } } } }