Duvida com Animações

Hi, guys!

Sou novo por aqui, estou com um projeto mais ta muito em cima da hora e está muito dificil associar as classes do projeto.
Bom, vim aqui para vocês me ajudarem.

Olha o que eu preciso…

Preciso fazer um controlador de animações, onde eu desenho na tela nós com Drawrect e uma string dentro, simulando uma estrutura de dados do tipo lista ligada.

Tenho as Classes Nó, NóGrafico, Animacao, CriaNoAnimacao, DeletaNoAnimacao, ControleAnimacao, Controlador, JanelaPrincipal…(se quiserem posto tudo que consegui ir fazendo)

Tenho muitas duvidas do tipo, preciso criar uma lista que receba o tipo de animação que eu to fazendo ou seja, executar uma thread que va desenhando o nó pouco a pouco, mas concorrentemente preciso que essa lista tenha outros tipos de animação, como por exemplo deletaNoanimacao, não sei como passar o tipo das animações para o LIST.
E outra como vou rodar uma thread pra ir desenhando só as animações que ainda estão ativas?
Exemplo:Tenho uma animação crianoanimacao que vai desenhar até x e y terem um valor, daí usou a thread um pouco passa pra proxima animação que pode ser criar outro Nó na tela.

Me ajudem to desesperado ja.=/

Nossa, que simples hein?
Se estiver esperando que alguém faça por vc, acho melhor desistir.
O que você já fez? Poste dúvidas pontuais para podermos ajudar.

[]'s

opa então minha primeira duvida a ser resolvida é como vou passar como parametro na Lista de Animação o Nó e o tipo de animação atribuido a ele, seja desenhar ou deletar.

Vou demonstrar as minhas classes até então.

Janela Principal


import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.JFrame;

public class JanelaPrincipal extends JFrame
{
	public JanelaPrincipal()
	{
		JanelaPrincipal frame = new JanelaPrincipal();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		//obtém as dimensões da tela
		
		Toolkit kit = Toolkit.getDefaultToolkit();
		Dimension screenSize = kit.getScreenSize();
		int screenHeight = screenSize.height;
		int screenWidth = screenSize.width;
		
		//centraliza o frame na tela
		
		setSize(screenWidth / 2, screenHeight / 2);
		setLocation(screenWidth / 4, screenHeight);
		
	}
	
	public void atualiza()
	{
		this.repaint();
	}
}

Janela

[code]package controle;

public class Janela implements Runnable
{
Thread anime = null;
Controle controle = new Controle();

//Tempo de espera entre cada animacao em milisegundos
public static final long TEMPO_ESPERA = 30;

public void start()
{
if (anime == null)
  {
	anime = new Thread(this);
	anime.start();
  }
}

@Override
public void run() 
{
	while(true)
	{
		try 
		{
			controle.desenhaNos(g);
			Thread.sleep(TEMPO_ESPERA);
		} 
		catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
	}		
	
}

}
[/code]

Controle

[code]package controle;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.List;

import controle.animacao.ControleAnimacao;
import controle.animacao.No;
import controle.animacao.NoGrafico;

public class Controle {

private int posicaoXAtual, posicaoYAtual;
private static Controle instancia = new Controle();
private List<NoGrafico> desenhosNos;
private static final int PAUSA_ANIMACAO = 300;


public Controle(){
	posicaoXAtual = 200;
	posicaoYAtual = 200;
	NoGrafico no = null;
	no.setX(posicaoXAtual);
	no.setY(posicaoYAtual);
}

public void CriaNo(No no){
	//Cria o No Grafico associado
	//Associa uma animacao a ele
	//Coloca na lista de animacoes
}

public void RemoveNo(No no){
	
}

public static Controle getInstancia() {
	return instancia;
}


//Este método deve ser utilizado no método de desenho para atualizar as imagens
//o ideal é rodá-lo dentro de uma Thread...
public void desenhaNos(Graphics2D g){
	
	ControleAnimacao controleAnimacao = ControleAnimacao.getInstancia();
	
	//Dispara as animacoes
	controleAnimacao.anima();
	
	//Desenha os nos após animados
	synchronized(desenhosNos){
		for (NoGrafico no:desenhosNos){
			no.desenha(g);
		}
	}
}

}[/code]

Animacao

[code]package controle.animacao;

public abstract class Animacao
{

private boolean ativa;

public boolean isAtiva() 
{
	return ativa;
}

public abstract void anima();

}[/code]

ControleAnimacao

[code]package controle.animacao;

import java.util.ArrayList;
import java.util.List;

public class ControleAnimacao {

public List<Animacao> listaAnimacoes;
private boolean terminou = false;

// Controle do Singleton
private static ControleAnimacao instancia = new ControleAnimacao();

public static ControleAnimacao getInstancia() {
	return instancia;
}

public ControleAnimacao() {
	listaAnimacoes = new ArrayList<Animacao>();
}

public void AdicionaAnimacao(Animacao animacao) {
	synchronized (listaAnimacoes) {
		listaAnimacoes.add(animacao);
	}

}


public void anima() {
	synchronized (listaAnimacoes) {

		// Anima todas as animações na lista
		for (Animacao animacao : listaAnimacoes) {
			animacao.anima();
		}

		// Remove as animações que terminaram
		List<Integer> listaNosRemovidos = new ArrayList<Integer>();

		// Faço a procura da ultima para o primeiro elemento para
		// facilitar
		// a remocao
		for (int i = listaAnimacoes.size() - 1; i >= 0; i--) {
			Animacao animacao = listaAnimacoes.get(i);
			if (!animacao.isAtiva()) {
				listaNosRemovidos.add(i);
			}
		}

		// Removo as animacoes terminadas, com oremovo da ultima para a primeira				
		// isto nao muda os indices das animacoes a serem removidas..
		for (int indice:listaNosRemovidos){
			listaAnimacoes.remove(indice);
		}				
	}		

}

}[/code]

CriaNoAnimacao

[code]package controle.animacao;

public class CriaNoAnimacao extends Animacao
{
	
	public CriaNoAnimacao(NoGrafico no)
	{
		
	}

	@Override
	public void anima() {
		// TODO Auto-generated method stub
		
	}
	
}[/code]

No

[code]package controle.animacao;

public class No
{
public static String str = “Gustavo”;

private static final int BORDAHORIZONT = 5;

public int getBordahorizont() 
{
	return BORDAHORIZONT;
}

}[/code]

NoGrafico

[code]package controle.animacao;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;

import javax.swing.JPanel;

public class NoGrafico extends JPanel
{
private No no;
private int x ;
private int y ;
private final int a = 90;
private final int l = 80;

public No getNo() {
	return no;
}
public void setNo(No no) {
	this.no = no;
}

 public int getX() {
	return x;
}

public void setX(int x) {
	this.x = x;
}

public int getY() {
	return y;
}

public void setY(int y) {
	this.y = y;
}

public synchronized Point getPosicao(){
	Point retorno = new Point();
	
	retorno.x = x;
	retorno.y = y;
	
	return retorno;
}

public void desenha(Graphics g)
{
	super.paintComponent( g );
	
	if (no!=null)
	{				
		Graphics2D g2d = (Graphics2D) g;
		Font font = new Font("monospaced", Font.PLAIN, 8);
		FontMetrics metrics= g2d.getFontMetrics();
		int tamanhoHorizontal = metrics.charsWidth(no.str.toCharArray(), 0, no.str.length());
		int tamanhoVertical = metrics.getHeight();
		
		g2d.drawRect(getX(), getY(), tamanhoHorizontal +2*no.getBordahorizont(),tamanhoVertical);
		g2d.drawString(no.str, getX()+no.getBordahorizont(), getY()+tamanhoVertical);
	}
	
	this.setBackground(Color.WHITE);
}

}
[/code]

[size=18]OBS:Nem todas as classes estão 100% corretas.[/size]

Do jeito q vc fez, está dificil de entender
Espero q isso ajude

[code]public class PanelDesenho extends JPanel {
private BufferedImage buffer;
private ThreadAnimador animador;
private Animacoes animacoes;

public PanelDesenho(Animacoes animacoes) {
this.animacoes = animacoes;
animador = new ThreadAnimador();
}

public void init() {
animador.start();
}

@Override
public void paintComponent(Graphics g) {
if (buffer != null) {
g.drawImage(buffer, 0, 0, null);
}
g.dispose();
}

private class ThreadAnimador extends Thread {
@Override
public void run() {
do{
if (getWidth() == 0 || getHeight() == 0) {//se o tamanho for 0, n será possivel criar o buffer
buffer = null;
} else {
if (buffer == null || buffer.getWidth(null) != getWidth() || buffer.getHeight(null) != getHeight()) {//verifica se alterou o tamanho do container
buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);//cria um novo buffer
}
Graphics2D g2d = buffer.createGraphics();//obtem o graphics
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, buffer.getWidth(null), buffer.getHeight(null));//limpa o buffer
animacoes.pintar(g2d);//pinta no buffer e atualiza para o prox frame da animacao
g2d.dispose();
repaint();//aviza pro JPanel redesenhar
}
Thread.sleep(TEMPO);
} while(true);
}
}
}[/code]

obrigado vou testar o lance do método pra desenhar dentro de uma thread que acho que vai ser de grande ajuda, mas o lance de passar uma animação como parametro eu não entendi.

Tipo, tenho dois tipos de animação a de criar a animação e de deletar a animação, como vou passar isso como parametro a animação vai ser um objeto que eu tenho que retornar dentro da classe Cria e Deleta?

[code]class Animacoes() {
private LinkedList listaAnimacao;
private LinkedList listaRemovidos;

public Animacoes() {
listaAnimacao = new LinkedList();
listaRemovidos = new LinkedList();
}

public void adicionar(Animacao a) {
listaAnimacao.add(a);
}

public void remover(Animacao a) {
listaRemovidos.add(a);
}

public void pintar(Graphics2D g) {
listaAnimacao.removeAll(listaRemovidos);//remove todos da listaAnimacoes q contem nos removidos
listaRemovidos.clear();//limpa a lista removidos
for (Animacao a : listaAnimacao) {
//vc poderia colocar aki
//if (a.isAtiva()) {
// a.pintar(g);
//} else {
// listaAnimacao.remove(a);
//}
a.pintar(g);
}
}
}[/code]

public class Animacao { //Atributos e metodos q n conheco private int indice; public void pintar(Graphics2D g) { //pinta a imagem com o indice indice = (indice + 1) % qtdDeFrames;//se for array de imagens, qtdDeFrames = array.lenght, se for lista list.size(); } }

só lembrando que eu não utilizo imagem em lugar algum no código só desenhos com drawrect e drawstring.
Então pelo seu exemplo eu não devo criar as classes anima ou deleta?
Centralizo todas as funcionalidades na classe animacão?

Eu comecei fazendo bem quebrado pra caso o trabalho venha a evoluir eu possa reutilizar.
Como eu desenho mais de um nó na tela concorrentemente ou seja, terminou um comeca o outro?Lembro que desenhar direto no frame do tipo frame.add(no) não consegui desenhar dois sempre um sobrescrevia os atributos do outro.

Lembrando também que eu só tenho um objeto Controle(Singleton)…

Entao axo q sua classe de Controle, seria a classe Animacoes q fiz, basta mudar mudar o nome do metodo de chamada q coloquei como pintar, para desenharNo, como sua classe é singleton, n precisa passar como parametro, basta fazer a chamada direta a classe

um exemplo sem thread no panel, mas ai vc teria q alterar a classe de controle

[code]public class PanelDesenho extends JPanel {
private BufferedImage buffer;
private Controle controle;

public PanelDesenho() {
controle = Controle.getInstancia();
controle.addPanelDesenho(this);//necessario para dar o repaint()
}

@Override
public void paintComponent(Graphics g) {
if (getWidth() == 0 || getHeight() == 0) {//se o tamanho for 0, n será possivel criar o buffer
buffer = null;
} else {
if (buffer == null || buffer.getWidth(null) != getWidth() || buffer.getHeight(null) != getHeight()) {//verifica se alterou o tamanho do container
buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);//cria um novo buffer
}
Graphics2D g2d = buffer.createGraphics();//obtem o graphics
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, buffer.getWidth(null), buffer.getHeight(null));//limpa o buffer
controle.desenhaNos(g2d);//pinta no buffer e atualiza para o prox frame da animacao (retira ou mantem as Animacao)
g2d.dispose();
}

if (buffer != null) {
  g.drawImage(buffer, 0, 0, null);
}
g.dispose();

}
}[/code]

public class Controle() {
  private LinkedList<PanelDesenho> panelsDesenho;
  //seu codigo
  public Controle() {
    //seu codigo
    panelsDesenho = new LinkedList<PanelDesenho>();
  }
  public void addPanelDesenho(PanelDesenho pd) {
    panelsDesenho.add(pd);
  }
  //avisar q houve alteraçao nas imagens como adicionou ou removeu no
  private void avisarPanels() {
    for (PanelDesenho pd : panelsDesenho) {
      pd.repaint();
    }
  }
}

oque as classes Anima e Deleta fariam?
A classe de Controle q vc fez cria e remove Animacao, entao axo q as classes Anima e Deleta n seriam necessarias

Cara ainda não consegui resolver tudo, sou bem novo em JAVA e to martelando pra aprender a fazer a montagem dos códigos, fiz algumas coisas que vc me deu a dica mas ainda não sei como rodar tudo e mostrar na tela?

Outra coisa é em qual classe eu adiciono o for pra ir desenhando ela no buffer aos poucos e não ela totalmente e setando o isAtiva()(true or false)?
E outra como agente já eliminou as classes Cria e Deleta, que tipo de Animação eu vou passar no parametro que vc colocou.
Ex: public void Adicionar (Animacao a) o que vai ser esse a?

Minha classe Animacao é abstract não serve pra muita coisa a não ser obrigar uma subclasse a implementar o método anima(), só estou com essa classe porque foi definido isso.

Já to agradecendo demais pela ajuda.

Como havia dito, o codigo q vc postou ta confuso
acho melhor vc dar uma olhada no link http://pontov.com.br/site/java/

Ignorando um pouco oq postei, oq vc quer fazer e oq cada classe faz?
Janela
Controle
Animacao
ControleAnimacao
CriaNoAnimacao
No
NoGrafico

Pense um pouco na funcionalidade de cada classe

Bom, objetivo.

Criar uma animação em um JFrame que manipule uma estrutura de dados no caso lista ligada simples.
Preciso desenhar um nó na tela com drawrect e inserir uma string dentro, manipular essa string dentro da estrutura, criar nós, remover nós, preciso basicamente fazer isso e mostrar na tela acontecendo cada ação.

Janela - onde fica o Frame e desenha as animações;
Controle - Controla todos os componentes do projeto, essa classe é quem distribui o que vai fazer o que e na ordem certa, também temos o controle singleton aqui
Animacao - Classe Abstract apenas com o método anima() também abstrato e o atributo se está ativa ou não a animação.
ControleAnimacao - Aqui faremos o controle da Animação, desenhar, adicionar um nó na lista, deletar, verificar se tem mais animações a serem animadas…
CriaNoAnimacao - Cria ou desenha o nó antes de mostrar na tela, na minha cabeça essa classe iria desenhando aos poucos e não de uma vez.
No - tem os atributos string e as bordas;
NoGrafico - Aqui tem o método desenha e os atributos x, y, e as dimensões do nó;

To desistindo já o professor que era pra me orientar nem responde meus emails…quero muito aprender mais ta foda =/

Acontece q vc ta tentando fazer algo complicado com pouco conhecimento em java

São necessárias duas classes, uma é a Janela(JanelaPrincipal) e a outra a area q será desenhada PanelDesenho

[code]import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.JFrame;

public class JanelaPrincipal extends JFrame
{
public JanelaPrincipal()
{
JanelaPrincipal frame = new JanelaPrincipal();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	//obtém as dimensões da tela
	
	Toolkit kit = Toolkit.getDefaultToolkit();
	Dimension screenSize = kit.getScreenSize();
	int screenHeight = screenSize.height;
	int screenWidth = screenSize.width;
	
	//centraliza o frame na tela
	
	setSize(screenWidth / 2, screenHeight / 2);
	setLocation(screenWidth / 4, screenHeight);
	
}

public void atualiza()
{
	this.repaint();
}

}
[/code][code]public class PanelDesenho extends JPanel {
private BufferedImage buffer;

public PanelDesenho(int largura, int altura) {//define a area q sera desenhada
buffer = new BufferedImage(largura, altura, BufferedImage.TYPE_INT_RGB);
setPreferredSize(new Dimension(largura, altura));
Controle.getInstancia().setTelaDesenho(this);//necessario para dar o repaint()
}

public Graphics2D obterGraphics() {
return buffer.createGraphics();//obtem o graphics
}

@Override
public void paintComponent(Graphics g) {
g.drawImage(buffer, 0, 0, null);
}
// add isso
//pinta toda a imagem de branco
public void limparBuffer() {
if (buffer != null) {
Graphics2D g2d = buffer.createGraphics();//obtem o graphics
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, buffer.getWidth(null), buffer.getHeight(null));//limpa o buffer
g2d.dispose();
}
}[/code][quote]Animacao - Classe Abstract apenas com o método anima() também abstrato e o atributo se está ativa ou não a animação. [/quote]
Em algum lugar isso tem q ser implementado

Cria e desenha o no, provavelmente sera chamado no Thread

Fiz algumas alterações

[code]package controle.animacao;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;

public class NoGrafico
{
private No no;
private int x ;
private int y ;
private final int a = 90;
private final int l = 80;

public No getNo() {
	return no;
}
public void setNo(No no) {
	this.no = no;
}

 public int getX() {
	return x;
}

public void setX(int x) {
	this.x = x;
}

public int getY() {
	return y;
}

public void setY(int y) {
	this.y = y;
}

public synchronized Point getPosicao(){
	Point retorno = new Point();
	
	retorno.x = x;
	retorno.y = y;
	
	return retorno;
}

public void desenha(Graphics2D g2d)
{	
	if (no!=null)
	{				
		Font font = new Font("monospaced", Font.PLAIN, 8);
		FontMetrics metrics= g2d.getFontMetrics();
		int tamanhoHorizontal = metrics.charsWidth(no.str.toCharArray(), 0, no.str.length());
		int tamanhoVertical = metrics.getHeight();
		
		g2d.drawRect(getX(), getY(), tamanhoHorizontal +2*no.getBordahorizont(),tamanhoVertical);
		g2d.drawString(no.str, getX()+no.getBordahorizont(), getY()+tamanhoVertical);
	}
}

}[/code][quote]Controle - Controla todos os componentes do projeto, essa classe é quem distribui o que vai fazer o que e na ordem certa, também temos o controle [/quote][code]package controle;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.List;

import controle.animacao.ControleAnimacao;
import controle.animacao.No;
import controle.animacao.NoGrafico;

public class Controle {

private int posicaoXAtual, posicaoYAtual;
private static Controle instancia = new Controle();
private List<NoGrafico> desenhosNos;
private static final int PAUSA_ANIMACAO = 300;


public Controle(){
	posicaoXAtual = 200;
	posicaoYAtual = 200;
	NoGrafico no = null;
	no.setX(posicaoXAtual);
	no.setY(posicaoYAtual);
}

public void CriaNo(No no){
	//Cria o No Grafico associado
	//Associa uma animacao a ele
	//Coloca na lista de animacoes
}

public void RemoveNo(No no){
	
}

public static Controle getInstancia() {
	return instancia;
}

   private PanelDesenho tela;
   
  public void setTelaDesenho(PanelDesenho tela) {
      this.tela = tela;
  }


//Este método deve ser utilizado no método de desenho para atualizar as imagens
//o ideal é rodá-lo dentro de uma Thread...
public void desenhaNos(){
            tela.limparBuffer();//pinta tudo de branco
	Graphics2D g = tela.obterGraphics();
	ControleAnimacao controleAnimacao = ControleAnimacao.getInstancia();
	
	//Dispara as animacoes
	controleAnimacao.anima();
	
	//Desenha os nos após animados
	synchronized(desenhosNos){
		for (NoGrafico no:desenhosNos){
			no.desenha(g);
		}
	}
            g.dispose();
            tela.repaint();//avisa q a imagem foi alterada
}

}[/code][code]public class ThreadDaAplicacao extends Thread {
public void run() {
while(true) {//loop infinito
Controle controle = Controle.getInstancia();

controle.desenhaNos();
    Thread.sleep(TEMPO DE ESPERA);
}

}
}[/code]

agora o main

public static void main(String[] args) { JanelaPrincipal jp = new JanelaPrincipal(); PanelDesenho pd = new PanelDesenho(500,500); jp.getContentPane().add(pd); jp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jp.pack(); jp.setVisible(true); ThreadDaAplicacao t = new ThreadDaAplicacao(); t.start(); }
as outras classes, axo q n precisam ser alteradas, axo q com isso ja ada pra fzar funcionar

ThreadDaAplicacao t = new ThreadDaAplicacao();

essa linha não funcionou e não to entendendo o porque…=/

como adiciono uma lista de animação em um frame.
do tipo frame.add(lista)