Fala galera, depois de um bom tempo distraido com faculdade e principalmente, dota , finalmente reiniciei a programação do meu software CG em Java, o UniversoPessoal. Nessa nova versão, estou implementado um sistema de script, que vai usar python.
Me embananei um pouco mas já consegui implementar o Jython e tals, o problema é que no meu programa estou deixando uma linha de comando a principio, pro cara fazer ações simples mesmo. Já criei uma série de comandos simples, que possibilitam fazer as mesmas ações que são feitas com mouse.
Aqui aparece o primeiro problema: eu quero ter a opção de, quando eu apertar seta pra cima, o campo(JtextField) se preencha com último comando que eu digitei. Se eu apertar de novo, que apareça o anterior, e assim por diante. Se eu apertar pra baixo, voltaria os comandos posteriores, que nem numa linha de comando comum como no linux ou no prompt do windows. O problema é que usando action listenner, num sei se isso é possível. Mas por acaso tem outro jeito simples de fazer isso? Minha preocupação é só a interface, porque salvar o que usuário digitar eu sei fazer.
Ai vem o segundo problema. Pra num deixar uma coisa totalmente chata, resolvi criar um script em python mesmo que simularia um jogo de corrida no programa. Desenhar uma pista foi simples, o ruim é fazer com que ela se anime. Tentei usar o código abaixo, mas acontece que o programa inteiro roda e só final exibe o resultado, alguém sabe se eu tenho que usar trheads pra isso funcionar? Ou eu tenho que dar um jetio de usar invoker later e etc no meu action performed?
Eis o código:
/**
* Arquivo onde é armazenado o interpretador de scripts do programa
*/
package br.ericware.programa;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/** Classe responsável por executar todo e qualquer script necessário para execução do programa
* @author elisson
*
*/
public class Interpretador implements ActionListener{
/**
* Armazena o módulo 2D
*/
private Mod2D mod2D;
/**
* Armazena o desenhista, por onde os desenhos são feitos
*/
private Desenhista desenhista;
/**
* Cria a conexão com o interpretador Python
*/
private ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");;
/**
* Construtor que recebe como parâmetro o móludo de desenho e o desenhista
* @param m2d o módulo2D de onde virão os scripts
* @param ds o desenhista do módulo em questão
*/
public Interpretador(Mod2D m2d, Desenhista ds) {
this.mod2D = m2d;
this.desenhista = ds;
try {
engine.eval("from " + Executor.class.getPackage().getName() + " import "+ Executor.class.getSimpleName());
Set<Class> classes = new HashSet<Class>();
for (Method metodo : Executor.class.getMethods()) {
if(Modifier.isPublic( metodo.getModifiers())){
if(metodo.getName() != "brincar"){
classes.addAll(Arrays.asList(metodo.getParameterTypes()));
classes.add(metodo.getReturnType());
StringBuffer sb = new StringBuffer("def "+ metodo.getName()+"(");
for(int i = 0; i < metodo.getParameterTypes().length;i++){
if(i > 0)
sb.append(",");
sb.append("param" + i);
}
sb.append("):");
StringBuffer chamada = new StringBuffer("return "+Executor.class.getSimpleName()+"."+metodo.getName()+"(");
for(int i = 0; i < metodo.getParameterTypes().length;i++){
if(i > 0)
chamada.append(",");
chamada.append("param" + i);
}
chamada.append(")");
engine.eval(sb.toString()+"\n "+chamada.toString());
}else{
StringBuffer jogo = new StringBuffer("from time import time" +
"\nvezes = 0" +
"\ndef brincar():" +
"\n global vezes"+
"\n comeco = time()" +
"\n while(vezes< 6000):" +
"\n if((comeco - time()/1000)> 1.5):" +
"\n deslocaPista()" +
"\n comeco = time()" +
"\ndef deslocaPista():"+
"\n global vezes"+
"\n soma = ((vezes%4)*30)" +
"\n alterarCorPrimaria(Color.black)" +
"\n desenharRetangulo(Point(0,0),Point(400,400))" +
"\n alterarCorPrimaria(Color.white)" +
"\n desenharRetangulo(Point(185,(-130)+soma),Point(215,(-40)+soma))" +
"\n desenharRetangulo(Point(185,0+soma),Point(215,90+soma))" +
"\n desenharRetangulo(Point(185,110+soma),Point(215,200+soma))" +
"\n desenharRetangulo(Point(185,220+soma),Point(215,310+soma))" +
"\n vezes= vezes+1" );
engine.eval(jogo.toString());
}
}
}
for(Class classe :classes){
if(!classe.isPrimitive()){
engine.eval("from " + classe.getPackage().getName() + " import "+ classe.getSimpleName());
}
}
} catch (ScriptException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
JTextField linhaComando = (JTextField) e.getSource();
try {
engine.eval(linhaComando.getText());
} catch (ScriptException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
linhaComando.setText("");
}
}
Aqui está a classe Executor
[code]
/**
- Armazena classe responsável pela execução de comandos para o programa
*/
package br.ericware.programa;
import java.awt.Color;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Enumeration;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import org.python.antlr.base.mod;
import br.ericware.desenhos.Elipse;
import br.ericware.desenhos.Linha;
import br.ericware.desenhos.Poligono;
import br.ericware.desenhos.Retangulo;
import br.ericware.desenhos.Texto;
import br.ericware.programa.Desenhista.EstadoSelecao;
import br.ericware.programa.Mod2D.NaoSalvouException;
/**Classe responsável por executar os comandos repassados ao programa, não importando a origem
*
- @author elisson
*/
public class Executor {
/**
* Armazena a instância única do mod2d para realizar as operações
*/
private static Mod2D mod2d;
/**
* Armazena a instância desenhista ligada a instancia de Mod2D armazenada
*/
private static Desenhista ds;
/**
* Determina qual instância será usada para as operações
* @param m2 a instância que será usada para as operações
*/
static void setMod2D(Mod2D m2){
Executor.mod2d = m2;
}
/**Determina a instância de Desenhista ligado a instância de mod2d armazenada
* @param ds o desenhista que deseja-se armazenar
*/
static void setDs(Desenhista ds) {
Executor.ds = ds;
}
/**
* Abre uma imagem a partir do arquivo indicado
* @param arquivo caminho do arquivo para abrir a imagem
*/
public static void abrirImagem(String arquivo){
mod2d.giGerenciador.abreImagem(arquivo);
}
/**
* Abre uma imagem a partir do caminho indicado pelo objeto
* @param arquivo a instância que apontar para o local onde o caminho está
*/
public static void abrirImagem(File arquivo) {
mod2d.giGerenciador.abreImagem(arquivo);
}
/**
* Cria uma nova imagem nas dimensões padrões
*/
public static void criarImagem() {
mod2d.giGerenciador.novaImagem();
}
/**
* Fecha a imagem indicada
* @param img a imagem que se deseja para de editar
*/
public static void fecharImagem(Imagem img) {
mudarImagemEmFoco(img);
mod2d.giGerenciador.fechaImagemAtual();
}
/**
* Fecha a imagem atual
*/
public static void fecharImagemAtual() {
mod2d.giGerenciador.fechaImagemAtual();
}
/**
* Altera a imagem em foco para imagem indicada
* @param novaImagem a imagem que se desejar focar
*/
public static void mudarImagemEmFoco(Imagem novaImagem) {
mod2d.giGerenciador.modificaImagemFocada(mod2d.giGerenciador.getLsImagens().indexOf(novaImagem));
}
/**
* Altera a resolução da imagem atual para a indicada
* @param novaAltura a nova altura da imagem
* @param novaLargura a nova largura da imagem
*/
public static void alterarResolucao(int novaAltura,int novaLargura){
mod2d.giGerenciador.getImagemAtual().getDesfazerRefazer().addEdit(new AcaoImagem(mod2d.giGerenciador,ds,mod2d.giGerenciador.getImagemAtual(), novaLargura/(float)mod2d.giGerenciador.getImagemAtual().getTamanho().width, novaAltura/(float)mod2d.giGerenciador.getImagemAtual().getTamanho().height));
mod2d.giGerenciador.getImagemAtual().setTamanho(novaLargura, novaAltura);
mod2d.giGerenciador.atualizaTitulo();
ds.invalidar();
}
/**
* Altera o nome da imagem atual
* @param nome o novo nome que se deseja dar a imagem atual
*/
public static void alterarNome(String nome){
mod2d.giGerenciador.getImagemAtual().setNome(nome);
mod2d.giGerenciador.atualizaTitulo();
}
/**
* Salva a iamgem indicada
* @param img a imagem que se deseja salvar
*/
public static void salvarImagem(Imagem img){
mod2d.giGerenciador.modificaImagemFocada(mod2d.giGerenciador.getLsImagens().indexOf(img));
try {
mod2d.giGerenciador.salvarImagemAtual();
} catch (IOException ioe) {
// TODO Auto-generated catch block
ioe.printStackTrace();
} catch (NaoSalvouException nse) {
nse.printStackTrace();
}
}
/**
* Salva a imagem indicada com o nome indicado
* @param img a imagem que se deseja salvar
* @param arquivo o caminho para o arquivo onde deseja-se salvar a imagem
*/
public static void salvarImagem(Imagem img, String arquivo){
mod2d.giGerenciador.modificaImagemFocada(mod2d.giGerenciador.getLsImagens().indexOf(img));
try {
mod2d.giGerenciador.salvarImagemAtual(new File(arquivo));
} catch (IOException ioe) {
// TODO Auto-generated catch block
ioe.printStackTrace();
} catch (NaoSalvouException nse) {
nse.printStackTrace();
}
}
/**
* Retorna a imagem atual
* @return a imagem atual
*/
public static Imagem retornarImagemAtual(){
return mod2d.giGerenciador.getImagemAtual();
}
/**
* Fecha o programa
*/
public static void fecharPrograma(){
try {
mod2d.fecha();
} catch (NaoSalvouException nse) {
// TODO Auto-generated catch block
nse.printStackTrace();
}
}
/**
* Copia a parte da imagem indicada pelo retangulo
* @param retangulo o retangulo da onde a imagem será copiada
*/
public static void copiar(Rectangle retangulo){
Executor.criarSelecao(retangulo);
mod2d.transfer.copiar(ds);
}
/**
* Colar uma imagem da área de transferencia na área indicada
* @param retangulo o retangulo onde a imagem será colada
* @param img a imagem que será colada na área indicada
*/
public static void colar(Rectangle retangulo, Image img){
Executor.criarSelecao(retangulo);
try {
mod2d.transfer.colar(ds);
} catch (UnsupportedFlavorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Extrai uma imagem da área indicada
* @param retangulo a área da onde a imagem será extraída
*/
public static void recortar(Rectangle retangulo){
Executor.criarSelecao(retangulo);
mod2d.transfer.recortar(ds);
}
/**
* Altera a cor primária atual para a cor indicada
* @param novaCor a nova cor que será aplicada
*/
public static void alterarCorPrimaria(Color novaCor){
mod2d.setCorPrimaria(novaCor);
}
/**
* Altera a cor secundária atual para a cor indicada
* @param novaCor a nova cor que será aplicada
*/
public static void alterarCorSecundaria(Color novaCor){
mod2d.setCorSecundaria(novaCor);
}
/**
* Desenha uma linha entre os pontos indicados
* @param origem ponto de origem da linha
* @param fim ponto de fim da linha
*/
public static void desenharLinha(Point origem, Point fim){
Linha linha = new Linha(origem.x, origem.y, ds.getCorPrimaria());
linha.setFimX(fim.x).setFimY(fim.y);
linha.setEspessuraLinha((float) mod2d.getEspessuraAtual());
mod2d.giGerenciador.getImagemAtual().getLsDesenhosPendentes().add(linha);
ds.finalizaUltimoDesenho();
ds.repaint();
}
/**
* Desenha a elipse tendo como limites os pontos indicados
* @param origem um dos pontos que marcará o limite da elipse
* @param fim outro ponto que marcará o limite da elipse
*/
public static void desenharElipse(Point origem, Point fim){
Elipse elipse = new Elipse(origem.x, origem.y,fim.x,fim.y, ds.getCorPrimaria());
elipse.setEspessuraLinha((float) mod2d.getEspessuraAtual());
mod2d.giGerenciador.getImagemAtual().getLsDesenhosPendentes().add(elipse);
ds.finalizaUltimoDesenho();
ds.repaint();
}
/**
* Cria um circulo a partir do seu centro e raio
* @param centro ponto que ser o centro do círculo
* @param raio distancia do centro até a borda do circulo
*/
public static void desenharCirculo(Point centro, int raio){
Elipse circulo = new Elipse(centro.x -raio, centro.y - raio,centro.x+raio,centro.y+raio, ds.getCorPrimaria());
circulo.setEspessuraLinha((float) mod2d.getEspessuraAtual());
mod2d.giGerenciador.getImagemAtual().getLsDesenhosPendentes().add(circulo);
ds.finalizaUltimoDesenho();
ds.repaint();
}
/**
* Desenha um retangulo limitado pelos pontos indicados
* @param origem um ponto que limitará o retângulo
* @param fim outro ponto que limitará o retângulo
*/
public static void desenharRetangulo(Point origem, Point fim){
Retangulo retangulo = new Retangulo(origem.x, origem.y,fim.x,fim.y, ds.getCorPrimaria());
retangulo.setEspessuraLinha((float) mod2d.getEspessuraAtual());
mod2d.giGerenciador.getImagemAtual().getLsDesenhosPendentes().add(retangulo);
ds.finalizaUltimoDesenho();
ds.repaint();
}
/**
* Cria um texto a partir do ponto indicado
* @param origem o ponto que será o canto inferior esquerdo do texto
*/
public static void inserirTexto(Point origem){
Texto texto = new Texto(origem.x, origem.y, mod2d.clCorPrimaria, mod2d.jfJanela, ds);
mod2d.giGerenciador.getImagemAtual().getLsDesenhosPendentes().add(texto);
}
/**
* Cria um texto a partir do texto e ponto indicados
* @param origem o ponto onde o texto iniciará
* @param texto o texto que será impresso
*/
public static void inserirTexto(Point origem, String texto){
Texto textoImpresso = new Texto(origem.x, origem.y, mod2d.clCorPrimaria, mod2d.jfJanela, ds,texto);
mod2d.giGerenciador.getImagemAtual().getLsDesenhosPendentes().add(textoImpresso);
ds.finalizaUltimoDesenho();
}
/**
* Indica uma área que será preenchida pela cor de fundo
* @param retanguloApagado o retangulo que será pagado
*/
public static void apagarArea(Rectangle retanguloApagado){
Retangulo retangulo = new Retangulo(retanguloApagado.x, retanguloApagado.y,retanguloApagado.x+retanguloApagado.width,retanguloApagado.y+retanguloApagado.height, mod2d.clCorSecundaria);
retangulo.setEspessuraLinha((float) mod2d.getEspessuraAtual());
mod2d.giGerenciador.getImagemAtual().getLsDesenhosPendentes().add(retangulo);
ds.finalizaUltimoDesenho();
ds.repaint();
}
/**
* Aplica a ferramenta lata de tinta no ponto indicado
* @param ponto o ponto que se deseja preencher os arredores
*/
public static void preencherPonto(Point ponto){
Poligono preenchimento = ds.geraPoligonoPreenchido(ponto.x,ponto.y,ds.getImagem());
mod2d.giGerenciador.getImagemAtual().getLsDesenhosPendentes().add(preenchimento);
ds.finalizaUltimoDesenho();
ds.repaint();
}
/**
* Cria um novo polígono a partir do ponto indicado
* @param origem o ponto que será a origem do polígono
*/
public static void iniciarPoligono(Point origem){
ds.verificaInicioPoligono(origem.x, origem.y);
}
/**
* Continua a traçar o polígono até o ponto indicado
* @param destino o ponto da onde será traçado uma linha que alcançará o atual fim do poligono
*/
public static void extenderPoligono(Point destino){
ds.verificaInicioPoligono(destino.x, destino.y);
}
/**
* Finaliza o poligno no ponto indicado
* @param destino o ultimo ponto do poligono que se deseja traçar
*/
public static void finalizarPoligono(Point destino){
ds.verificaInicioPoligono(destino.x, destino.y);
finalizarPoligono();
}
/**
* Finaliza o poligono que está sendo desenhado
*/
public static void finalizarPoligono(){
ds.finalizaUltimoDesenho();
ds.repaint();
}
/**
* Amostra a cor no ponto indicado
* @param ponto o ponto da onde se deseja tirar a cor primária
*/
public static void amostrarCor(Point ponto){
ds.amostraCor((int)(ponto.x*mod2d.giGerenciador.getImagemAtual().getZoom()),(int)(ponto.y*mod2d.giGerenciador.getImagemAtual().getZoom()));
}
/**
* Aumenta o zoom
*/
public static void aumentarZoom(){
ds.aumentaZoom();
}
/**
* Diminui o zoom
*/
public static void diminuirZoom(){
ds.diminuiZoom();
}
/**
* Determina o zoom
* @param zoom O valor em porcentagem qeu se deseja para o novo zoom
*/
public static void aplicarZoom(int zoom){
ds.setZoom(((double)(zoom))/100.0);
}
/**
* Altera a espessura da ferramenta atual
* @param espessura a nova espessura desejada
*/
public static void alterarExpessura(double espessura){
mod2d.setEspessuraAtual(espessura);
}
/**
* Troca a ferramenta atualmente usada pela indicada por seu nome
* @param ferramenta o nome da ferramenta desejada
*/
public static void trocarFerramenta(String ferramenta){
Enumeration<AbstractButton> botoes = mod2d.bgFerramentas.getElements();
while(botoes.hasMoreElements()){
AbstractButton botao = botoes.nextElement();
if(botao.getName() == ferramenta){
ButtonModel modelo = botao.getModel();
mod2d.bgFerramentas.setSelected(modelo, true);
}
}
}
/**
* Inicia um joguinho de corrida :)
*/
public static void brincar(){
}
/**
* Rotaciona a imagem no sentido horário
*/
public static void rotacionar(){
mod2d.giGerenciador.getImagemAtual().rotacionar();
}
/**
* Desfaz a última ação realizada na imagem atual
*/
public static void desfazer(){
if(mod2d.giGerenciador.getImagemAtual().getDesfazerRefazer().canUndo())
mod2d.giGerenciador.getImagemAtual().getDesfazerRefazer().undo();
}
/**
* Refaz a última ação desfeita na imagem
*/
public static void refazer(){
if(mod2d.giGerenciador.getImagemAtual().getDesfazerRefazer().canRedo()){
mod2d.giGerenciador.getImagemAtual().getDesfazerRefazer().redo();
}
}
/**
* Cria uma seleção na área do retangulo indicado. Entretano, a seleção só será exibida se a ferramenta seleciona for seleção
* @param area o retangulo onde ficará a seleção
*/
public static void criarSelecao(Rectangle area){
mod2d.setSelecao(area);
}
}[/code]
Uma ajuda pra qualquer um dos problema é muito bem vinda, Agradeço desde já.