com.vgi.mafscaling.LogPlay.java Source code

Java tutorial

Introduction

Here is the source code for com.vgi.mafscaling.LogPlay.java

Source

/*
* Open-Source tuning tools
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

package com.vgi.mafscaling;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.Rectangle2D;
import java.util.HashSet;
import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIDefaults;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;

import quick.dbtable.DBTable;

public class LogPlay extends JFrame implements ActionListener {
    private static final long serialVersionUID = -1614821051358033847L;

    public class TableHolder {
        public int xColIdx;
        public int yColIdx;
        public int zColIdx;
        public LogPlayTable table;

        TableHolder(int x, int y, int z, LogPlayTable t) {
            xColIdx = x;
            yColIdx = y;
            zColIdx = z;
            table = t;
            table.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    int size;
                    synchronized (lock) {
                        tables.remove(new TableHolder(xColIdx, yColIdx, zColIdx, table));
                        size = tables.size();
                    }
                    if (size == 0)
                        stop();
                }
            });
        }

        @Override
        public int hashCode() {
            return table.hashCode() ^ (31 * xColIdx) ^ (31 * yColIdx);
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            TableHolder other = (TableHolder) obj;
            if (xColIdx != other.xColIdx)
                return false;
            if (yColIdx != other.yColIdx)
                return false;
            if (table != other.table)
                return false;
            return true;
        }
    }

    private final int step = 20;
    private Timer timer = null;
    private LogView logView = null;
    private JPanel playerPanel = null;
    private DBTable logDataTable = null;
    private JButton playButton = null;
    private JButton stopButton = null;
    private JButton ffwButton = null;
    private JButton rewButton = null;
    private JButton newPlayButton = null;
    private JComboBox<String> xAxisColumn = null;
    private JComboBox<String> yAxisColumn = null;
    private JComboBox<String> zAxisColumn = null;
    private JCheckBox showIntepCells = null;
    private JCheckBox showSignifCells = null;
    private JCheckBox showTraceLine = null;
    private JCheckBox showTraceMarker = null;
    private JSlider progressBar = null;
    private HashSet<TableHolder> tables = new HashSet<TableHolder>();
    private Object lock = new Object();
    private volatile boolean playing = false;
    private volatile boolean showMarker = false;
    private boolean paused = false;
    private int lastRow = 0;
    private int startPlay = -1;
    private int endPlay = -1;
    private int timerDelay = 200;
    private AtomicInteger playNext = null;
    private ImageIcon playIcon = null;
    private ImageIcon pauseIcon = null;
    private Insets insets0 = new Insets(0, 0, 0, 0);
    private Insets insets3 = new Insets(3, 3, 3, 3);
    private UIDefaults zeroInsets = new UIDefaults();

    public LogPlay(LogView logView) {
        //       super(SwingUtilities.windowForComponent(logView));
        super("Log Play");
        this.logView = logView;
        logDataTable = logView.getLogDataTable();
        initialize();
    }

    private void initialize() {
        lastRow = logDataTable.getRowCount() - 1;
        playNext = new AtomicInteger(1);
        playIcon = new ImageIcon(getClass().getResource("/play.png"));
        pauseIcon = new ImageIcon(getClass().getResource("/pause.png"));
        zeroInsets.put("Button.contentMargins", insets0);
        timer = new Timer(timerDelay, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                progressBar.setValue(progressBar.getValue() + playNext.get());
            }
        });

        JPanel dataPanel = new JPanel();
        GridBagLayout gbl_dataPanel = new GridBagLayout();
        gbl_dataPanel.columnWidths = new int[] { 0 };
        gbl_dataPanel.rowHeights = new int[] { 0, 1 };
        gbl_dataPanel.columnWeights = new double[] { 1.0 };
        gbl_dataPanel.rowWeights = new double[] { 0.0, 1.0 };
        dataPanel.setLayout(gbl_dataPanel);
        getContentPane().add(dataPanel);

        createSelectionPanel(dataPanel);
        createPlayer(dataPanel);

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                timer.stop();
                synchronized (lock) {
                    for (TableHolder t : tables)
                        t.table.dispose();
                    tables.clear();
                }
                logView.disposeLogView();
            }
        });

        pack();
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setIconImage((new ImageIcon(getClass().getResource("/player.png"))).getImage());
        setResizable(false);
        setLocationRelativeTo(SwingUtilities.windowForComponent(logView));
        setVisible(true);
    }

    private void createSelectionPanel(JPanel panel) {
        JPanel selectionPanel = new JPanel();
        GridBagLayout gbl_selectionPanel = new GridBagLayout();
        gbl_selectionPanel.columnWidths = new int[] { 0, 0, 0, 0, 0, 0, 0 };
        gbl_selectionPanel.rowHeights = new int[] { 0 };
        gbl_selectionPanel.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 };
        gbl_selectionPanel.rowWeights = new double[] { 0.0 };
        selectionPanel.setLayout(gbl_selectionPanel);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = insets3;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.gridx = 0;
        gbc.gridy = 0;

        selectionPanel.add(new JLabel("X-Axis"), gbc);

        gbc.gridx++;
        xAxisColumn = new JComboBox<String>();
        selectionPanel.add(xAxisColumn, gbc);

        gbc.gridx++;
        selectionPanel.add(new JLabel("Y-Axis"), gbc);

        gbc.gridx++;
        yAxisColumn = new JComboBox<String>();
        selectionPanel.add(yAxisColumn, gbc);

        gbc.gridx++;
        selectionPanel.add(new JLabel("Data*"), gbc);

        gbc.gridx++;
        zAxisColumn = new JComboBox<String>();
        selectionPanel.add(zAxisColumn, gbc);

        gbc.gridx++;
        gbc.weightx = 1.0;
        newPlayButton = new JButton("New Play Table");
        newPlayButton.addActionListener(this);
        selectionPanel.add(newPlayButton, gbc);

        xAxisColumn.addItem("");
        yAxisColumn.addItem("");
        zAxisColumn.addItem("Optional");
        for (int i = 0; i < logDataTable.getColumnCount(); ++i) {
            String colName = logDataTable.getColumn(i).getHeaderValue().toString();
            xAxisColumn.addItem(colName);
            yAxisColumn.addItem(colName);
            zAxisColumn.addItem(colName);
        }
        zAxisColumn.setSelectedIndex(0);

        gbc.insets = insets0;
        gbc.gridx = 0;
        gbc.anchor = GridBagConstraints.PAGE_START;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        panel.add(selectionPanel, gbc);
    }

    private void createPlayer(JPanel panel) {
        playerPanel = new JPanel();
        GridBagLayout gbl_playerPanel = new GridBagLayout();
        gbl_playerPanel.columnWidths = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
        gbl_playerPanel.rowHeights = new int[] { 0, 0, 0, 0 };
        gbl_playerPanel.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 };
        gbl_playerPanel.rowWeights = new double[] { 0.0, 0.0 };
        playerPanel.setLayout(gbl_playerPanel);

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = insets0;
        gbc.anchor = GridBagConstraints.PAGE_START;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 0;
        gbc.gridy = 0;

        progressBar = new JSlider(0, 0, 0);
        progressBar.setMinimum(0);
        progressBar.setMaximum(lastRow);
        setProgressBar(logDataTable.getSelectedRow());
        progressBar.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                int row = progressBar.getValue();
                if (playing) {
                    if (row == lastRow || (endPlay >= 0 && endPlay < row)) {
                        stop();
                        return;
                    }
                    if (showMarker) {
                        Rectangle2D dataArea = logView.getChartPanel().getChartRenderingInfo().getPlotInfo()
                                .getDataArea();
                        XYPlot plot = (XYPlot) logView.getChartPanel().getChart().getPlot();
                        double x = plot.getDomainAxis().valueToJava2D(row, dataArea, plot.getDomainAxisEdge());
                        boolean isLeft = (x < (dataArea.getMaxX() - dataArea.getMinX()) / 2) ? true : false;
                        logView.setMarkers(row, isLeft);
                    }
                }
                logDataTable.getTable().setRowSelectionInterval(row, row);
                logDataTable.getTable().changeSelection(row, logDataTable.getSelectedColumn(), false, false);
                double x, y, z;
                int origXCol, origYCol, origZCol;
                synchronized (lock) {
                    for (TableHolder tableHolder : tables) {
                        try {
                            origXCol = logDataTable.getCurrentIndexForOriginalColumn(tableHolder.xColIdx);
                            origYCol = logDataTable.getCurrentIndexForOriginalColumn(tableHolder.yColIdx);
                            origZCol = logDataTable.getCurrentIndexForOriginalColumn(tableHolder.zColIdx);
                            x = Double.valueOf(logDataTable.getValueAt(row, origXCol).toString());
                            y = Double.valueOf(logDataTable.getValueAt(row, origYCol).toString());
                            if (origZCol > 0)
                                z = Double.valueOf(logDataTable.getValueAt(row, origZCol).toString());
                            else
                                z = Double.NaN;
                            tableHolder.table.setCurrentPoint(x, y, z);
                        } catch (Exception ex) {
                            JOptionPane
                                    .showMessageDialog(null,
                                            "Invalid numeric value in column " + (tableHolder.xColIdx + 1)
                                                    + ", row " + (row + 1),
                                            "Invalid value", JOptionPane.ERROR_MESSAGE);
                            return;
                        }
                    }
                }
            }
        });
        gbc.weightx = 1.0;
        gbc.gridwidth = gbl_playerPanel.columnWidths.length;
        playerPanel.add(progressBar, gbc);

        stopButton = addPlayerButton(0, new ImageIcon(getClass().getResource("/stop.png")));
        rewButton = addPlayerButton(1, new ImageIcon(getClass().getResource("/rew.png")));
        playButton = addPlayerButton(2, playIcon);
        ffwButton = addPlayerButton(3, new ImageIcon(getClass().getResource("/ffw.png")));
        showIntepCells = addCheckBox(4, "Show interpolation cells");
        showSignifCells = addCheckBox(5, "Show significant cell");
        showTraceLine = addCheckBox(6, "Show trace line");
        showTraceMarker = addCheckBox(7, "Show plot trace marker");

        gbc.weightx = 0.0;
        gbc.gridwidth = 0;
        gbc.gridy = 1;
        panel.add(playerPanel, gbc);
    }

    //////////////////////////////////////////////////////////////////////////////////////
    // WORK FUNCTIONS
    //////////////////////////////////////////////////////////////////////////////////////

    void createPlayTable() {
        int x, y, z;
        x = xAxisColumn.getSelectedIndex() - 1;
        if (x < 0) {
            JOptionPane.showMessageDialog(null, "Please select 'X-Axis column' from drop-down list", "Error",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }
        y = yAxisColumn.getSelectedIndex() - 1;
        if (y < 0) {
            JOptionPane.showMessageDialog(null, "Please select 'X-Axis column' from drop-down list", "Error",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }
        z = zAxisColumn.getSelectedIndex() - 1;
        // no need to lock as og isn't being played yet
        LogPlayTable lpt = new LogPlayTable(this,
                "X-Axis: " + xAxisColumn.getSelectedItem() + "; Y-Axis: " + yAxisColumn.getSelectedItem());
        lpt.setShowInterpolationCells(showIntepCells.isSelected());
        lpt.setShowSignificantCell(showSignifCells.isSelected());
        lpt.setShowTraceLine(showTraceLine.isSelected());
        TableHolder th = new TableHolder(x, y, z, lpt);
        tables.add(th);
    }

    private JButton addPlayerButton(int column, ImageIcon icon) {
        JButton button = new JButton(icon);
        button.putClientProperty("Nimbus.Overrides", zeroInsets);
        button.setMargin(insets0);
        button.setBorderPainted(false);
        button.setContentAreaFilled(false);
        button.addActionListener(this);
        GridBagConstraints gbc_button = new GridBagConstraints();
        gbc_button.insets = insets0;
        gbc_button.anchor = GridBagConstraints.WEST;
        gbc_button.gridx = column;
        gbc_button.gridy = 1;
        playerPanel.add(button, gbc_button);
        return button;
    }

    private JCheckBox addCheckBox(int column, String text) {
        JCheckBox check = new JCheckBox(text);
        check.addActionListener(this);
        GridBagConstraints gbc_check = new GridBagConstraints();
        gbc_check.insets = insets0;
        gbc_check.anchor = GridBagConstraints.WEST;
        gbc_check.gridx = column;
        gbc_check.gridy = 1;
        playerPanel.add(check, gbc_check);
        return check;
    }

    private void play() {
        // no need to lock yet
        if (tables.size() == 0) {
            JOptionPane.showMessageDialog(null, "Please create at least one play table", "Error",
                    JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (playing)
            return;
        if (startPlay >= 0 && !paused) {
            logDataTable.getTable().setRowSelectionInterval(startPlay, startPlay);
            int col = logDataTable.getSelectedColumn();
            logDataTable.getTable().changeSelection(startPlay, (col > 0 ? col : 0), false, false);
        }
        paused = false;
        setProgressBar(logDataTable.getSelectedRow());
        timer.setDelay(timerDelay);
        playNext.set(1);
        playing = true;
        timer.start();
        playButton.setIcon(pauseIcon);
        newPlayButton.setEnabled(false);
        logDataTable.setEditable(false);
        logView.disableMouseListener();
        synchronized (lock) {
            for (TableHolder t : tables)
                t.table.setEditable(false);
        }
    }

    private void pause() {
        if (!playing)
            return;
        playing = false;
        paused = true;
        timer.stop();
        timer.setDelay(timerDelay);
        playButton.setIcon(playIcon);
        playNext.set(1);
    }

    private void stop() {
        if (playing)
            pause();
        if (paused)
            paused = false;
        else
            return;
        setProgressBar(startPlay);
        logDataTable.setEditable(true);
        logView.enableMouseListener();
        newPlayButton.setEnabled(true);
        synchronized (lock) {
            for (TableHolder t : tables)
                t.table.setEditable(true);
        }
    }

    private void rewind() {
        playNext.set(-1);
        if (timer.getDelay() > 0)
            timer.setDelay(timer.getDelay() - step);
    }

    private void forward() {
        playNext.set(1);
        if (timer.getDelay() > 0)
            timer.setDelay(timer.getDelay() - step);
    }

    private void setShowInterpolationCells() {
        synchronized (lock) {
            for (TableHolder t : tables)
                t.table.setShowInterpolationCells(showIntepCells.isSelected());
        }
    }

    private void setShowSignificantCell() {
        synchronized (lock) {
            for (TableHolder t : tables)
                t.table.setShowSignificantCell(showSignifCells.isSelected());
        }
    }

    private void setShowTraceLine() {
        synchronized (lock) {
            for (TableHolder t : tables)
                t.table.setShowTraceLine(showTraceLine.isSelected());
        }
    }

    public void setStartEndArea(ValueMarker startMarker, ValueMarker endMarker) {
        int start = (startMarker == null ? -1 : (int) startMarker.getValue());
        int end = (endMarker == null ? -1 : (int) endMarker.getValue());
        if (start == -1 || end == -1)
            startPlay = Math.max(start, end);
        else {
            startPlay = Math.min(start, end);
            endPlay = Math.max(start, end);
        }
        if (startPlay > lastRow)
            startPlay = lastRow;
        if (endPlay > lastRow)
            endPlay = lastRow;
        setProgressBar(startPlay);
    }

    public void setProgressBar(int val) {
        if (val >= 0 && val <= lastRow)
            progressBar.setValue(val);
        else
            progressBar.setValue(0);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == newPlayButton)
            createPlayTable();
        else if (e.getSource() == playButton) {
            if (playing)
                pause();
            else
                play();
        } else if (e.getSource() == rewButton) {
            rewind();
        } else if (e.getSource() == ffwButton) {
            forward();
        } else if (e.getSource() == stopButton) {
            stop();
        } else if (e.getSource() == showIntepCells) {
            setShowInterpolationCells();
        } else if (e.getSource() == showSignifCells) {
            setShowSignificantCell();
        } else if (e.getSource() == showTraceLine) {
            setShowTraceLine();
        } else if (e.getSource() == showTraceMarker) {
            showMarker = showTraceMarker.isSelected();
        }
    }

}