Olá,
O programa a seguir exibe uma imagem de um arquivo png que pode ser arrastada no painel.
Problemas:
- Se vc clicar em qualquer lugar do painel e arrastar o mouse, a imagem irá se teleportar para onde o mouse está.
- Como adicionar mais imagens para que todas possam ser movimentadas livremente pelo painel, arrastando o mouse.
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Painel extends JPanel
{
Toolkit toolkit = Toolkit.getDefaultToolkit();
Image image = toolkit.getImage(getClass().getResource("imagemPequena.png"));
ImageIcon icon = new ImageIcon(image); // linha necessaria para ter retorno
// correto dos metodos getWidth e getHeight da classe Image. Porque e necessario?
// se comentar essa linha os metodos get listados acima retornam 0
int x; // posicao x da imagem no painel
int y; // posicao y da imagem no painel
int w; // coordenada x do centro da imagem
int h; // coordenada y do centro da imagem
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, x, y, null);
}
public Painel()
{
x = 0; // posicao inicial da imagem em x
y = 0; // posicao inicial da imagem em y
w = image.getWidth(null)/2; // coordenada x do centro da imagem
h = image.getHeight(null)/2; // coordenada y do centro da imagem
addMouseMotionListener(new Handler1()); // adicionando Handler
}
class Handler1 implements MouseMotionListener
{
@Override
public void mouseDragged(MouseEvent event)
{
// pega as coordenadas do mouse e centraliza a imagem no mouse quando for arrastar
x = event.getX() - w;
y = event.getY() - h;
repaint();
}
@Override
public void mouseMoved(MouseEvent me)
{
}
}
}
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
// Classe Main
public class Main
{
public static void main( String[] args )
{
JFrame application = new JFrame( "Programa" );
Painel painel = new Painel();
application.add( painel, BorderLayout.CENTER );
application.add( new JLabel( "Mensagem de fundo" ), BorderLayout.SOUTH );
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
application.setSize( 600, 400 );
application.setVisible( true );
}
}
Obrigado a quem se interessar em me ajudar.
Ten ha uma lsita de Image invés de uma unica.
E sobre o ImageIcon ali, carregue a imagem através da classe ImageIO que retorna um BufferedImage, esta contém os métodos getWidth e getHeight que funcionam corretamente,
Obrigado por responder.
Ainda continuo com os problemas iniciais.
Ao arrastar o mouse em um local que a imagem não está, não deveria acontecer nada, no entanto a imagem teleporta para o mouse.
Uma solução que pensei, ao invés de desenhar diretamente a imagem no JPanel, eu a colocaria no JLabel e depois colocaria este JLabel no JPanel.
Qual a vantagem que vi nisso? Poder setar evento no JLabel para que eu saiba se o mouse está em cima do JLabel para autorizar o movimento de arrastar a imagem e com isso eliminaria o problema inicial de teleporte de imagens, quando se arrasta o mouse fora da área da imagem.
Qual o problema que vi nisso? Será que é realmente necessário eu adicionar minhas imagens em vários JLabels para depois colocá-las no JPanel, para poder mover JLabels pelo JPanel que é o painel central?
Será que é possível desenhar as imagens diretamente no JPanel controlando eventos isolados para cada uma? Afinal eu quero adicionar várias imagens no painel e poder movê-las com o mouse livremente arrastando elas.
Valeu.
Neste código serão carregadas 3 imagens de arquivos png no JPanel.
Dúvida:
Como poder arrastar livremente qualquer uma das imagens carregadas no JPanel?
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Painel extends JPanel
{
Point[] locations = new Point[3];
BufferedImage[] images = new BufferedImage[3];
public Painel()
{
// Posicoes iniciais das imagens
locations[0] = new Point(0, 0);
locations[1] = new Point(200, 0);
locations[2] = new Point(0, 160);
try
{
//Carregando imagens
URL url = this.getClass().getResource("imagemPequena0.png");
BufferedImage img = ImageIO.read(url);
images[0] = img;
url = this.getClass().getResource("imagemPequena1.png");
img = ImageIO.read(url);
images[1] = img;
url = this.getClass().getResource("imagemPequena2.png");
img = ImageIO.read(url);
images[2] = img;
}
catch (IOException e)
{
}
addMouseMotionListener(new Handler1()); // adicionando Handler
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
// Desenhando imagens de acordo com as posicoes setadas
for(int i = 0; i < images.length; i++)
{
BufferedImage bi = images[i];
Point p = locations[i];
g.drawImage(bi, p.x, p.y, null);
}
}
class Handler1 implements MouseMotionListener
{
@Override
public void mouseDragged(MouseEvent event)
{
}
@Override
public void mouseMoved(MouseEvent me)
{
}
}
}
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
// Classe Main
public class Main
{
public static void main( String[] args )
{
JFrame application = new JFrame( "Programa" );
Painel painel = new Painel();
application.add( painel, BorderLayout.CENTER );
application.add( new JLabel( "Mensagem de fundo" ), BorderLayout.SOUTH );
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
application.setSize( 600, 400 );
application.setVisible( true );
}
}
Obrigado por ter lido.
Guarde a posição das imagens e interaja com a correta baseada no ACTION_DOWN do MouseEvent.
Estou pesquisando sobre o ACTION_DOWN e só encontrei referências para o desenvolvimento para Android ou seja em dispositivo touch screen.
Vc poderia indicar algo para eu ler ou enviar um exemplo?
Talvez esteja falando do mouseClicked do MouseListener. É isso?
O problema maior que enfrento é:
Quem dispara o evento é o JPanel, não são as imagens. Se cada imagem disparasse seu próprio evento e o JPanel recebesse as novas posições e redesenhasse o painel, seria uma solução para mim.
Obrigado pela ajuda.
Desculpe, eu quis dizer o MouseMotionListener e comparar com MOUSE_PRESSED, a idéia é a mesma.
E o JPanel mesmo que vai continuar recebendo os eventos, as imagens você que vai desenhar.
[quote=Marky.Vasconcelos]Desculpe, eu quis dizer o MouseMotionListener e comparar com MOUSE_PRESSED, a idéia é a mesma.
E o JPanel mesmo que vai continuar recebendo os eventos, as imagens você que vai desenhar.[/quote]
Trabalhando na solução.
Obrigado pela ajuda.
Não sei se vc achou solução cara, mas pra quem não achou aí abaixo vai um código que estou desenvolvendo. Talvez ajude mais alguém.
Estou com um problema apenas. A imagem adicionada fica piscando quando movimentada. O que eu poderia fazer?
[code]import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Mesas extends JPanel {
JLabel bg, objeto;
public Mesas() { //Painel
setLayout(null);
objeto = new JLabel();
objeto.setBounds(new Rectangle(0, 0, 300, 284));
objeto.addMouseMotionListener(new MouseAdapter() { //movimenta o objeto
@Override
public void mouseDragged(MouseEvent e) {
moveLabel(e.getX(),e.getY());
}
});
add(objeto);
bg = new JLabel(new ImageIcon(this.getClass().getResource("/bg.jpg")));
bg.setBounds(0,-10,2000,1500);
add(bg);
}
public void addMesas(String url) { //adiciona um objeto do tipo image
objeto.setIcon(new ImageIcon(this.getClass().getResource(url)));
}
public void moveLabel(int x, int y) {
objeto.setLocation(x,y);
objeto.repaint();
}
}[/code]