/* * 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.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.Vector; import javax.swing.AbstractCellEditor; import javax.swing.BorderFactory; import javax.swing.DefaultCellEditor; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComboBox; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.JTable; import javax.swing.SpinnerNumberModel; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableCellEditor; import org.jsampler.event.ParameterEvent; import org.jsampler.event.ParameterListener; import org.linuxsampler.lscp.Parameter; import org.linuxsampler.lscp.ParameterType; import org.linuxsampler.lscp.StringListParameter; /** * A tabular data model for representing LSCP parameters. * @see ParameterTable * @author Grigor Iliev */ public class ParameterTableModel extends AbstractTableModel { public final static int PARAMETER_NAME_COLUMN = 0; public final static int PARAMETER_VALUE_COLUMN = 1; private Parameter[] parameters; private final BooleanCellRenderer booleanRenderer = new BooleanCellRenderer(); private final BooleanCellEditor booleanEditor = new BooleanCellEditor(); private final IntegerCellRenderer integerRenderer = new IntegerCellRenderer(); private final IntegerCellEditor integerEditor = new IntegerCellEditor(); private final FloatCellRenderer floatRenderer = new FloatCellRenderer(); private final FloatCellEditor floatEditor = new FloatCellEditor(); private final StringListCellRenderer stringListRenderer = new StringListCellRenderer(); private final StringListCellEditor stringListEditor = new StringListCellEditor(); private boolean editFixedParameters; /** * Creates a new instance of ParameterTableModel. * @param parameters The parameters to be provided by this model. */ public ParameterTableModel(Parameter[] parameters) { this(parameters, false); } /** * Creates a new instance of ParameterTableModel. * @param parameters The parameters to be provided by this model. * @param editFixedParameters Determines whether fixed parameters are editable. * Specify true to enable the editing of fixed parameters. */ public ParameterTableModel(Parameter[] parameters, boolean editFixedParameters) { setParameters(parameters); setEditFixedParameters(editFixedParameters); } private final Vector parameterListeners = new Vector(); /** * Registers the specified listener for receiving event messages. * @param l The ParameterListener to register. */ public void addParameterListener(ParameterListener l) { parameterListeners.add(l); } /** * Removes the specified listener. * @param l The ParameterListener to remove. */ public void removeParameterListener(ParameterListener l) { parameterListeners.remove(l); } /** * Sets whether fixed parameters are editable. * @param b Specify true to enable the editing of fixed parameters. * @see org.linuxsampler.lscp.Parameter#isFixed */ public void setEditFixedParameters(boolean b) { editFixedParameters = b; } /** * Determines whether fixed parameters are editable. * @return true if the fixed parameters are * editable, false otherwise. * @see org.linuxsampler.lscp.Parameter#isFixed */ public boolean canEditFixedParameters() { return editFixedParameters; } /** * Gets the parameter at the specified row. * @param row The row number of the parameter to be provided. * @return The parameter at the specified row. */ public Parameter getParameter(int row) { return parameters[row]; } /** * 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) { if(column != PARAMETER_VALUE_COLUMN) return null; if(parameters[row].getType() == ParameterType.BOOL) return booleanRenderer; else if(parameters[row].getType() == ParameterType.INT) return integerRenderer; else if(parameters[row].getType() == ParameterType.FLOAT) return floatRenderer; else if(parameters[row].getType() == ParameterType.STRING_LIST) { return stringListRenderer; } return null; } /** * Returns an appropriate editor for the cell specified by * row and column. * @param row The row of the cell to edit, where 0 is the first row. * @param column The column of the cell to edit, where 0 is the first column. */ public TableCellEditor getCellEditor(int row, int column) { if(column != PARAMETER_VALUE_COLUMN) return null; Parameter p = parameters[row]; if(p.getType() == ParameterType.BOOL) return booleanEditor; if(p.getType() == ParameterType.BOOL_LIST) { } if(p.getType() == ParameterType.FLOAT_LIST) { } if(p.getType() == ParameterType.INT_LIST) { } if(p.getType() == ParameterType.STRING_LIST) { StringListParameter slp = (StringListParameter)p; if(slp.hasPossibilities()) { return stringListEditor; } } else if(p.hasPossibilities()) { return new DefaultCellEditor(new JComboBox(p.getPossibilities())); } else if(p.getType() == ParameterType.INT) { Integer i = p.hasRangeMin() ? p.getRangeMin().intValue() : null; integerEditor.setMinimum(i); i = p.hasRangeMax() ? p.getRangeMax().intValue() : null; integerEditor.setMaximum(i); return integerEditor; } else if(p.getType() == ParameterType.FLOAT) { Float f = p.hasRangeMin() ? p.getRangeMin().floatValue() : null; floatEditor.setMinimum(f); f = p.hasRangeMax() ? p.getRangeMax().floatValue() : null; floatEditor.setMaximum(f); return floatEditor; } return null; } /** * Sets the parameters to be shown in the table. * @param parameters The parameters to be shown in the table. */ public void setParameters(Parameter[] parameters) { this.parameters = parameters; fireTableDataChanged(); } /** * Gets the number of columns in the model. * @return The number of columns in the model. */ public int getColumnCount() { return 2; } /** * Gets the number of rows in the model. * @return The number of rows in the model. */ public int getRowCount() { return parameters.length; } /** * Gets the name of the column at columnIndex. * @return The name of the column at columnIndex. */ public String getColumnName(int col) { return " "; } /** * Gets the value for the cell at columnIndex and * rowIndex. * @param row The row whose value is to be queried. * @param col The column whose value is to be queried. * @return The value for the cell at columnIndex and * rowIndex. */ public Object getValueAt(int row, int col) { switch(col) { case PARAMETER_NAME_COLUMN: return parameters[row].getName(); case PARAMETER_VALUE_COLUMN: return parameters[row].getValue(); } return null; } /** * Sets the value in the cell at col * and row to value. */ public void setValueAt(Object value, int row, int col) { if(col != PARAMETER_VALUE_COLUMN) return; parameters[row].setValue(value); fireTableCellUpdated(row, col); fireParameterChanged(parameters[row]); } /** * Returns true if the cell at * row and col is editable. */ public boolean isCellEditable(int row, int col) { switch(col) { case PARAMETER_NAME_COLUMN: return false; case PARAMETER_VALUE_COLUMN: return canEditFixedParameters() || !parameters[row].isFixed(); default: return false; } } private void fireParameterChanged(Parameter p) { ParameterEvent e = new ParameterEvent(this, p); for(ParameterListener l : parameterListeners) l.parameterChanged(e); } class BooleanCellRenderer extends JCheckBox implements TableCellRenderer { private final Border emptyBorder = BorderFactory.createEmptyBorder(1, 1, 1, 1); BooleanCellRenderer() { setHorizontalAlignment(CENTER); setBorderPainted(true); } public Component getTableCellRendererComponent ( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) { if (isSelected) { setBackground(table.getSelectionBackground()); setForeground(table.getSelectionForeground()); } else { setBackground(table.getBackground()); setForeground(table.getForeground()); } Boolean b = (Boolean) value; setSelected(b != null && b); if(hasFocus) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); } else { setBorder(emptyBorder); } setToolTipText(parameters[row].getDescription()); return this; } } class BooleanCellEditor extends DefaultCellEditor { BooleanCellEditor() { super(new JCheckBox()); JCheckBox cb = (JCheckBox)getComponent(); cb.setHorizontalAlignment(JCheckBox.CENTER); } } class IntegerCellEditor extends NumberCellEditor { } class IntegerCellRenderer extends DefaultTableCellRenderer { IntegerCellRenderer() { setHorizontalAlignment(RIGHT); } } class FloatCellEditor extends NumberCellEditor { FloatCellEditor() { SpinnerNumberModel model = new SpinnerNumberModel(0.0, 0.0, 0.0, 1.0); setModel(model); } } class FloatCellRenderer extends DefaultTableCellRenderer { FloatCellRenderer() { setHorizontalAlignment(RIGHT); } } /*class StringListCellEditor extends AbstractCellEditor implements TableCellEditor { private final JButton editor = new JButton(); private final JPopupMenu menu = new JPopupMenu(); private final Vector menuItems = new Vector(); StringListCellEditor() { editor.setBorderPainted(false); editor.setContentAreaFilled(false); editor.setFocusPainted(false); editor.setFont(editor.getFont().deriveFont(java.awt.Font.PLAIN)); editor.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { menu.show(editor, 0, 0); } }); menu.addPopupMenuListener(new PopupMenuListener() { public void popupMenuCanceled(PopupMenuEvent e) { StringListCellEditor.this.cancelCellEditing(); } public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { } public void popupMenuWillBecomeVisible(PopupMenuEvent e) { } }); } private final Vector strings = new Vector(); public Object getCellEditorValue() { strings.removeAllElements(); for(JCheckBoxMenuItem i : menuItems) { if(i.isSelected()) strings.add(i.getText()); } return strings.toArray(new String[strings.size()]); } private final StringBuffer sb = new StringBuffer(); public Component getTableCellEditorComponent ( JTable table, Object value, boolean isSelected, int row, int column ) { StringListParameter slp = (StringListParameter)parameters[row]; String[] poss = slp.getPossibilities()[0]; String[] vals = (String[])value; sb.setLength(0); if(vals != null) { if(vals.length > 0) sb.append(vals[0]); for(int i = 1; i < vals.length; i++) { sb.append(", ").append(vals[i]); } } editor.setText(sb.toString()); menu.removeAll(); menuItems.removeAllElements(); for(String s : poss) { JCheckBoxMenuItem item = new JCheckBoxMenuItem(s); setListener(item); for(String s2 : vals) if(s2.equals(s)) item.setSelected(true); menu.add(item); menuItems.add(item); } return editor; } private void setListener(JCheckBoxMenuItem i) { i.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { StringListCellEditor.this.stopCellEditing(); } }); } }*/ private static JComboBox comboBox = new JComboBox(); class StringListCellEditor extends DefaultCellEditor { StringListCellEditor() { super(comboBox); } public Object getCellEditorValue() { Object o = comboBox.getSelectedItem(); if(o == null) return null; String[] sS = new String[1]; sS[0] = (String)o; return sS; } public Component getTableCellEditorComponent ( JTable table, Object value, boolean isSelected, int row, int column ) { StringListParameter slp = (StringListParameter)parameters[row]; comboBox.removeAllItems(); for(String s : slp.getPossibilities()[0]) comboBox.addItem(s); return comboBox; } } class StringListCellRenderer extends DefaultTableCellRenderer { private final StringBuffer sb = new StringBuffer(); public Component getTableCellRendererComponent ( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) { if(value instanceof String) return super.getTableCellRendererComponent ( table, value, isSelected, hasFocus, row, column ); String[] s = (String[])value; sb.setLength(0); if(s != null) { if(s.length > 0) sb.append(s[0]); for(int i = 1; i < s.length; i++) sb.append(", ").append(s[i]); } return super.getTableCellRendererComponent ( table, sb.toString(), isSelected, hasFocus, row, column ); } } }