/* Copyright (C) 2007 Felipe A. Lessa * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * 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 Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ package tirateima.gui.variaveis; import java.awt.Color; import java.awt.Dimension; import java.awt.Point; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Map.Entry; import tirateima.Par; /** * Variável que contém uma coleção homogênea de variáveis indexadas por dois * índices inteiros (matriz). * * @author felipe.lessa * */ @SuppressWarnings("serial") public class VarMatriz extends VarGrade { private static List<Variavel> concatenar(List<List<Variavel>> vars) { ArrayList<Variavel> ret = new ArrayList<Variavel>(); for (List<Variavel> l : vars) ret.addAll(l); return ret; } private int cols; private int rows; /** * Constrói uma nova matriz com as variáveis definidas. Cada variável deve * ter um nome que corresponda à posição dela na matriz, todas devem * ser do mesmo tipo, e a matriz deve ser quadrada, porém essas propriedades * não são verificadas. * @param nome nome da variável. * @param variaveis variáveis. */ public VarMatriz(String nome, List<List<Variavel>> variaveis) throws Exception { super(nome, variaveis.size(), variaveis.get(0).size(), concatenar(variaveis)); this.cols = variaveis.get(0).size(); this.rows = variaveis.size(); } /** * Constrói uma nova matriz com as variáveis definidas. Cada variável deve * ter um nome que corresponda à posição dela na matriz, todas devem * ser do mesmo tipo, e a matriz deve ser quadrada, porém essas propriedades * não são verificadas. * @param nome nome da variável. * @param cols número de colunas. * @param rows número de linhas. * @param variaveis variáveis. */ public VarMatriz(String nome, int rows, int cols, List<Variavel> variaveis, Color cor, Color corExterna, Dimension dimensao, Point posicao, Boolean mostraNome) { super(nome, rows, cols, variaveis); this.rows = rows; this.cols = cols; super.cor = cor; super.corExterna = corExterna; super.dimensao = dimensao; super.posicao = posicao; super.mostraNome = mostraNome; } /** * Constrói um novo array vazio a partir de uma classe. * @param nome nome da variável. * @param rows número de linhas. * @param cols número de colunas. * @param tipo tipo das variáveis (deve derivar de Variavel). * @throws Exception lança uma exceção caso haja algum erro ao criar * as variáveis. */ public VarMatriz(String nome, int rows, int cols, Class<Variavel> tipo) throws Exception { super(nome, rows, cols, criarVariaveis(rows, cols, tipo)); this.rows = rows; this.cols = cols; } /** * Constrói uma nova matriz vazia a partir de uma variável modelo. * Utilizado para criar matriz de record. * @param nome nome da variável. * @param rows número de linhas. * @param cols número de colunas. * @param tipo tipo das variáveis (deve derivar de Variavel). * @throws Exception lança uma exceção caso haja algum erro ao criar * as variáveis. */ public VarMatriz(String nome, int rows, int cols, Variavel tipo) throws Exception { super(nome, rows, cols, criarVariaveis(rows*cols, tipo)); this.rows = rows; this.cols = cols; } /** * Constrói uma nova matriz vazia a partir de uma variável modelo com cor e tamanhos customizados * Utilizado para criar matriz de record. * @param nome nome da variável. * @param rows número de linhas. * @param cols número de colunas. * @param tipo tipo das variáveis (deve derivar de Variavel). * @throws Exception lança uma exceção caso haja algum erro ao criar * as variáveis. */ public VarMatriz(String nome, int rows, int cols, Variavel tipo, Color cor, Dimension dimensao, Point posicao) throws Exception { super(nome, rows, cols, criarVariaveis(rows*cols, tipo)); super.cor = cor; super.dimensao = dimensao; super.posicao = posicao; this.rows = rows; this.cols = cols; } /** * Constrói uma nova matriz vazia a partir de uma variável modelo com cor e tamanhos customizados * Utilizado para criar matriz de record. * @param nome nome da variável. * @param rows número de linhas. * @param cols número de colunas. * @param tipo tipo das variáveis (deve derivar de Variavel). * @throws Exception lança uma exceção caso haja algum erro ao criar * as variáveis. */ public VarMatriz(String nome, int rows, int cols, Variavel tipo, Color cor, Color corExterna, Dimension dimensao, Point posicao) throws Exception { super(nome, rows, cols, criarVariaveis(rows*cols, tipo)); super.cor = cor; super.corExterna = corExterna; super.dimensao = dimensao; super.posicao = posicao; this.rows = rows; this.cols = cols; } private static List<Variavel> criarVariaveis(int rows, int cols, Class<Variavel> tipo) throws Exception { int tamanho = rows * cols; Variavel[] ret = new Variavel[tamanho]; Constructor<Variavel> constr = tipo.getConstructor(String.class); for (int i = 0; i < tamanho; i++) { int coluna = i % cols; int linha = i / cols; ret[i] = constr.newInstance((linha+1) + "," + (coluna+1)); } return Arrays.asList(ret); } @Override public VarMatriz criarCopia() { int tamanho = variaveis.size(); Variavel[] novo = new Variavel[tamanho]; for (int i = 0; i < tamanho; i++) novo[i] = variaveis.get(i).criarCopia(); try { VarMatriz ret = new VarMatriz(nome, rows, cols, Arrays.asList(novo), cor, corExterna, dimensao, posicao, mostraNome); ret.modificado = modificado; modificado = false; return ret; } catch (Exception e) { e.printStackTrace(); System.exit(1); return null; } } @Override public String dimensions() { StringBuilder builder = new StringBuilder(); Variavel v = variaveis.get(0); if (v instanceof VarGrade) { builder.append(((VarGrade) v).dimensions()); } builder.append("["); builder.append(Integer.toString(rows)); builder.append(","); builder.append(Integer.toString(cols)); builder.append("]"); return builder.toString(); } @Override public Color getCorTitulo() { if(corExterna != null){ return corExterna; } if(cor == null){ return Color.PINK; } return cor; } @Override public Dimension getTamanhoMaximo() { return new Dimension(700, 700); } @Override public Object[] getValor() { Object[] ret = new Object[variaveis.size()]; int i = 0; for (Variavel v : variaveis) ret[i++] = v.getValor(); return ret; } /** * Define um ou mais valores das variáveis desta matriz. Se valor for null, * todas as variáveis são limpas como se não tivessem qualquer valor. Caso * contrário, valor deve implementar Map<Par<Integer, Integer>, Object> * onde cada chave corresponde a um índice da matriz (variáveis que não * sejam referenciadas não serão modificadas). * * Por exemplo, depois de criar uma matriz 5x7 (5 linhas por 7 colunas) de * inteiros, você pode modificar o último elemento para conter o número 42 * fazendo algo como: * * Integer valor; * Par<Integer,Integer> par; * Map<Par<Integer,Integer>, Object> map; * * par = new Par<Integer,Integer>(4,6); * valor = new Integer(42); * map = new HashMap<Par<Integer,Integer>, Object>(); * map.put(par, valor); * matriz.setValor(map); */ @SuppressWarnings("unchecked") @Override public void setValor(Object valor) { if (valor == null) { for (Variavel v : variaveis) v.setValor(null); } else { Map<Par<Integer,Integer>, Object> map; map = (Map<Par<Integer,Integer>, Object>) valor; for (Entry<Par<Integer,Integer>, Object> entry : map.entrySet()) { Par<Integer,Integer> par = entry.getKey(); variaveis.get(par.fst * cols + par.snd).setValor(entry.getValue()); } } } }