Criar uma bola que se movimente no JFrame

9 respostas
F

Ola,
preciso fazer um programa, utilizando threads(public class Bola extends JFrame implements Runnable), q faça uma bola se movimentar no frame a partir do lugar onde
o usuario clicar com o mouse.
a bola aparece, porem, ao movimentar-se o programa nao apaga as bolas anteriores, alguem tem alguma sugestao de codigo para me ajudar?

9 Respostas

L

talvez isto possa lhe ajudar: http://faq.javaranch.com/java/CodeBarnApplets

T

Fiz no Netbeans veja se ajuda você.

/*
 * JFrame.java
 *
 * Created on 13 de Março de 2008, 14:07
 */

package view;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

/**
 *
 * @author  Rogério Tomassoni
 */
public class JFrame extends javax.swing.JFrame implements Runnable{
    private static Thread thProcesso;
    private int mouseX;
    private int mouseY;
    
    
    /**
     * Creates new form JFrame
     */
    public JFrame() {
        initComponents();
        this.setLocationRelativeTo(null);
        
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">                          
    private void initComponents() {
        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        jPanel1.setBackground(new java.awt.Color(255, 255, 255));
        jPanel1.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                JFrame.this.mouseClicked(evt);
            }
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                JFrame.this.mouseReleased(evt);
            }
        });
        jPanel1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                JFrame.this.mouseDragged(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 380, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 281, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 17, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
        pack();
    }// </editor-fold>                        
    
    private void mouseReleased(java.awt.event.MouseEvent evt) {                               
        if(thProcesso.isAlive())
            thProcesso.interrupt();
    }                              
    
    private void mouseDragged(java.awt.event.MouseEvent evt) {                              
        mouseX = evt.getX();
        mouseY = evt.getY();
        this.desenhaCirculo(mouseX,mouseY, Color.BLUE);
        jLabel1.setText("x: " + mouseX + " y:" + mouseY);
    }                             
    
    private void mouseClicked(java.awt.event.MouseEvent evt) {                              
        mouseX = evt.getX();
        mouseY = evt.getY();
        this.desenhaCirculo(mouseX,mouseY, Color.RED);
        jLabel1.setText("x: " + mouseX + " y:" + mouseY);
        thProcesso.start();
    }                             
    
    
    
    private void desenhaCirculo(int x, int y, Color color){
        Graphics grf = this.jPanel1.getGraphics();
        grf.setColor(color);
        grf.drawOval(x,y,50,50);//x y
    }
    
    public void run() {
        
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame jfrm = new JFrame();
                thProcesso = new Thread(jfrm);
                jfrm.setVisible(true);
            }
        });
    }
    
    // Variables declaration - do not modify                     
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    // End of variables declaration                   
    
    
    
}
M

Cara sinceramente eu tenho nojo do que o NetBeans joga no código, eu tenho mais trabalho usando o AbsoluteLayout na mão, mas o código fica bem mais limpo, fáçil compreendimento e manutenção (Não incluo fazer mudanças graves de posicionamento pois tudo deve ser setado através de um mapa cartesiano da tela (x,y)).

Posta o código para vermos aonde está errando.

Uma sugestão é que você está sobreescrevendo o método paintComponent ou paint dessa maneira:

public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g.create();
//métodos para pintar a bolinha no graphics2D
g2d.dispose();
}

Se for, chame o método da classe pai para limpar a tela.

public void paintComponent(Graphics g){
super.paintComponent(g); //&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;^^
Graphics2D g2d = (Graphics2D) g.create();
//métodos para pintar a bolinha no graphics2D
g2d.dispose();
}

Caso não for este, realmente poste o código pois se não, fica difíçil ajudar.

F

olha, agradeço ai pela ajuda de voces, porem, meu conhecimento em java ainda eh muito basico , portanto os codigos acima ainda nao entendo,nem posso usar, postarei o meu codigo aqui, ele tem alguns erros sim, ainda nao sei quais sao, mas ele ta gerando varias frames, e eu nao consigo fazer a bola voltar no sentido contrario.
ai esta..

import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.event.*;
import java.util.concurrent.*;

public class Bola extends JFrame implements Runnable
{
	int x1,x2,y1,y2;
	boolean teste=true;
	Bola()
	{
		super("Linhas com o Mouse");
		x1=x2=y1=y2=0;

		addMouseListener
		(
			new MouseAdapter()
			{
				public void mousePressed(MouseEvent event)
				{
					x1=event.getX();
					y1=event.getY();

				}
				public void mouseReleased(MouseEvent event)
				{
					x2=event.getX();
					y2=event.getY();
					repaint();
				}
			}
		);
		setSize(400,200);
		setVisible(true);
	}

	public void paint(Graphics g)
	{
		if(teste)
		{
			super.paint(g);
			teste=false;
		}


		g.fillOval(x1,y1,20,20);

		int inicio=1;

		while(inicio<2)
		{

		for(int i=1; i<=15; i++)
			{
			x1++;
			repaint();
			inicio++;
			}
		}

		while(inicio<3)
		{

			for(int j=1; j<=30; j++)
			{
				x1--;

				inicio++;
			}
		}


		while(inicio==3)
		{
			for (int l=1; l<=30; l++)
			{
			x1++;
			inicio--;
			}
		}


	}



	public void run()
{

	while(true)
	    {


		try{
			Bola bola=new Bola();

			Thread.sleep(1000);

			}



	catch (Exception e)
	{
	System.out.println("erro");}

	    }
}


	public static void main(String args[])
	{

		Bola r1= new Bola();
		ExecutorService te= Executors.newFixedThreadPool(2);
		te.execute(r1);
		te.shutdown();
		Bola app = new Bola();
		app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
	}
}
M
frenkba:
olha, agradeço ai pela ajuda de voces, porem, meu conhecimento em java ainda eh muito basico , portanto os codigos acima ainda nao entendo,nem posso usar, postarei o meu codigo aqui, ele tem alguns erros sim, ainda nao sei quais sao, mas ele ta gerando varias frames, e eu nao consigo fazer a bola voltar no sentido contrario. ai esta..
import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.event.*;
import java.util.concurrent.*;

public class Bola extends JFrame implements Runnable
{
	int x1,x2,y1,y2;
	boolean teste=true;
	Bola()
	{
		super("Linhas com o Mouse");
		x1=x2=y1=y2=0;

		addMouseListener
		(
			new MouseAdapter()
			{
				public void mousePressed(MouseEvent event)
				{
					x1=event.getX();
					y1=event.getY();

				}
				public void mouseReleased(MouseEvent event)
				{
					x2=event.getX();
					y2=event.getY();
					repaint();
				}
			}
		);
		setSize(400,200);
		setVisible(true);
	}

	public void paint(Graphics g)
	{
		if(teste)
		{
			super.paint(g);
			teste=false;
		}


		g.fillOval(x1,y1,20,20);

		int inicio=1;

		while(inicio<2)
		{

		for(int i=1; i<=15; i++)
			{
			x1++;
			repaint();
			inicio++;
			}
		}

		while(inicio<3)
		{

			for(int j=1; j<=30; j++)
			{
				x1--;

				inicio++;
			}
		}


		while(inicio==3)
		{
			for (int l=1; l<=30; l++)
			{
			x1++;
			inicio--;
			}
		}


	}



	public void run()
{

	while(true)
	    {


		try{
			Bola bola=new Bola();

			Thread.sleep(1000);

			}



	catch (Exception e)
	{
	System.out.println("erro");}

	    }
}


	public static void main(String args[])
	{

		Bola r1= new Bola();
		ExecutorService te= Executors.newFixedThreadPool(2);
		te.execute(r1);
		te.shutdown();
		Bola app = new Bola();
		app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
	}
}

Vou comentar por partes:
Vamos lá:

Por que a tela não limpa as outras bolas?

if(teste)
		{
			super.paint(g);
			teste=false;
		}

Por que o chamado a super.paint é feito apenas uma vez? (Pois na proxima vez o teste vai ser false
Ele repinta a tela e limpa o que foi desenhado antes

Substitua para:
super.paint(g);
Assim a cada iteração a tela vai ser limpa

Por que abre um monte de tela?

while(true)
	    {


		try{
			Bola bola=new Bola();

			Thread.sleep(1000);

			}



	catch (Exception e)
	{
	System.out.println("erro");}
while(true) enquanto for verdadeiro

Esse método vai sempre criar novos objetos de Bola,
Bola extends JFrame, logo você criara uma nova tela para cada vez que isso for chamado.

Substitua para isso:
while(true)
	    {


		try{
			repaint();

			Thread.sleep(1000);

			}



	catch (Exception e)
	{
	System.out.println("erro");}

Agora o método só repinta a tela e não cria uma nova toda hora.

Isso já resolve alguns dos seus problemas.

Agora para fazer a bolinha voltar

Se a posição da bola x e y chegar na borda direita faça o valor de x e y ir diminuindo (--) e se chegar na borda esquerda aumentar(++)

F

opa!..
ta ficando melhor o programa, porem, a bola esta se movimentando rapido demais no jframe, e mesmo eu aumentando ou diminuindo as variaveis x e y, ainda nao consigo fazer com que ela volte…
vlw

V

Lembre-se da física:

Deslocamento = velocidade * tempo;

Então, primeiro você deve calcular o tempo entre duas chamadas ao seu método de desenhar a bolinha. Com esse tempo na mão, basta multiplicar pelo velocidade que a bola tem na sua escala de tempo.

Por exemplo:

Se o tempo for de 900 milis, e a bola deve se deslocar 5 pixels a cada segundo, você deve fazer:

Sem levar em consideração o tempo, vai ser muito difícil desenhar uma bolinha que se mova de maneira suave e uniforme.

F
opa e ai galera blza?

ja consigo fazer com que a bola se movimente suavemente na tela

mas nao consigo fazer com que ela volte!

olhem so o codigo atual:

import javax.swing.JFrame;

import java.awt.Graphics;

import java.awt.event.<em>;

import java.util.concurrent.</em>;
public class Bola extends JFrame implements Runnable
{
	int x1,x2,y1,y2;
	
	Bola()
	{
		super("Linhas com o Mouse");
		x1=x2=y1=y2=0;

		addMouseListener
		(
			new MouseAdapter()
			{
				public void mousePressed(MouseEvent event)
				{
					x1=event.getX();
					y1=event.getY();

				}
				public void mouseReleased(MouseEvent event)
				{
					x2=event.getX();
					y2=event.getY();
					repaint();
				}
			}
		);
		setSize(400,200);
		setVisible(true);
	}

	public void paint(Graphics g)
	{
		
		
			super.paint(g);
			
		
		g.fillOval(x1,y1,20,20);

	
			
			
			try
			{
			
			Thread.sleep(10);			
			x1++;
			repaint();
			
			}
			catch (Exception e){}
			
			
		

	}



	public void run()
{

	while(true)
	    {


		try{
			repaint();
			Thread.sleep(1000);

			}



	catch (Exception e)
	{
	System.out.println("erro");}

	    }
}








	public static void main(String args[])
	{

		Bola r1= new Bola();
		ExecutorService te= Executors.newFixedThreadPool(2);
		te.execute(r1);
		te.shutdown();


		Bola app = new Bola();
		app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
	}
}

tentei alterar este trecho,

try
			{
			
			Thread.sleep(10);			
			x1++;
			repaint();
			
			}
			catch (Exception e){}

para isto…

try
	{
			while(x1<3000
			{
                        Thread.sleep(10);			
			x1++;
			repaint();
			}
                        while(x1>00
                        {
                        Thread.sleep(10);			
			x1++;
			repaint();}
	}
			catch (Exception e){}
F

ae galera, agradeço a atenção de voces, mas consegui resolver o problema,
porem, agora tenho que modificar este codigo para que quando eu clicar no jframe ele crie outra bola em vez de redesenhar a primeira em outro lugar.
segue o codigo(a bola ja volta quando chega no limite do frame)

import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.event.*;
import java.util.concurrent.*;

public class Bola extends JFrame implements Runnable
{
	int x1,x2,y1,y2;
	int c=300;
	Bola()
	{
		super("Linhas com o Mouse");


		addMouseListener
		(
			new MouseAdapter()
			{
				public void mousePressed(MouseEvent event)
				{
					x1=event.getX();
					y1=event.getY();

				}
				public void mouseReleased(MouseEvent event)
				{
					x2=event.getX();
					y2=event.getY();
					repaint();
				}
			}
		);
		setSize(400,200);
		setVisible(true);
	}

	public void paint(Graphics g)
	{
			try
			{
			
			Thread.sleep(1);			
		super.paint(g);
			repaint();
			
			}
			catch (Exception e){}
		
		
			
			
		
		g.fillOval(x1,y1,20,20);
			if(x1<c)
			{x1++;
			}
			
			if(x1==299)
			{
				x1=299;
				c=5;
			}
			if(x1>c)
			{
				
				x1--;
				
			}
			if(x1==c)
			{c=300;
			}
			
			
		

	}



	public void run()
{

	while(true)
	    {


		try{
			repaint();
			Thread.sleep(1000);

			}



	catch (Exception e)
	{
	System.out.println("erro");}

	    }
}








	public static void main(String args[])
	{

		Bola r1= new Bola();
		ExecutorService te= Executors.newFixedThreadPool(2);
		te.execute(r1);
		te.shutdown();


		Bola app = new Bola();
		app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );
	}
}
Criado 13 de março de 2008
Ultima resposta 25 de mar. de 2008
Respostas 9
Participantes 5