MixerTest2.java Source code

Java tutorial

Introduction

Here is the source code for MixerTest2.java

Source

/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O'Reilly 
*/
// MixerTest2.java
//A test of the MixerModel and sliders for rendering volume values.
//This version also includes adjustable sliders for editing the
//volume values.
//

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventObject;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

public class MixerTest2 extends JFrame {

    public MixerTest2() {
        super("Customer Editor Test");
        setSize(600, 160);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        MixerModel test = new MixerModel();
        test.dump();
        JTable jt = new JTable(test);
        jt.setDefaultRenderer(Volume.class, new VolumeRenderer());
        jt.setDefaultEditor(Volume.class, new VolumeEditor());
        JScrollPane jsp = new JScrollPane(jt);
        getContentPane().add(jsp, BorderLayout.CENTER);
    }

    public static void main(String args[]) {
        MixerTest2 mt = new MixerTest2();
        mt.setVisible(true);
    }
}

//MixerModel.java
//An audio mixer table data model. This model contains the following columns:
//<br> + Track name (String)
//<br> + Track start time (String)
//<br> + Track stop time (String)
//<br> + Left channel volume (Volume, 0 . . 100)
//<br> + Right channel volume (Volume, 0 . . 100)
//

class MixerModel extends AbstractTableModel {

    String headers[] = { "Track", "Start", "Stop", "Left Volume", "Right Volume" };

    Class columnClasses[] = { String.class, String.class, String.class, Volume.class, Volume.class };

    Object data[][] = { { "Bass", "0:00:000", "1:00:000", new Volume(56), new Volume(56) },
            { "Strings", "0:00:000", "0:52:010", new Volume(72), new Volume(52) },
            { "Brass", "0:08:000", "1:00:000", new Volume(99), new Volume(0) },
            { "Wind", "0:08:000", "1:00:000", new Volume(0), new Volume(99) }, };

    public int getRowCount() {
        return data.length;
    }

    public int getColumnCount() {
        return headers.length;
    }

    public Class getColumnClass(int c) {
        return columnClasses[c];
    }

    public String getColumnName(int c) {
        return headers[c];
    }

    public boolean isCellEditable(int r, int c) {
        return true;
    }

    public Object getValueAt(int r, int c) {
        return data[r][c];
    }

    // Ok, do something extra here so that if we get a String object back (from
    // a
    // text field editor) we can still store that as a valid Volume object. If
    // it's just a string, then stick it directly into our data array.
    public void setValueAt(Object value, int r, int c) {
        if (c >= 3) {
            ((Volume) data[r][c]).setVolume(value);
        } else {
            data[r][c] = value;
        }
    }

    // A quick debugging utility to dump out the contents of our data structure
    public void dump() {
        for (int i = 0; i < data.length; i++) {
            System.out.print("|");
            for (int j = 0; j < data[0].length; j++) {
                System.out.print(data[i][j] + "|");
            }
            System.out.println();
        }
    }
}

//Volume.java
//A simple data structure for track volumes on a mixer.
//

class Volume {
    private int volume;

    public Volume(int v) {
        setVolume(v);
    }

    public Volume() {
        this(50);
    }

    public void setVolume(int v) {
        volume = (v < 0 ? 0 : v > 100 ? 100 : v);
    }

    public void setVolume(Object v) {
        if (v instanceof String) {
            setVolume(Integer.parseInt((String) v));
        } else if (v instanceof Number) {
            setVolume(((Number) v).intValue());
        } else if (v instanceof Volume) {
            setVolume(((Volume) v).getVolume());
        }
    }

    public int getVolume() {
        return volume;
    }

    public String toString() {
        return String.valueOf(volume);
    }
}

//VolumeRenderer.java
//A slider renderer for volume values in a table.
//

class VolumeRenderer extends JSlider implements TableCellRenderer {

    public VolumeRenderer() {
        super(SwingConstants.HORIZONTAL);
        // set a starting size...some 1.2/1.3 systems need this
        setSize(115, 15);
    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
            int row, int column) {
        if (value == null) {
            return this;
        }
        if (value instanceof Volume) {
            setValue(((Volume) value).getVolume());
        } else {
            setValue(0);
        }
        return this;
    }
}

//VolumeEditor.java
//A slider Editor for volume values in a table.
//

class VolumeEditor extends JSlider implements TableCellEditor {

    public OkCancel helper = new OkCancel();

    protected transient Vector listeners;

    protected transient int originalValue;

    protected transient boolean editing;

    public VolumeEditor() {
        super(SwingConstants.HORIZONTAL);
        listeners = new Vector();
    }

    // Inner class for the ok/cancel popup window that displays below the
    // active scrollbar. It's position will have to be determined by the
    // editor when getTableCellEditorComponent() is called.
    public class OkCancel extends JWindow {
        private JButton okB = new JButton(new ImageIcon("accept.gif"));

        private JButton cancelB = new JButton(new ImageIcon("decline.gif"));

        private int w = 50;

        private int h = 24;

        public OkCancel() {
            setSize(w, h);
            setBackground(Color.yellow);
            JPanel p = new JPanel(new GridLayout(0, 2));
            //p.setBorder(BorderFactory.createLineBorder(Color.gray));
            //okB.setBorder(null);
            //cancelB.setBorder(null);
            p.add(okB);
            p.add(cancelB);
            setContentPane(p);

            okB.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ae) {
                    stopCellEditing();
                }
            });

            cancelB.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ae) {
                    cancelCellEditing();
                }
            });
        }
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
            int column) {
        if (value == null) {
            return this;
        }
        if (value instanceof Volume) {
            setValue(((Volume) value).getVolume());
        } else {
            setValue(0);
        }
        table.setRowSelectionInterval(row, row);
        table.setColumnSelectionInterval(column, column);
        originalValue = getValue();
        editing = true;
        Point p = table.getLocationOnScreen();
        Rectangle r = table.getCellRect(row, column, true);
        helper.setLocation(r.x + p.x + getWidth() - 50, r.y + p.y + getHeight());
        helper.setVisible(true);
        return this;
    }

    // CellEditor methods
    public void cancelCellEditing() {
        fireEditingCanceled();
        editing = false;
        helper.setVisible(false);
    }

    public Object getCellEditorValue() {
        return new Integer(getValue());
    }

    public boolean isCellEditable(EventObject eo) {
        return true;
    }

    public boolean shouldSelectCell(EventObject eo) {
        return true;
    }

    public boolean stopCellEditing() {
        fireEditingStopped();
        editing = false;
        helper.setVisible(false);
        return true;
    }

    public void addCellEditorListener(CellEditorListener cel) {
        listeners.addElement(cel);
    }

    public void removeCellEditorListener(CellEditorListener cel) {
        listeners.removeElement(cel);
    }

    protected void fireEditingCanceled() {
        setValue(originalValue);
        ChangeEvent ce = new ChangeEvent(this);
        for (int i = listeners.size() - 1; i >= 0; i--) {
            ((CellEditorListener) listeners.elementAt(i)).editingCanceled(ce);
        }
    }

    protected void fireEditingStopped() {
        ChangeEvent ce = new ChangeEvent(this);
        for (int i = listeners.size() - 1; i >= 0; i--) {
            ((CellEditorListener) listeners.elementAt(i)).editingStopped(ce);
        }
    }
}