org.nuiton.math.matrix.gui.MatrixTableModelND Maven / Gradle / Ivy
Show all versions of nuiton-matrix Show documentation
/*##% NuitonMatrix
* Copyright (C) 2004 - 2009 CodeLutin
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* . ##%*/
package org.nuiton.math.matrix.gui;
import static org.nuiton.i18n.I18n._;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import org.nuiton.math.matrix.MatrixException;
import org.nuiton.math.matrix.MatrixND;
/**
* Extension de AbstractTableModel pour definir un TableModel avec une
* MatrixND comme support d'information.
*
* Created: 21 mars 2006 19:01:27
*
* @author poussin
* @version $Revision: 197 $
*
* Last update: $Date: 2009-11-02 12:11:40 +0100 (lun., 02 nov. 2009) $
* by : $Author: echatellier $
*/
public class MatrixTableModelND extends AbstractTableModel implements MatrixTableModel {
/** serialVersionUID. */
private static final long serialVersionUID = 983978774901981167L;
protected MatrixND m;
/** nombre de ligne ajouté */
protected int addRow = 0;
/** nombre de colone ajouté */
protected int addCol = 0;
protected int[] multRowCol = null;
/** par defaut, la matrice est editable. */
protected boolean enabled = true;
protected TableCellRenderer renderer = null;
/**
* TableModel basee sur une MatrixND a une ou deux dimensions. Pour le
* moment les matrices de plus de 3 dimensions ne sont pas geree.
*
* Pour les matrices 1D :
*
* La premiere dimension represente les colonnes.
*
* Pour les matrices 2D :
*
* La premiere dimension represente les lignes.
*
* La deuxieme dimension represente les colonnes.
*
* Pour les matrices 3D :
*
* La premiere dimension represente les lignes.
*
* La deuxieme dimension represente les colonnes.
*
* La troisieme dimension represente les lignes (dim1 x dim3).
*
* @param m Matrice a afficher dans la table
* @throws MatrixException
*/
public MatrixTableModelND(MatrixND m) throws MatrixException {
setMatrix(m);
}
@Override
public void setMatrix(MatrixND m) {
this.m = m;
addRow = m.getDimCount() / 2;
addCol = (m.getDimCount() + 1) / 2;
// calcule les coefficients multiplicateur pour la correspondance
// table/matrice
multRowCol = new int[m.getDimCount()];
for (int i = multRowCol.length - 1; i >= 0; i--) {
if (i >= multRowCol.length - 2) {
multRowCol[i] = 1;
} else {
multRowCol[i] = multRowCol[i + 2] * m.getDim(i + 2);
}
}
}
/**
* converti les coordonnées de la table en coordonnées pour la matrice
*
* @param row la ligne dans la table
* @param col la colonne dans la table
* @return les coordonnées equivalentes dans la matrice
*/
protected int[] tableToMatrix(int row, int col) {
int[] result = new int[m.getDimCount()];
for (int i = 0; i < result.length; i++) {
int val = row;
if (i % 2 == 1) { // si impaire alors la valeur vient de la colonne
val = col;
}
result[i] = tableToMatrixCell(i, val);
}
return result;
}
protected int tableToMatrixCell(int dim, int tableValue) {
int b = 0;
int val = tableValue;
if (dim % 2 == 1) { // si impaire alors la valeur vient de la colonne
b = 1; // les colonnes represente toutes les dim impaires
}
while (b < dim) {
val = val % multRowCol[b];
b += 2;
}
int result = val / multRowCol[b];
return result;
}
/**
* Get value.
*
* Return column name (i18n if possible) for bounded values.
*
* @param row row
* @param col column
* @return value
*/
protected Object getValue(int row, int col) {
Object result = null;
if (row < addRow && col < addCol) {
if (row == addRow - 1 && col == addCol - 1) {
result = _(m.getDimensionName(col * 2)) + "\\"
+ _(m.getDimensionName(row * 2 + 1));
} else if (row == addRow - 1) {
result = _(m.getDimensionName(col * 2));
} else if (col == addCol - 1) {
result = _(m.getDimensionName(row * 2 + 1));
} else {
result = "";
}
} else if (row < addRow) {
result = getSemantic(row * 2 + 1, tableToMatrixCell(row * 2 + 1,
col - addCol));
} else if (col < addCol) {
result = getSemantic(col * 2, tableToMatrixCell(col * 2, row
- addRow));
} else {
result = m.getValue(tableToMatrix(row - addRow, col - addCol));
}
return result;
}
/**
* Retourne une representation String de la semantique de l'element elem de
* la dimension dim
*
* @param dim la dimension dans lequel on recherche l'element
* @param elem l'element de la dimension a prendre
* @return une chaine representant l'element. Si l'element est null, la
* chaine vide est retourné
*/
protected String getSemantic(int dim, int elem) {
Object o = m.getSemantic(dim).get(elem);
return (o == null) ? "" : o.toString();
}
@Override
public String getColumnName(int column) {
return null;
// String result = null;
// if (m.getNbDim() != 1) {
// result = getValue(0, column).toString();
// } else {
// result = getValue(column, 0).toString();
// }
// return result;
}
/**
* @return Le nombre de lignes de la table.
*/
@Override
public int getRowCount() {
int result = 0;
if (m.getDimCount() != 1) {
// result = multRowCol[0] * m.getDim(0) + addRow - 1; // -1 pour le
// header
result = multRowCol[0] * m.getDim(0) + addRow;
} else {
result = 2;
}
return result;
}
/**
* @return Le nombre de colonnes de la table.
*/
@Override
public int getColumnCount() {
int result = 0;
if (m.getDimCount() != 1) {
result = multRowCol[1] * m.getDim(1) + addCol;
} else {
result = m.getDim(0);
}
return result;
}
/**
* @param row La ligne
* @param column La colonnes
* @return L'Object correspondant dans la matrice.
*/
@Override
public Object getValueAt(int row, int column) {
Object result = null;
if (m.getDimCount() != 1) {
// // on fait row + 1 a cause du header
// result = getValue(row + 1, column);
result = getValue(row, column);
} else {
result = getValue(column, row);
}
return result;
}
/**
* @param obj L'objet a inserer dans la matrice.
* @param row La ligne
* @param column La colonnes
*/
@Override
public void setValueAt(Object obj, int row, int column) {
if ((m.getDimCount() != 1 && row >= addRow && column >= addCol)
|| (m.getDimCount() == 1 && row >= 1)) {
try {
double val = Double.parseDouble((String) obj);
int[] coord = null;
if (m.getDimCount() != 1) {
// coord = tableToMatrix(row - addRow + 1, column - addCol);
// // +1 pour le header
coord = tableToMatrix(row - addRow, column - addCol);
} else {
coord = new int[] { column };
}
m.setValue(coord, val);
fireTableDataChanged();
} catch (Exception eee) {
Logger.getLogger(getClass().getName() + ".setValueAt").log(
Level.FINE,
"La nouvelle valeur n'est pas convertible en double: "
+ obj, eee);
}
}
}
@Override
public boolean isCellEditable(int row, int column) {
if (m.getDimCount() != 1 && (row < addRow || column < addCol)) {
return false;
} else if (m.getDimCount() == 1 && row < 1) {
return false;
}
return enabled;
}
@Override
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Override
public Class> getColumnClass(int column) {
return String.class;
}
@Override
public TableCellRenderer getMatrixCellRenderer() {
if (renderer == null) {
renderer = new MatrixCellRenderer(this);
}
return renderer;
}
class MatrixCellRenderer extends DefaultTableCellRenderer {
/** serialVersionUID. */
private static final long serialVersionUID = 6537813058357761914L;
protected MatrixTableModelND model = null;
protected Color bg = null;
protected Color fg = null;
protected Font font = null;
protected Border border = null;
public MatrixCellRenderer(MatrixTableModelND model) {
this.model = model;
bg = getBackground();
fg = getForeground();
font = getFont();
border = getBorder();
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
super.getTableCellRendererComponent(table, value, isSelected,
hasFocus, row, column);
setToolTipText(getText());
if ((model.m.getDimCount() != 1 && (row < model.addRow || column < model.addCol))
|| (model.m.getDimCount() == 1 && row < 1)) {
if (table != null) {
JTableHeader header = table.getTableHeader();
if (header != null) {
setForeground(header.getForeground());
setBackground(header.getBackground());
setFont(header.getFont());
}
}
setBorder(UIManager.getBorder("TableHeader.cellBorder"));
} else {
setBackground(bg);
setForeground(fg);
setFont(font);
setBorder(border);
return super.getTableCellRendererComponent(table, value,
isSelected, hasFocus, row, column);
}
return this;
}
}
}