package lecture.swing;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
/**
 *   JTableのサンプルプログラム<br>
 *   <ul>
 *   <li>一行ごとに色を変える<br>
 *   <li>セルにチェックボックスを入れる<br>
 *   <li>セルにコンボボックスを入れる<br>
 *   <li>テーブルの内容を表示する<br>
 *   <li>行を追加する<br>
 *   <li>選択されている行を削除する<br>
 *   </ul>
 *   本プログラムの技術的要素は以下のとおり.
 *   <ul>
 *   <li> セルエディタ、セルレンダラを設定することにより、JTableのセルの動作を変更する.これにより以下の機能を実現した
 *      <ul>
 *      <li> 一行ごとに色を変える
 *      <li> セルにチェックボックスを入れる
 *      <li> セルにコンボボックスを入れる
 *      </ul>
 *   <li> DefaultTableModelを使ってJTableに表示するデータを作成する.DefaultTableModelのデータを更新することにより、JTableの表示が自動的に更新される
 *      <ul>
 *      <li> 行の追加・削除が行える
 *      <li> セルのデータの変更が自動的に反映される
 *      </ul>
 *   </ul>
 */
class TableTest0 extends JFrame  {
  /**メインメソッド */
  public static void main(String[] args) {
    new TableTest0("JTableSample");
  }
  /** コンストラクタ. */
  private TableTest0(String title) {
    super(title);
    setLayout(new BorderLayout());
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // テーブルモデル作成
    MyTableModel tableModel = new MyTableModel();
    // JTable 作成
    final JTable jtable = new JTable(tableModel);
    // 行の高さを設定する
    jtable.setRowHeight(20);
    // セルの幅を設定する
    //jtable.getColumnModel().getColumn(0).setPreferredWidth(25);
    jtable.getColumnModel().getColumn(0).setMaxWidth(25);
    // フラグにセルエディタとセルレンダラをセルエディタを設定する
    {
      // セルエディタの設定
      DefaultCellEditor editor = new DefaultCellEditor(new JCheckBox());
      jtable.getColumnModel().getColumn(0).setCellEditor(editor);
      // セルレンダラの設定
      FlagRenderer renderer = new FlagRenderer();
      jtable.getColumnModel().getColumn(0).setCellRenderer(renderer);
    }
    // 名前にレンダラを設定する
    {
      NameRenderer renderer = new NameRenderer();
      jtable.getColumnModel().getColumn(1).setCellRenderer(renderer);
    }
    // 所属にセルエディタとセルレンダラを設定する
    {
      // セルエディタの設定
      DefaultCellEditor editor = new DefaultCellEditor(new BranchList());
      jtable.getColumnModel().getColumn(2).setCellEditor(editor);
      // セルレンダラの設定
      BranchRenderer renderer = new BranchRenderer();
      jtable.getColumnModel().getColumn(2).setCellRenderer(renderer);
    }
    //
    // テーブルを画面に追加する
    JScrollPane pane = new JScrollPane(jtable);
    add(pane,BorderLayout.CENTER);
    // 表示用のボタン
    JButton dispButton = new JButton("表示");
    dispButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            // モデルを取得する
            MyTableModel model = (MyTableModel)jtable.getModel();
            System.out.println("== テーブルの内容 ==");
            // 一行ずつ取り出して内容を表示する.
            for (int row=0; row<model.getRowCount(); row++) {
              Boolean flag = (Boolean)model.getValueAt(row,0);
              String name = (String)model.getValueAt(row,1);
              String branch = (String)model.getValueAt(row,2);
              System.out.println(row+":"+flag+":"+name+":"+branch);
            }
          }
        }
    );
    // 追加用のボタン
    JButton addButton= new JButton("追加");
    addButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            // モデルを取得する
            MyTableModel model = (MyTableModel)jtable.getModel();
            // データを追加する
            model.addRow(new Object[]{new Boolean(true),"大橋","東京"});
          }
        }
    );
    // 削除用のボタン
    JButton delButton = new JButton("削除");
    delButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            // 選択されている行
            int row = jtable.getSelectedRow();
            // 選択されていないときは戻る
            if (row < 0) {
              return;
            }
            // モデルを取得する
            MyTableModel model = (MyTableModel)jtable.getModel();
            // 指定行を削除する
            model.removeRow(row);
          }
        }
    );

    // ボタンを画面に設定する
    JPanel buttonPanel = new JPanel(new FlowLayout());
    buttonPanel.add(dispButton);
    buttonPanel.add(addButton);
    buttonPanel.add(delButton);
    add(buttonPanel,BorderLayout.SOUTH);
    // 表示
    pack();
    setVisible(true);
  }

  /**
   * フラグのレンダラ
   */
    public class FlagRenderer extends JCheckBox   implements TableCellRenderer {
         public Component getTableCellRendererComponent(
             JTable table, Object value, boolean isSelected, boolean hasFocus, int  row,  int column) {
           if (Boolean.TRUE.equals((Boolean)value)) {
             // チェックされているとき
             setSelected(true);
           }
           else {
             // チェックされていないとき
             setSelected(false);
           }
           setBackground(getBackColor(row));
           return this;
          }
       }

  /**
   * 支社リストコンボボックス
   */
  private class BranchList extends JComboBox {
    public BranchList() {
      super(new String[] {"札幌","仙台","東京","名古屋","大阪","広島","福岡"});
    }
  }
  /**
   * 支社のレンダラ
   */
    public class BranchRenderer extends BranchList   implements TableCellRenderer {
       public Component getTableCellRendererComponent(
           JTable table, Object value, boolean isSelected, boolean hasFocus, int  row,  int column) {
         // 選択されている値を設定する
         setSelectedItem(value);
         setBackground(getBackColor(row));
         return this;
        }
     }
    /**
     * 名前のレンダラ
     */
    public class NameRenderer extends DefaultTableCellRenderer  implements TableCellRenderer {
         public Component getTableCellRendererComponent(
             JTable table, Object value, boolean isSelected, boolean hasFocus, int  row,  int column) {
           // 値をそのまま設定する
           setText((String)value);
             setBackground(getBackColor(row));
           return this;
          }
       }

    /**
     * テーブルモデル
     */
    private class MyTableModel extends DefaultTableModel {
      public MyTableModel() {
        super(new String[]{"フラグ","名前","所属"},0);
        for (int i=0; i<myModelData.length; i++) {
          addRow(myModelData[i]);
        }
      }
    }
  /**
   * テーブル設定用のデータ
   */
  private static Object[][] myModelData;
  private static final int ROW = 5;
  private static final int COL = 3;
  static {
    myModelData = new Object[ROW][COL];
    for (int i=0; i<ROW; i++) {
      myModelData[i][0] = new Boolean(false);
      myModelData[i][1] = "name-"+i;
      myModelData[i][2] = "札幌";
    }
  };

  /**
   * 背景色を戻す
   */
  private static Color getBackColor(int row) {
    if (row % 2 == 0){
      return Color.white;
    }
    else {
      return new Color(238, 232, 170);
    }
  }
}