290 lines
7.9 KiB
Java
290 lines
7.9 KiB
Java
package org.solovyev.android.calculator.matrix;
|
|
|
|
import android.content.Context;
|
|
import android.util.AttributeSet;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.EditText;
|
|
import android.widget.TableLayout;
|
|
import android.widget.TableRow;
|
|
import android.widget.TextView;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
/**
|
|
* User: Solovyev_S
|
|
* Date: 12.10.12
|
|
* Time: 15:41
|
|
*/
|
|
public class MatrixView extends TableLayout {
|
|
|
|
/*
|
|
**********************************************************************
|
|
*
|
|
* CONSTANTS
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
private static final CharSequence DEFAULT_CELL_TEXT = "0";
|
|
private static final int NUMBER_INDEX = -1;
|
|
|
|
|
|
/*
|
|
**********************************************************************
|
|
*
|
|
* FIELDS
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
private int rows = 0;
|
|
private int cols = 0;
|
|
|
|
@Nullable
|
|
private CharSequence defaultCellText = DEFAULT_CELL_TEXT;
|
|
|
|
private boolean initialized = false;
|
|
|
|
/*
|
|
**********************************************************************
|
|
*
|
|
* CONSTRUCTORS
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
public MatrixView(Context context) {
|
|
super(context);
|
|
}
|
|
|
|
public MatrixView(Context context, AttributeSet attrs) {
|
|
super(context, attrs);
|
|
}
|
|
|
|
/*
|
|
**********************************************************************
|
|
*
|
|
* METHODS
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
public int getRows() {
|
|
return rows;
|
|
}
|
|
|
|
public int getCols() {
|
|
return cols;
|
|
}
|
|
|
|
public void setMatrixCols(int newCols) {
|
|
setMatrixDimensions(rows, newCols);
|
|
}
|
|
|
|
public void setMatrixRows(int newRows) {
|
|
setMatrixDimensions(newRows, cols);
|
|
}
|
|
|
|
public void setMatrixDimensions(int newRows, int newCols) {
|
|
if (newRows <= 1) {
|
|
throw new IllegalArgumentException("Number of rows must be more than 1: " + newRows);
|
|
}
|
|
|
|
if (newCols <= 1) {
|
|
throw new IllegalArgumentException("Number of columns must be more than 1: " + newCols);
|
|
}
|
|
|
|
boolean rowsChanged = this.rows != newRows;
|
|
boolean colsChanged = this.cols != newCols;
|
|
|
|
if (rowsChanged || colsChanged) {
|
|
if (!initialized) {
|
|
addRow(NUMBER_INDEX, 0);
|
|
initialized = true;
|
|
}
|
|
|
|
if (this.cols > newCols) {
|
|
removeCols(newCols);
|
|
} else if (this.cols < newCols) {
|
|
addCols(newCols);
|
|
}
|
|
|
|
this.cols = newCols;
|
|
|
|
if (this.rows > newRows) {
|
|
removeRows(newRows);
|
|
} else if (this.rows < newRows) {
|
|
addRows(newRows);
|
|
}
|
|
|
|
this.rows = newRows;
|
|
}
|
|
}
|
|
|
|
public void setMatrix(@NotNull Object[][] matrix) {
|
|
final int rows = matrix.length;
|
|
final int cols = matrix[0].length;
|
|
|
|
setMatrixDimensions(rows, cols);
|
|
for (int row = 0; row < rows; row++) {
|
|
for (int col = 0; col < cols; col++) {
|
|
setCell(row, col, matrix[row][col]);
|
|
}
|
|
}
|
|
}
|
|
|
|
@NotNull
|
|
public String[][] toMatrix() {
|
|
final String[][] result = new String[rows][cols];
|
|
|
|
for (int row = 0; row < rows; row++) {
|
|
for (int col = 0; col < cols; col++) {
|
|
final TextView cellTextView = (TextView) getCell(this, row, col);
|
|
if (cellTextView != null) {
|
|
result[row][col] = cellTextView.getText().toString();
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private void setCell(int row, int col, @Nullable Object o) {
|
|
final TextView cellTextView = (TextView) getCell(this, row, col);
|
|
if (cellTextView != null) {
|
|
if (o == null) {
|
|
cellTextView.setText(null);
|
|
} else {
|
|
cellTextView.setText(String.valueOf(o));
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
**********************************************************************
|
|
*
|
|
* PRIVATE METHODS
|
|
*
|
|
**********************************************************************
|
|
*/
|
|
|
|
private void addRows(int newRows) {
|
|
for (int row = this.rows; row < newRows; row++) {
|
|
addRow(row, cols);
|
|
}
|
|
}
|
|
|
|
private void removeRows(int newRows) {
|
|
for (int row = this.rows - 1; row >= newRows; row--) {
|
|
removeRow(row);
|
|
}
|
|
}
|
|
|
|
private void addCols(int newCols) {
|
|
for (int row = NUMBER_INDEX; row < rows; row++) {
|
|
final ViewGroup rowView = getRow(row);
|
|
if (rowView != null) {
|
|
for (int col = this.cols; col < newCols; col++) {
|
|
rowView.addView(createCellView(row, col));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void removeCols(int newCols) {
|
|
for (int row = NUMBER_INDEX; row < rows; row++) {
|
|
final ViewGroup rowView = getRow(row);
|
|
if (rowView != null) {
|
|
for (int col = this.cols - 1; col >= newCols; col--) {
|
|
final View cellView = getCell(rowView, row, col);
|
|
if (cellView != null) {
|
|
rowView.removeView(cellView);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void addRow(int row, int newCols) {
|
|
this.addView(createRowView(row, newCols));
|
|
}
|
|
|
|
private void removeRow(int row) {
|
|
final View rowView = getRow(row);
|
|
if (rowView != null) {
|
|
this.removeView(rowView);
|
|
}
|
|
}
|
|
|
|
@Nullable
|
|
private TableRow getRow(int row) {
|
|
return (TableRow) this.findViewWithTag(getRowTag(row));
|
|
}
|
|
|
|
@Nullable
|
|
private View getCell(@NotNull View view, int row, int col) {
|
|
return view.findViewWithTag(getCellTag(row, col));
|
|
}
|
|
|
|
@NotNull
|
|
private String getRowTag(int row) {
|
|
if (row != NUMBER_INDEX) {
|
|
return "row_" + row;
|
|
} else {
|
|
return "row_index";
|
|
}
|
|
}
|
|
|
|
@NotNull
|
|
private View createRowView(int row, int cols) {
|
|
final ViewGroup rowView = new TableRow(this.getContext());
|
|
|
|
rowView.setTag(getRowTag(row));
|
|
|
|
if (row != NUMBER_INDEX) {
|
|
rowView.addView(createCellView(row, NUMBER_INDEX));
|
|
} else {
|
|
// empty cell
|
|
rowView.addView(new View(this.getContext()));
|
|
}
|
|
|
|
for (int col = 0; col < cols; col++) {
|
|
rowView.addView(createCellView(row, col));
|
|
}
|
|
return rowView;
|
|
}
|
|
|
|
@NotNull
|
|
private View createCellView(int row, int col) {
|
|
final TextView result;
|
|
|
|
if (row != NUMBER_INDEX && col != NUMBER_INDEX) {
|
|
result = new EditText(this.getContext());
|
|
result.setText(defaultCellText);
|
|
} else {
|
|
result = new TextView(this.getContext());
|
|
if (row == NUMBER_INDEX) {
|
|
result.setText(String.valueOf(col + 1));
|
|
} else {
|
|
result.setText(String.valueOf(row + 1));
|
|
}
|
|
}
|
|
|
|
result.setTag(getCellTag(row, col));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
@NotNull
|
|
private String getCellTag(int row, int col) {
|
|
if (row != NUMBER_INDEX) {
|
|
return "cell_" + row + "_" + col;
|
|
} else {
|
|
return "cell_index_" + col;
|
|
}
|
|
}
|
|
|
|
}
|