package de.javasoft.synthetica.democenter.examples.jypropertytable;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.Font;
import java.lang.reflect.Method;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import de.javasoft.swing.JYPropertyTable;
import de.javasoft.swing.table.PropertyTableModel;
import de.javasoft.swing.table.TableSeparator;

/**
 * Demonstrates how to use a JYPropertyTable.
 */
@SuppressWarnings("serial")
public class SimpleJYPropertyTable extends JFrame
{
  private JLabel testLabel;
  
  public SimpleJYPropertyTable()
  {
    super("Simple JYPropertyTable");
    createAndAddComponents(getContentPane());

    //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setSize(400,300);
    setLocationRelativeTo(null);
    setVisible(true);
  }

  /**
   * Create components and add them to the container.
   */
  private void createAndAddComponents(final Container container)
  {
    testLabel = new JLabel("TestLabel");
    testLabel.setBorder(new EmptyBorder(10,10,10,10));    
    testLabel.setOpaque(true);
    testLabel.setBackground(new Color(0xBFFFFF));
    testLabel.setForeground(new Color(0x202020));
    testLabel.setFont(new Font("Dialog", Font.PLAIN, 20));
    container.add(testLabel, BorderLayout.NORTH);
    
//@highlight
    JYPropertyTable table = new JYPropertyTable();
    //set custom model to make row #3 non-editable, Note: separator counts as row too
    /*table.setModel(new DefaultPropertyTableModel(){
      @Override
      public boolean isCellEditable(int rowIndex, int columnIndex)
      {
        if (rowIndex == 3)
          return false;
        return super.isCellEditable(rowIndex, columnIndex);
      }
    });*/
    //add listener to update testLabel properties
    table.getModel().addTableModelListener(new ModelListener());
    //add data to the table
    initTable(table);
//@/highlight

    //workaround to avoid border fallback to default scrollpane-border after a LAF switch - Java 1.5/JTable bug.
    JScrollPane scrollPane = new JScrollPane(table){
      @Override
      public void updateUI()
      {
        super.updateUI();
        setBorder(UIManager.getBorder("Table.scrollPaneBorder"));
      }
    };
    container.add(scrollPane);    
  }

  private void initTable(JYPropertyTable table)
  {
    table.addProperty("Text", testLabel.getText());
    table.addProperty("Font", testLabel.getFont());
    table.addSeparator();
    table.addProperty("Foreground", testLabel.getForeground());
    table.addProperty("Background", testLabel.getBackground());    
    table.addProperty("Opaque", testLabel.isOpaque());
    table.addSeparator();
    table.addProperty("HorizontalAlignment", testLabel.getHorizontalAlignment());
    table.addProperty("PreferredSize", testLabel.getPreferredSize());    
    table.addProperty("Visible", testLabel.isVisible());    
  }
  
  /**
   * Static main method for application startup. 
   */
  public static void main(String[] args)
  {
    EventQueue.invokeLater(new Runnable()
    {
      public void run()
      {
        try
        {
          UIManager.setLookAndFeel("de.javasoft.plaf.synthetica.SyntheticaStandardLookAndFeel");
          new SimpleJYPropertyTable();
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
    });
  }
  
  //
  //TableListener Class to apply testLabel settings
  //
  private class ModelListener implements TableModelListener
  {      
    public void tableChanged(TableModelEvent evt)
    {
      if (evt.getColumn() == 0)
        return;
      
      int row = evt.getFirstRow();
      PropertyTableModel model = (PropertyTableModel)evt.getSource();
      Object val = model.getPropertyValue(row);

      if (val instanceof TableSeparator)
        return;

      //set value via reflection 
      try
      {
        Class<?> clazz = val.getClass();
        if (val instanceof Boolean)
          clazz = boolean.class;
        else if (val instanceof Integer)
          clazz = int.class;
        Method m = testLabel.getClass().getMethod("set"+model.getPropertyKey(row), clazz);
        m.invoke(testLabel, val);
      }
      catch (Exception e)
      {
        //throw new RuntimeException(e);
      }
      
      testLabel.revalidate();
      testLabel.repaint();
    }
  }
}
