Package net.geco.ui.tabs

Source Code of net.geco.ui.tabs.RunnersTableModel

/**
* Copyright (c) 2009 Simon Denier
* Released under the MIT License (see LICENSE file)
*/
package net.geco.ui.tabs;

import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import java.util.List;
import java.util.Vector;

import javax.swing.AbstractCellEditor;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.border.LineBorder;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;

import net.geco.control.RunnerControl;
import net.geco.framework.IGeco;
import net.geco.model.Course;
import net.geco.model.Messages;
import net.geco.model.Registry;
import net.geco.model.Runner;
import net.geco.model.RunnerRaceData;
import net.geco.model.Status;


/**
* @author Simon Denier
* @since Jan 24, 2009
*
*/
public class RunnersTableModel extends AbstractTableModel {

  private static final int NUMBER_WIDTH = 50;
  private static final int FIELD_WIDTH = 70;
  private static final int NAME_WIDTH = 100;

  private IGeco geco;
  private String[] headers;
  private List<RunnerRaceData> data;

  private int clickCountToEdit;
  private boolean useDefaultCourseForCategory;
  private DefaultCellEditor categoryEditor;
  private DefaultCellEditor courseEditor;
  private DefaultCellEditor clubEditor;
  private DefaultCellEditor statusEditor;

 
  public RunnersTableModel(IGeco geco) {
    this.geco = geco;
    this.headers = new String[] {
        Messages.uiGet("RunnersTableModel.StartHeader"), //$NON-NLS-1$
        Messages.uiGet("RunnersTableModel.EcardHeader"), //$NON-NLS-1$
        Messages.uiGet("RunnersTableModel.FirstnameHeader"), //$NON-NLS-1$
        Messages.uiGet("RunnersTableModel.LastnameHeader"), //$NON-NLS-1$
        Messages.uiGet("RunnersTableModel.CategoryHeader"), //$NON-NLS-1$
        Messages.uiGet("RunnersTableModel.CourseHeader"), //$NON-NLS-1$
        Messages.uiGet("RunnersTableModel.ClubHeader"), //$NON-NLS-1$
        Messages.uiGet("RunnersTableModel.TimeHeader"), //$NON-NLS-1$
        Messages.uiGet("RunnersTableModel.StatusHeader"), //$NON-NLS-1$
    };
    this.data = new Vector<RunnerRaceData>();
    this.clickCountToEdit = 2;
    this.useDefaultCourseForCategory = false;
  }
 
  private RunnerControl control() {
    return geco.runnerControl();
  }
 
  private Registry registry() {
    return geco.registry();
  }

  public int getColumnCount() {
    return headers.length;
  }
 
  @Override
  public String getColumnName(int column) {
    return this.headers[column];
  }

  public List<RunnerRaceData> getData() {
    return data;
  }

  public void setData(List<RunnerRaceData> data) {
    this.data = data;
    fireTableDataChanged();
  }

  public void addDataFirst(RunnerRaceData data) {
    this.data.add(0, data);
    fireTableRowsInserted(0, 0);
  }

  public void addData(RunnerRaceData data) {
    this.data.add(data);
    fireTableRowsInserted(this.data.size() - 1, this.data.size() - 1);
  }

  public void removeData(RunnerRaceData data) {
    int deleted = this.data.indexOf(data);
    this.data.remove(data);
    fireTableRowsDeleted(deleted, deleted);
  }

 
  public int getRowCount() {
    return data.size();
  }

  private RunnerRaceData getRunnerData(int rowIndex) {
    return data.get(rowIndex);
  }

  private Runner getRunner(int rowIndex) {
    return getRunnerData(rowIndex).getRunner();
  }
 
 
  public Object getValueAt(int rowIndex, int columnIndex) {
    Runner runner = getRunner(rowIndex);
    switch (columnIndex) {
    case 0: return runner.getStartId();
    case 1: return runner.getEcard();
    case 2: return runner.getFirstname();
    case 3: return runner.getLastname();
    case 4: return runner.getCategory().getShortname();
    case 5: return runner.getCourse().getName();
    case 6: return runner.getClub().getName();
    case 7: return getRunnerData(rowIndex).getResult().formatRacetime();
    case 8: return getRunnerData(rowIndex).getResult().getStatus();
    default: return "Pbm"; //$NON-NLS-1$
    }
  }

  @Override
  public Class<?> getColumnClass(int columnIndex) {
    switch (columnIndex) {
    case 0: return Integer.class;
    case 1: return Integer.class;
    case 2: return String.class;
    case 3: return String.class;
    case 4: return String.class;
    case 5: return String.class;
    case 6: return String.class;
    case 7: return String.class;
    case 8: return Status.class;
    default: return Object.class;
    }
  }
 
  public void initTableColumnSize(JTable table) {
    TableColumnModel model = table.getColumnModel();
    for (int i = 0; i < headers.length; i++) {
      int width = 0;
      switch (i) {
      case 0: width = NUMBER_WIDTH ; break;
      case 1: width = FIELD_WIDTH ;break;
      case 2: width = NAME_WIDTH ;break;
      case 3: width = NAME_WIDTH ;break;
      case 4: width = FIELD_WIDTH ;break;
      case 5: width = FIELD_WIDTH ;break;
      case 6: width = FIELD_WIDTH ;break;
      case 7: width = FIELD_WIDTH ;break;
      case 8: width = FIELD_WIDTH ;break;
      default: break;
      }
      model.getColumn(i).setPreferredWidth(width);
    }
  }
 
  public class RacetimeCellRenderer extends JLabel implements TableCellRenderer {
    public RacetimeCellRenderer() {
      setOpaque(true);
    }
    @Override
    public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row,
        int column) {
      setHorizontalAlignment(RIGHT);
      setText(value.toString());
      if( isSelected ) {
        setBackground(table.getSelectionBackground());
        setForeground(table.getSelectionForeground());
      } else {
        setBackground(null);
        setForeground(null);
      }
      return this;
    }
  }
 
  public static class StatusCellRenderer extends JLabel implements TableCellRenderer {
    public StatusCellRenderer() {
      setOpaque(true);
    }
    @Override
    public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row,
        int column) {
      setBackground( ((Status) value).color() );
      setHorizontalAlignment(CENTER);
      setText(value.toString());
      return this;
    }
  }

  public void initCellEditors(JTable table) {
    TableColumnModel model = table.getColumnModel();
    model.getColumn(0).setCellEditor(new StartIdEditor());
    model.getColumn(1).setCellEditor(new EcardEditor());
    model.getColumn(2).setCellEditor(new FirstnameEditor());
    model.getColumn(3).setCellEditor(new LastnameEditor());
    model.getColumn(7).setCellEditor(new RacetimeEditor());
    statusEditor = new DefaultCellEditor(new JComboBox(Status.values()));
    model.getColumn(8).setCellEditor(statusEditor);
    updateComboBoxEditors(table); // init cell clicks to edit

    // also init some specific cell renderers
    model.getColumn(7).setCellRenderer(new RacetimeCellRenderer());
    model.getColumn(8).setCellRenderer(new StatusCellRenderer());
  }

  protected void updateComboBoxEditors(JTable table) {
    TableColumnModel model = table.getColumnModel();
    categoryEditor = new DefaultCellEditor(new JComboBox(registry().getSortedCategoryNames().toArray()));
    model.getColumn(4).setCellEditor(categoryEditor);
    courseEditor = new DefaultCellEditor(new JComboBox(registry().getSortedCourseNames().toArray()));
    model.getColumn(5).setCellEditor(courseEditor);
    clubEditor = new DefaultCellEditor(new JComboBox(registry().getSortedClubNames().toArray()));
    model.getColumn(6).setCellEditor(clubEditor);
    // (re)set clicks for new cell editors
    setClickCountToEdit(clickCountToEdit);
  }

  @Override
  public boolean isCellEditable(int rowIndex, int columnIndex) {
    return true;
  }
 
  public void enableFastEdition() {
    setClickCountToEdit(1);
  }

  public void disableFastEdition() {
    setClickCountToEdit(2);
  }
 
  private void setClickCountToEdit(int clicks) {
    clickCountToEdit = clicks;
    categoryEditor.setClickCountToStart(clicks);
    courseEditor.setClickCountToStart(clicks);
    clubEditor.setClickCountToStart(clicks);
    statusEditor.setClickCountToStart(clicks);
  }
 
  public void enableDefaultCourseForCategory(boolean flag){
    useDefaultCourseForCategory = flag;
  }
 

  @Override
  public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
    switch (columnIndex) {
    case 0: break;
    case 1: break;
    case 2: break;
    case 3: break;
    case 4: setCategory(getRunnerData(rowIndex), (String) aValue); break;
    case 5: setCourse(getRunnerData(rowIndex), (String) aValue); break;
    case 6: setClub(getRunner(rowIndex), (String) aValue); break;
    case 7: break;
    case 8: setStatus(getRunnerData(rowIndex), (Status) aValue); break;
    default: break;
    }
  }

  private void setCategory(RunnerRaceData runnerData, String newCategory) {
    Runner runner = runnerData.getRunner();
    control().validateCategory(runner, newCategory);
    // check course even if no change in category
    if( useDefaultCourseForCategory ){
      Course catCourse = runner.getCategory().getCourse();
      if( catCourse!=null ){
        control().validateCourse(runnerData, catCourse.getName());
      }
    }
  }

  private void setCourse(RunnerRaceData runnerData, String newCourse) {
    control().validateCourse(runnerData, newCourse);
  }
 
  private void setClub(Runner runner, String newClub) {
    control().validateClub(runner, newClub);
  }
 
  private void setStatus(RunnerRaceData runnerData, Status newStatus) {
    control().validateStatus(runnerData, newStatus);
  }
 

  public abstract class RunnersTableEditor extends AbstractCellEditor implements TableCellEditor {

    protected Runner selectedRunner;
    protected JTextField editField;
   
    public RunnersTableEditor() {
      editField = new JTextField();
      editField.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
          if( validateInput() ) {
            fireEditingStopped();
          } else {
            editField.setBorder(new LineBorder(Color.red));
          }
        }
      });
    }
   
    @Override
    public boolean stopCellEditing() {
      if( validateInput() ) {
        return super.stopCellEditing();
      } else {
        editField.setBorder(new LineBorder(Color.red));
        return false;
      }
    }
   
    public abstract boolean validateInput();

    public String getValue() {
      return editField.getText();
    }

    @Override
    public Component getTableCellEditorComponent(JTable table, Object value,
        boolean isSelected, int row, int column) {
      selectedRunner = getRunner(table.convertRowIndexToModel(row));
      editField.setText((String) getCellEditorValue());
      editField.setBorder(new LineBorder(Color.black));
      return editField;
    }

    @Override
    public boolean isCellEditable(EventObject e) {
        if (e instanceof MouseEvent) {
        return ((MouseEvent) e).getClickCount() >= clickCountToEdit;
      }
        return true;
    }
   
  }


  public class StartIdEditor extends RunnersTableEditor {
    @Override
    public Object getCellEditorValue() {
      return selectedRunner.getStartId().toString();
    }
    @Override
    public boolean validateInput() {
      return control().validateStartId(selectedRunner, getValue());
    }
  }
 
  public class EcardEditor extends RunnersTableEditor {
    @Override
    public Object getCellEditorValue() {
      return selectedRunner.getEcard();
    }
    @Override
    public boolean validateInput() {
      return control().validateEcard(selectedRunner, getValue());
    }
  }

  public class FirstnameEditor extends RunnersTableEditor {
    @Override
    public Object getCellEditorValue() {
      return selectedRunner.getFirstname();
    }
    @Override
    public boolean validateInput() {
      return control().validateFirstname(selectedRunner, getValue());
    }
  }
 
  public class LastnameEditor extends RunnersTableEditor {
    @Override
    public Object getCellEditorValue() {
      return selectedRunner.getLastname();
    }
    @Override
    public boolean validateInput() {
      return control().validateLastname(selectedRunner, getValue());
    }
  }
 
  public class RacetimeEditor extends RunnersTableEditor {
    private RunnerRaceData selectedData;
    @Override
    public Object getCellEditorValue() {
      return selectedData.getResult().formatRacetime();
    }
    @Override
    public boolean validateInput() {
      return control().validateRaceTime(selectedData, getValue());
    }
    @Override
    public Component getTableCellEditorComponent(JTable table, Object value,
        boolean isSelected, int row, int column) {
      selectedData = getRunnerData(table.convertRowIndexToModel(row));
      return super.getTableCellEditorComponent(table, value, isSelected, row, column);
    }
  }
 
}
TOP

Related Classes of net.geco.ui.tabs.RunnersTableModel

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.