/*
 * NetworkLocationsPanel.java
 *
 * Created on January 10, 2005, 10:40 AM
 */

package DDMT.core;

import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.lang.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import javax.swing.DefaultListModel;
import DDMT.core.*;
import DDMT.Nodes.*;
/**
 *
 * @author  John Kloetzli
 */

public class DynamicMonitoringPanel extends DDMT.core.DefaultPanel {

    //List model for the node monitoring selection list
    private DefaultListModel nodeMonitoringModel;
    
    //Pattern for a node definition
    //Node Number, Network Location, Data Location, Node Type, X-value, Y-value, Neighbor1, Neighbor1 delay, Neighbor2, ...
    private Pattern nodePattern = Pattern.compile("\\d+\\s\\S+\\s\\S+\\s\\S+\\s\\d+\\s\\d+\\s[\\d+\\s\\d+\\p{Punct}\\d+\\s]*");
    private Matcher nodeMatcher;
    
    //The standard group of patterns from the other panels
    private Pattern integerP = Pattern.compile("\\d+");
    private Pattern doubleP = Pattern.compile("\\d+\\p{Punct}\\d+");
    private Pattern stringP = Pattern.compile("\\S+\\s");
    private Pattern alphaStringP = Pattern.compile("[a-zA-Z]\\S*");
    private Pattern neighborP = Pattern.compile("\\s\\d+\\s\\d+\\p{Punct}\\d+");
    private Pattern fileP = Pattern.compile("\\S+\\s\\S+");
    private Pattern firstP = Pattern.compile("\\A(\\S+)");
    private Pattern nextP = Pattern.compile("\\s(\\S+)");
    private Pattern lastP = Pattern.compile("\\S+\\Z");
    private Matcher fileM;
    private Matcher firstM;
    private Matcher nextM;
    private Matcher lastM;
    private Matcher integerM;
    private Matcher doubleM;
    private Matcher stringM;
    private Matcher alphaStringM;
    private Matcher neighborM;
    
    /** Creates new form NetworkLocationsPanel */
    public DynamicMonitoringPanel(DDMT.core.MainPanel.ControlClass cClass) {
        initComponents();
        
        controlClass = cClass;
        
        //Set the name of this panel for the main window's tab pane
        this.setName("Local Monitoring");
    }
    
    /**
     *Method to refresh the panel
     */
    public void refresh()
    {
        //Make sure that the project has been selected
        if( controlClass.getProjectName() == null)
        {
            controlClass.showError("Dynamic Monitoring: Error: No project selected!");
            return;
        }
        //See if there is a dynamic monitoring file already
        else if( new File("Files\\Projects\\"+controlClass.getProjectName()+"\\monitoring.txt").exists() )
        {
            File file = null;
            try{
                //Set up the file and the readers
                file = new File("Files\\Projects\\"+controlClass.getProjectName()+"\\monitoring.txt");
                FileReader reader = new FileReader(file);
                BufferedReader bReader = new BufferedReader(reader);
                
                //Read the number of lines
                int numLines = Integer.parseInt(bReader.readLine());
                if(numLines != controlClass.nodes.length)
                {
                    throw new Exception("Dynamic Monitoring: Error: File "+file.getPath()+" is in the wrong format!");
                }
                
                //read the file
                String line = bReader.readLine();
                
                String output = null;
                for(int i = 0; i< controlClass.nodes.length; i++)
                {
                    
                }
            }catch(IOException ex)
            {
                controlClass.showError("Dynamic Monitoring: Error: Could not read file "+file.getPath());
            }catch(Exception ex)
            {
                controlClass.showError(ex.getMessage());
            }
        }
        //See if the control class nodes array is loaded
        else if( controlClass.nodes == null )
        {
            try{
                //load the nodes
                this.loadNodes();
            }catch(Exception ex)
            {
                controlClass.showError("Dynamic Monitoring: Error: Please load a topology.");
            }
            this.setUpModel();
        }
        //If all else fails then set up a new list.
        else
        {   
            this.setUpModel();
        }
    }
    
    /**
     *Method to set up the model from the nodes
     */
    private void setUpModel()
    {
        //Loop for each node
        try{
            nodeMonitoringModel = new DefaultListModel();
            for( int i = 0; i< controlClass.nodes.length ; i++)
            {
                nodeMonitoringModel.addElement(new String[]{ 
                    controlClass.nodes[i].getNumber()+" ("
                    +controlClass.nodes[i].getType()+")", "None"});
            }
            jList1.setCellRenderer(new DoubleCellRenderer());
            jList1.setModel(nodeMonitoringModel);
        }catch(NullPointerException ex)
        {
            ex.printStackTrace();
        }
    }
    
    /**
     *Method to load the nodes into the system
     */
    private void loadNodes()
    {
        //Open the Nodes.txt file
        File nodesFile = null;

        nodesFile = new File("Files\\Projects\\" + controlClass.getProjectName() + "\\nodes.txt");
        
        try{
            FileReader fileReader = new FileReader(nodesFile);
            BufferedReader bReader = new BufferedReader(fileReader);
            //Read the number of nodes

            String line = bReader.readLine();
            if( line == null )
            {
                controlClass.showError("Agent Types: Error: Could not read file "+nodesFile.getPath()+".");
                throw new IOException();
            }
            controlClass.nodes = new Node[Integer.parseInt(line)];
            line = bReader.readLine();
            
            //Loop for each line read.
            int i = 0;
            while( line != null )
            {
                nodeMatcher = nodePattern.matcher(line);
                if( nodeMatcher.matches() )
                {
                    //Set up the matchers
                    integerM = integerP.matcher(line);
                    doubleM = doubleP.matcher(line);
                    alphaStringM = alphaStringP.matcher(line);
                    neighborM = neighborP.matcher(line);
                    
                    //Read in the node.
                    Node node = new Node();
                    integerM.find();
                    node.setNumber(Integer.parseInt(integerM.group()));
                    alphaStringM.find();
                    node.setNetworkLocation(alphaStringM.group());
                    alphaStringM.find();
                    String dataLocation = new String(alphaStringM.group());
                    node.setDataLocation(dataLocation);
                    alphaStringM.find();
                    node.setType(alphaStringM.group());
                    integerM.find();
                    node.setX(Integer.parseInt(integerM.group()));
                    integerM.find();
                    node.setY(Integer.parseInt(integerM.group()));

                    //Load the neighbors
                    while( neighborM.find() )
                    {
                        String neighbor = new String( neighborM.group() );
                        integerM = integerP.matcher(neighbor);
                        doubleM = doubleP.matcher(neighbor);
                        Neighbor nodeNeighbor = new Neighbor();
                        integerM.find();
                        nodeNeighbor.setNumber(Integer.parseInt(integerM.group()));
                        doubleM.find();
                        nodeNeighbor.setDelay(Double.parseDouble(doubleM.group()));
                        node.addNeighbor(nodeNeighbor);       
                    }
                    //Add node to nodes list
                    controlClass.nodes[i] = node;
            
                    i++;
                }
                line = bReader.readLine();
            }
            
            //Close the files
            bReader.close();
            fileReader.close();
        }catch(IOException ex)
        {
            controlClass.showError("Data Import: Error: Could not read file "+nodesFile.getPath());
        }
    }
    
    /**
     *Method to write the list out to a file
     */
    private void export(File f)
    {
        try
        {
            //Open the file
            File file = new File(f.getPath());
            FileWriter writer = new FileWriter(file);
            BufferedWriter bWriter = new BufferedWriter(writer);    
            
            //Write the number of elements
            bWriter.write((String)(""+nodeMonitoringModel.getSize()));
            bWriter.newLine();
            
            //Loop for each element in the list
            String line = new String();
            for( int i = 0; i< this.nodeMonitoringModel.getSize(); i++)
            {
                //Set up the matchers
                String input1 = ((String[])nodeMonitoringModel.elementAt(i))[0];
                String input2 = ((String[])nodeMonitoringModel.elementAt(i))[1];
                firstM = firstP.matcher(input1);

                //Parse each element into it's part
                firstM.find();
                line = new String(firstM.group()) +" "+ input2;
                
                bWriter.write(line);
                bWriter.newLine();
            }
            
            //Close the writers
            bWriter.flush();
            writer.close();
            bWriter.close();
        }catch(IOException ex)
        {
            controlClass.showError("Dynamic Monitoring: ");
        }
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {//GEN-BEGIN:initComponents
        jPanel1 = new javax.swing.JPanel();
        jButton1 = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        jPanel3 = new javax.swing.JPanel();
        jPanel10 = new javax.swing.JPanel();
        jPanel11 = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        jPanel12 = new javax.swing.JPanel();
        jPanel7 = new javax.swing.JPanel();
        jLabel5 = new javax.swing.JLabel();
        jCheckBox4 = new javax.swing.JCheckBox();
        jPanel4 = new javax.swing.JPanel();
        jPanel5 = new javax.swing.JPanel();
        jPanel6 = new javax.swing.JPanel();
        jPanel8 = new javax.swing.JPanel();
        jPanel9 = new javax.swing.JPanel();
        jPanel15 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        jList1 = new javax.swing.JList();
        jPanel20 = new javax.swing.JPanel();
        jButton3 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();
        jPanel21 = new javax.swing.JPanel();
        jPanel16 = new javax.swing.JPanel();
        jPanel14 = new javax.swing.JPanel();
        jPanel17 = new javax.swing.JPanel();
        jPanel18 = new javax.swing.JPanel();
        jPanel19 = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        jCheckBox1 = new javax.swing.JCheckBox();
        jPanel13 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();

        jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 5, 0));

        jPanel1.setPreferredSize(new java.awt.Dimension(25, 25));
        jPanel1.setMaximumSize(new java.awt.Dimension(25, 25));
        jPanel1.setMinimumSize(new java.awt.Dimension(25, 25));
        jButton1.setText("Save");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jPanel1.add(jButton1);

        add(jPanel1, java.awt.BorderLayout.SOUTH);

        jPanel2.setLayout(new javax.swing.BoxLayout(jPanel2, javax.swing.BoxLayout.Y_AXIS));

        jPanel3.setLayout(new java.awt.BorderLayout());

        jPanel3.add(jPanel10, java.awt.BorderLayout.EAST);

        jLabel3.setText("Dynamic Global Monitoring");
        jPanel11.add(jLabel3);

        jPanel3.add(jPanel11, java.awt.BorderLayout.NORTH);

        jPanel3.add(jPanel12, java.awt.BorderLayout.WEST);

        jPanel7.setLayout(new javax.swing.BoxLayout(jPanel7, javax.swing.BoxLayout.Y_AXIS));

        jPanel7.setBorder(new javax.swing.border.EtchedBorder());
        jPanel7.setMaximumSize(new java.awt.Dimension(80000, 80000));
        jLabel5.setText("Global Monitoring Types");
        jPanel7.add(jLabel5);

        jCheckBox4.setText("Launch Network Monitoring GUI");
        jCheckBox4.setToolTipText("Selects to launch a GUI that allows viewing of network message loads in realtime");
        jPanel7.add(jCheckBox4);

        jPanel3.add(jPanel7, java.awt.BorderLayout.CENTER);

        jPanel2.add(jPanel3);

        jPanel4.setLayout(new java.awt.BorderLayout());

        jPanel4.add(jPanel5, java.awt.BorderLayout.EAST);

        jPanel4.add(jPanel6, java.awt.BorderLayout.WEST);

        jPanel4.add(jPanel8, java.awt.BorderLayout.SOUTH);

        jPanel9.setLayout(new javax.swing.BoxLayout(jPanel9, javax.swing.BoxLayout.X_AXIS));

        jPanel9.setBorder(new javax.swing.border.EtchedBorder());
        jPanel15.setLayout(new java.awt.BorderLayout());

        jLabel1.setText("Node Monitoring Selections");
        jPanel15.add(jLabel1, java.awt.BorderLayout.NORTH);

        jList1.setToolTipText("Shows the current nodes selected to show the local GUI");
        jScrollPane1.setViewportView(jList1);

        jPanel15.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jButton3.setText("Set");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        jPanel20.add(jButton3);

        jButton2.setText("Export");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        jPanel20.add(jButton2);

        jButton4.setText("Import");
        jButton4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton4ActionPerformed(evt);
            }
        });

        jPanel20.add(jButton4);

        jPanel15.add(jPanel20, java.awt.BorderLayout.SOUTH);

        jPanel9.add(jPanel15);

        jPanel9.add(jPanel21);

        jPanel16.setLayout(new java.awt.BorderLayout());

        jPanel16.add(jPanel14, java.awt.BorderLayout.EAST);

        jPanel16.add(jPanel17, java.awt.BorderLayout.NORTH);

        jPanel16.add(jPanel18, java.awt.BorderLayout.SOUTH);

        jPanel19.setLayout(new javax.swing.BoxLayout(jPanel19, javax.swing.BoxLayout.Y_AXIS));

        jPanel19.setBorder(new javax.swing.border.EtchedBorder());
        jPanel19.setPreferredSize(new java.awt.Dimension(50, 150));
        jPanel19.setMinimumSize(new java.awt.Dimension(50, 150));
        jLabel4.setText(" Local Monitoring Types");
        jPanel19.add(jLabel4);

        jCheckBox1.setText("Local Monitoring GUI");
        jCheckBox1.setToolTipText("Selects to start the selected node with a local GUI that shows information from that node");
        jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox1ActionPerformed(evt);
            }
        });

        jPanel19.add(jCheckBox1);

        jPanel16.add(jPanel19, java.awt.BorderLayout.CENTER);

        jPanel9.add(jPanel16);

        jPanel4.add(jPanel9, java.awt.BorderLayout.CENTER);

        jLabel2.setText("Dynamic Local Monitoring");
        jLabel2.setIcon(new javax.swing.ImageIcon("D:\\John\\Leap\\DDMT\\Files\\Core\\Icons\\go.ico"));
        jPanel13.add(jLabel2);

        jPanel4.add(jPanel13, java.awt.BorderLayout.NORTH);

        jPanel2.add(jPanel4);

        add(jPanel2, java.awt.BorderLayout.CENTER);

    }//GEN-END:initComponents

    /**
     *Method for 'Save' clicked
     */
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        //Make sure that there is a project open
        File file = null;
        try
        {
            file = new File("Files\\Projects\\"+controlClass.getProjectName()+"\\GlobalMonitoring.txt");
        }catch(NullPointerException ex)
        {
            controlClass.showError("Dynamic Monitoring: Error: No project selected!");
            return;
        }
        
        //Write the global monitoring control file
        try
        {
            //open the streams
            FileWriter writer = new FileWriter(file);
            BufferedWriter bWriter = new BufferedWriter(writer);
            
            /*Write the global data in the following format:
             *(global, none) 
             *where either global or none is written to the file in that posiiton, etc.
             *with global representing global GUI selected in the panel.
             */
            if( jCheckBox4.isSelected() )
            {
                bWriter.write(new String("global"));
            }else
            {
                bWriter.write(new String("none"));
            }
            bWriter.flush();
            bWriter.close();
            writer.close();
        }catch(IOException ex)
        {
            controlClass.showError("Dynamic Monitoring: Error: Could not save data!");
        }
        
        //Write the local monitoring data in the same format as export.
        file = new File("Files\\Projects\\"+controlClass.getProjectName()+"\\LocalMonitoring.txt");
        this.export(file);
            
    }//GEN-LAST:event_jButton1ActionPerformed

    /**
     *Method for 'Import' clicked
     */
    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed
        //make sure that the nodes have been inputted
        
        
        //get the file to import
        //Show a file chooser 
        JFileChooser fc = new JFileChooser();
        int returnVal = fc.showOpenDialog(this.getParent());
        
        //Get the return file, if applicable
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            
            try{
                //open the streams
                FileReader reader = new FileReader(file);
                BufferedReader bReader = new BufferedReader(reader);
                
                //Read the number of lines
                int numLines = Integer.parseInt(bReader.readLine());
                if( numLines != controlClass.nodes.length )
                {
                    controlClass.showError("Dynamic Monitoring: Error: No topology information available!");
                    return;
                }
                
                //Reset the model
                nodeMonitoringModel = new DefaultListModel();
                
                //Read in the rest of the lines and parse them
                String line = new String();
                String output = new String();
                for( int i = 0; i< numLines; i++ )
                {
                    //Read the line and seed the matchers
                    line = bReader.readLine();
                    firstM = firstP.matcher(line);
                    nextM = nextP.matcher(line);
                    
                    //Put the node number in the string
                    firstM.find();
                    output = new String();
                    String first = new String(""+Integer.parseInt(firstM.group())+" ("+controlClass.nodes[Integer.parseInt(firstM.group())].getType()+")");
                    
                    while(nextM.find())
                    {
                        output = output + " "+nextM.group();
                    }
                    nodeMonitoringModel.addElement(new String[]{first, output});
                }
                jList1.setCellRenderer(new DoubleCellRenderer());
                jList1.setModel(nodeMonitoringModel);
            }catch( Exception ex)
            {
                controlClass.showError("Dynamic Monitoring: Error: File "+file.getPath()+" is not in the correct format!");
            }
        }
    }//GEN-LAST:event_jButton4ActionPerformed

    /**
     *Method for 'Export' clicked
     */
    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        //Get the file to export to
        //Show a file chooser 
        JFileChooser fc = new JFileChooser();
        int returnVal = fc.showSaveDialog(this.getParent());
        
        File file = null;
        try{
            //Get the return file, if applicable
            if (returnVal == JFileChooser.APPROVE_OPTION) 
	    {
                file = fc.getSelectedFile();
                file.createNewFile();
                this.export(file);
            }
        }catch( IOException ex)
        {
            controlClass.showError("Dynamic Monitoring: Error: Could not open file "+file.getPath());
        }
    }//GEN-LAST:event_jButton2ActionPerformed

    /**
     *Method for 'Set' clicked
     */
    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
        //Loop for each line selected
        int[] indices = jList1.getSelectedIndices();
        for( int i = 0; i< indices.length; i++)
        {
            //Get the first part of the line
            boolean something = false;
            firstM = firstP.matcher(((String[])nodeMonitoringModel.getElementAt(indices[i]))[0]);
            firstM.find();
            String line = new String();
            String first = firstM.group()+ " ("+ controlClass.nodes[Integer.parseInt(firstM.group())].getType()+")";
            
            //Add the line for the local GUI selected
            if( jCheckBox1.isSelected() )
            {
                something = true;
                line = line + "Local_GUI";
            }

            //If nothing is selected, then say that
            if( !something )
            {
                line = line + "None";
            }
            
            //Replace the line
            nodeMonitoringModel.setElementAt(new String[]{first, line}, indices[i]);
        }
    }//GEN-LAST:event_jButton3ActionPerformed

    private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox1ActionPerformed

    }//GEN-LAST:event_jCheckBox1ActionPerformed
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JCheckBox jCheckBox1;
    private javax.swing.JCheckBox jCheckBox4;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JList jList1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel10;
    private javax.swing.JPanel jPanel11;
    private javax.swing.JPanel jPanel12;
    private javax.swing.JPanel jPanel13;
    private javax.swing.JPanel jPanel14;
    private javax.swing.JPanel jPanel15;
    private javax.swing.JPanel jPanel16;
    private javax.swing.JPanel jPanel17;
    private javax.swing.JPanel jPanel18;
    private javax.swing.JPanel jPanel19;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel20;
    private javax.swing.JPanel jPanel21;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel4;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JPanel jPanel9;
    private javax.swing.JScrollPane jScrollPane1;
    // End of variables declaration//GEN-END:variables
    
    /**
     *Cell renderer for the list.  Shows two strings seperated by a two-way arrow.
     */
    public class DoubleCellRenderer extends JPanel implements ListCellRenderer {
            
        //The left label
        JLabel left;
        
        //The right label
        JLabel right;
        
        //the center label
        JLabel center;
        
        /**
         *Method to create a new cell renderer
         */
        DoubleCellRenderer() 
        {
            setLayout( new GridLayout());
            left = new JLabel();
            right = new JLabel();
            center = new JLabel();
            left.setOpaque(true);
            right.setOpaque(true);
            center.setOpaque(true);
            add(left);
            add(center);
            add(right);
        }
      
        /**
         *Method to get one component of the cell renderer
         */
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) 
        {
            //The first string
            String leftS = ((String[])value)[0];
            String rightS = ((String[])value)[1];
            left.setText(leftS);
            right.setText(rightS);
            center.setIcon(new ImageIcon("Files\\Core\\Icons\\arrow.gif"));
            
            if (isSelected) 
            {
                right.setBackground( list.getSelectionBackground());
                right.setForeground( list.getSelectionForeground());
                left.setBackground( list.getSelectionBackground());
                left.setForeground( list.getSelectionForeground());
                center.setBackground( list.getSelectionBackground());
                center.setForeground( list.getSelectionForeground());
                right.setEnabled(true);
                left.setEnabled(true);
                center.setEnabled(true);
            } else {
                right.setBackground(list.getBackground());
                right.setForeground(list.getForeground());
                left.setBackground(list.getBackground());
                left.setForeground(list.getForeground());
                center.setBackground(list.getBackground());
                center.setForeground(list.getForeground());
                right.setEnabled(true);
                left.setEnabled(true);
                center.setEnabled(true);
            }
            
            if( !list.isEnabled() )
            {
                right.setBackground(list.getBackground());
                right.setEnabled(false);
                left.setBackground(list.getBackground());
                left.setEnabled(false);
                center.setBackground(list.getBackground());
                center.setEnabled(false);
            }
            
            setEnabled(list.isEnabled());
            setFont(list.getFont());
            return this;
        }
    }
}
