Package SimulatorsGUI

Source Code of SimulatorsGUI.ProgramComponent$ProgramTableModel

/********************************************************************************
* The contents of this file are subject to the GNU General Public License      *
* (GPL) Version 2 or later (the "License"); you may not use this file except   *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.gnu.org/copyleft/gpl.html                                         *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* without warranty of any kind, either expressed or implied. See the License   *
* for the specific language governing rights and limitations under the         *
* License.                                                                     *
*                                                                              *
* This file was originally developed as part of the software suite that        *
* supports the book "The Elements of Computing Systems" by Nisan and Schocken, *
* MIT Press 2005. If you modify the contents of this file, please document and *
* mark your changes clearly, for the benefit of others.                        *
********************************************************************************/

package SimulatorsGUI;

import Hack.Events.ErrorEvent;
import Hack.Events.ErrorEventListener;
import Hack.Events.ProgramEvent;
import Hack.Events.ProgramEventListener;
import Hack.VMEmulator.VMEmulatorInstruction;
import Hack.VMEmulator.VMProgramGUI;
import Hack.VirtualMachine.HVMInstruction;
import HackGUI.MouseOverJButton;
import HackGUI.Utilities;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;

/**
* This class represents the gui of a Program.
*/
public class ProgramComponent extends JPanel implements VMProgramGUI {

    private static final String OPEN_GIF_RESOURCE = "resources/open2.gif";
    private static final String FIND_GIF_RESOURCE = "resources/find.gif";
    private static final String SMALLNEW_GIF_RESOURCE = "resources/smallnew.gif";
    // A vector containing the listeners to this object.
    private ArrayList<ProgramEventListener> listeners;

    // A vector containing the error listeners to this object.
    private ArrayList<ErrorEventListener> errorEventListeners;

    // The table representing this program
    protected JTable programTable;

    // The model of the table;
    private ProgramTableModel model;

    // The HVMInstructions of this program.
    protected VMEmulatorInstruction[] instructions;

    // Creating the browse button.
    protected MouseOverJButton browseButton = new MouseOverJButton();

    // Creating the icon of the button.
    private ImageIcon browseIcon = new ImageIcon(ProgramComponent.class.getResource(OPEN_GIF_RESOURCE));

    // The file chooser window.
    //private FileChooserWindow fileChooser = new FileChooserWindow(null);
    private JFileChooser fileChooser = new JFileChooser();

    // The current instruction index (yellow background).
    private int instructionIndex;

    // The text field with the message (for example "Loading...").
    private JTextField messageTxt = new JTextField();

    // The cell renderer of this table.
    private ColoredTableCellRenderer coloredRenderer = new ColoredTableCellRenderer();

    // Creating the search button.
    private MouseOverJButton searchButton = new MouseOverJButton();

    // Creating the icon for the search button.
    private ImageIcon searchIcon = new ImageIcon(ProgramComponent.class.getResource(FIND_GIF_RESOURCE));

    // The window of searching a specific location in memory.
    private SearchProgramWindow searchWindow;

    // The scroll pane on which the table is placed.
    private JScrollPane scrollPane;

    // The name of this component ("Program :").
    private JLabel nameLbl = new JLabel();

    // Creating the clear button.
    protected MouseOverJButton clearButton = new MouseOverJButton();

    // Creating the icon for the clear button.
    private ImageIcon clearIcon = new ImageIcon(ProgramComponent.class.getResource(SMALLNEW_GIF_RESOURCE));

    /**
     * Constructs a new ProgramComponent.
     */
    public ProgramComponent() {
        listeners = new ArrayList<>();
        errorEventListeners = new ArrayList<>();
        instructions = new VMEmulatorInstruction[0];
        model = new ProgramTableModel();
        programTable = new JTable(model);
        programTable.setDefaultRenderer(programTable.getColumnClass(0), coloredRenderer);
        searchWindow = new SearchProgramWindow(programTable, instructions);

        jbInit();

    }

    /**
     * Registers the given ProgramEventListener as a listener to this GUI.
     */
    @Override
    public synchronized void addProgramListener(ProgramEventListener listener) {
        listeners.add(listener);
    }

    /**
     * Un-registers the given ProgramEventListener from being a listener to this GUI.
     */
    @Override
    public synchronized void removeProgramListener(ProgramEventListener listener) {
        listeners.remove(listener);
    }

    /**
     * Notifies all the ProgramEventListeners on a change in the program by creating a
     * ProgramEvent (with the new event type and program's directory name) and sending it
     * using the programChanged method to all the listeners.
     */
    @Override
    public void notifyProgramListeners(byte eventType, String programFileName) {
        ProgramEvent event = new ProgramEvent(this, eventType, programFileName);
        for(int i=0;i<listeners.size();i++) {
            listeners.get(i).programChanged(event);
        }
    }

    /**
     * Registers the given ErrorEventListener as a listener to this GUI.
     */
    @Override
    public synchronized void addErrorListener(ErrorEventListener listener) {
        errorEventListeners.add(listener);
    }

    /**
     * Un-registers the given ErrorEventListener from being a listener to this GUI.
     */
    @Override
    public synchronized void removeErrorListener(ErrorEventListener listener) {
        errorEventListeners.remove(listener);
    }

    /**
     * Notifies all the ErrorEventListener on an error in this gui by
     * creating an ErrorEvent (with the error message) and sending it
     * using the errorOccured method to all the listeners.
     */
    @Override
    public void notifyErrorListeners(String errorMessage) {
        ErrorEvent event = new ErrorEvent(this, errorMessage);
        for (int i=0; i<errorEventListeners.size(); i++) {
            errorEventListeners.get(i).errorOccured(event);
        }
    }

    /**
     * Sets the working directory with the given directory File.
     */
    public void setWorkingDir(File file) {
        fileChooser.setCurrentDirectory(file);
    }

    /**
     * Sets the contents of the gui with the first instructionsLength
   * instructions from the given array of instructions.
     */
    @Override
    public synchronized void setContents(VMEmulatorInstruction[] newInstructions,
                     int newInstructionsLength) {
        instructions = new VMEmulatorInstruction[newInstructionsLength];
        System.arraycopy(newInstructions,0,instructions,0,newInstructionsLength);
        programTable.revalidate();
        try {
            wait(100);
        } catch (InterruptedException ie) {}
        searchWindow.setInstructions(instructions);
    }

    /**
     * Sets the current instruction with the given instruction index.
     */
    @Override
    public void setCurrentInstruction(int instructionIndex) {
        this.instructionIndex = instructionIndex;
        Utilities.tableCenterScroll(this, programTable, instructionIndex);
    }

    /**
     * Resets the contents of this ProgramComponent.
     */
    @Override
    public void reset() {
        instructions = new VMEmulatorInstruction[0];
        programTable.clearSelection();
        repaint();
    }

    /**
     * Opens the program file chooser for loading a program.
     */
    public void loadProgram() {
        int returnVal = fileChooser.showDialog(this, "Load Program");
        if(returnVal == JFileChooser.APPROVE_OPTION) {
            notifyProgramListeners(ProgramEvent.LOAD,
                                   fileChooser.getSelectedFile().getAbsolutePath());
        }
    }

    /**
     * Implementing the action of pressing the browse button.
     */
    public void browseButton_actionPerformed(ActionEvent e) {
        loadProgram();
    }

    /**
     * Hides the displayed message.
     */
    @Override
    public void hideMessage() {
        messageTxt.setText("");
        messageTxt.setVisible(false);
        searchButton.setVisible(true);
        clearButton.setVisible(true);
        browseButton.setVisible(true);
    }

    /**
     * Displays the given message.
     */
    @Override
    public void showMessage(String message) {
        messageTxt.setText(message);
        messageTxt.setVisible(true);
        searchButton.setVisible(false);
        clearButton.setVisible(false);
        browseButton.setVisible(false);
    }

    // Determines the width of each column in the table.
    private void determineColumnWidth() {
        TableColumn column;
        for (int i = 0; i < 3; i++) {
            column = programTable.getColumnModel().getColumn(i);
            if (i == 0) {
                column.setPreferredWidth(30);
            }
            else if (i==1) {
                column.setPreferredWidth(40);
            }
            else if(i==2) {
                column.setPreferredWidth(100);
            }
        }
    }

    /**
     * Implementing the action of pressing the search button.
     */
    public void searchButton_actionPerformed(ActionEvent e) {
        searchWindow.showWindow();
    }

    /**
     * Implementing the action of pressing the clear button.
     */
    public void clearButton_actionPerformed(ActionEvent e) {
        Object[] options = {"Yes", "No","Cancel"};
        int pressedButtonValue = JOptionPane.showOptionDialog(this.getParent(),
            "Are you sure you want to clear the program?",
            "Warning Message",
            JOptionPane.YES_NO_CANCEL_OPTION,
            JOptionPane.WARNING_MESSAGE,
            null,
            options,
            options[2]);

        if(pressedButtonValue==JOptionPane.YES_OPTION) {
            notifyProgramListeners(ProgramEvent.CLEAR, null);
        }
    }

    /**
     * Sets the number of visible rows.
     */
    public void setVisibleRows(int num) {
        int tableHeight = num * programTable.getRowHeight();
        scrollPane.setSize(getTableWidth(), tableHeight + 3);
        setPreferredSize(new Dimension(getTableWidth(), tableHeight + 30));
        setSize(getTableWidth(), tableHeight + 30);
    }

    /**
     * Sets the name label.
     */
    public void setNameLabel (String name) {
        nameLbl.setText(name);
    }

    /**
     * Returns the width of the table.
     */
    public int getTableWidth() {
        return 225;
    }

    // Initialization of this component.
    private void jbInit() {
        fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        fileChooser.setFileFilter(new VMFileFilter());
        programTable.getTableHeader().setReorderingAllowed(false);
        programTable.getTableHeader().setResizingAllowed(false);
        scrollPane = new JScrollPane(programTable);
        scrollPane.setLocation(0,27);
        browseButton.setToolTipText("Load Program");
        browseButton.setIcon(browseIcon);
        browseButton.setBounds(new Rectangle(119, 2, 31, 24));
        browseButton.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                browseButton_actionPerformed(e);
            }
        });
        messageTxt.setBackground(SystemColor.info);
        messageTxt.setEnabled(false);
        messageTxt.setFont(Utilities.labelsFont);
        messageTxt.setPreferredSize(new Dimension(70, 20));
        messageTxt.setDisabledTextColor(Color.red);
        messageTxt.setEditable(false);
        messageTxt.setBounds(new Rectangle(91, 2, 132, 23));
        messageTxt.setVisible(false);

        searchButton.setToolTipText("Search");
        searchButton.setIcon(searchIcon);
        searchButton.setBounds(new Rectangle(188, 2, 31, 24));
        searchButton.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                searchButton_actionPerformed(e);
            }
        });
        this.setForeground(Color.lightGray);
        this.setLayout(null);
        nameLbl.setText("Program");
        nameLbl.setBounds(new Rectangle(5, 5, 73, 20));
        nameLbl.setFont(Utilities.labelsFont);

        clearButton.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                clearButton_actionPerformed(e);
            }
        });
        clearButton.setBounds(new Rectangle(154, 2, 31, 24));
        clearButton.setIcon(clearIcon);
        clearButton.setToolTipText("Clear");
        this.add(scrollPane, null);
        this.add(nameLbl, null);
        this.add(searchButton, null);
        this.add(clearButton, null);
        this.add(messageTxt, null);
        this.add(browseButton, null);
        determineColumnWidth();
        programTable.setTableHeader(null);
        setBorder(BorderFactory.createEtchedBorder());
    }


    // An inner class representing the model of the CallStack table.
    class ProgramTableModel extends AbstractTableModel {

        /**
         * Returns the number of columns.
         */
        @Override
        public int getColumnCount() {
            return 3;
        }

        /**
         * Returns the number of rows.
         */
        @Override
        public int getRowCount() {
            return instructions.length;
        }

        /**
         * Returns the names of the columns.
         */
        @Override
        public String getColumnName(int col) {
            return null;
        }

        /**
         * Returns the value at a specific row and column.
         */
        @Override
        public Object getValueAt(int row, int col) {

            String[] formattedString = instructions[row].getFormattedStrings();

            switch(col) {
                case 0:
                    short index = instructions[row].getIndexInFunction();
                    if (index >= 0) {
                return new Short(index);
            }
                    else {
                return "";
            }
                case 1:
                    return formattedString[0];
                case 2:
                    return formattedString[1] + " " + formattedString[2];
                default:
                    return null;

            }
        }

        /**
         * Returns true of this table cells are editable, false -
         * otherwise.
         */
        @Override
        public boolean isCellEditable(int row, int col){
            return false;
        }
    }

    // An inner class which implemets the cell renderer of the program table, giving
    // the feature of coloring the background of a specific cell.
    class ColoredTableCellRenderer extends DefaultTableCellRenderer {

        @Override
        public Component getTableCellRendererComponent
            (JTable table, Object value, boolean selected, boolean focused, int row, int column)
        {
            setEnabled(table == null || table.isEnabled());
            setBackground(null);
            setForeground(null);

            if(column==0) {
                setHorizontalAlignment(SwingConstants.CENTER);
            }
            else {
                setHorizontalAlignment(SwingConstants.LEFT);
            }
            if(row==instructionIndex) {
                setBackground(Color.yellow);
            }
            else {
                HVMInstruction currentInstruction = instructions[row];
                String op = (currentInstruction.getFormattedStrings())[0];
                if (op.equals("function") && (column == 1 || column == 2)) {
                    setBackground(new Color(190,171,210));
                }
            }

            super.getTableCellRendererComponent(table, value, selected, focused, row, column);

            return this;
        }
    }

  /**
   * Displays a confirmation window asking the user permission to
   * use built-in vm functions
   */
    @Override
  public boolean confirmBuiltInAccess() {
    String message =
      "No implementation was found for some functions which are called in the VM code.\n" +
      "The VM Emulator provides built-in implementations for the OS functions.\n" +
      "If available, should this built-in implementation be used for functions which were not implemented in the VM code?";
    return (JOptionPane.showConfirmDialog(this.getParent(),
                        message,
                        "Confirmation Message",
                        JOptionPane.YES_NO_OPTION,
                        JOptionPane.QUESTION_MESSAGE) ==
        JOptionPane.YES_OPTION);
  }

  /**
   * Displays a notification window with the given message.
   */
    @Override
  public void notify(String message) {
    JOptionPane.showMessageDialog(this.getParent(),
                    message,
                    "Information Message",
                    JOptionPane.INFORMATION_MESSAGE);
  }
}
TOP

Related Classes of SimulatorsGUI.ProgramComponent$ProgramTableModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.