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.
importjava.awt.Graphics;importjava.awt.Image;importjava.awt.Toolkit;importjava.awt.event.MouseEvent;importjava.awt.event.MouseMotionListener;importjavax.swing.ImageIcon;importjavax.swing.JPanel;publicclassPainelextendsJPanel{Toolkittoolkit=Toolkit.getDefaultToolkit();Imageimage=toolkit.getImage(getClass().getResource("imagemPequena.png"));ImageIconicon=newImageIcon(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 0intx;// posicao x da imagem no painelinty;// posicao y da imagem no painel intw;// coordenada x do centro da imageminth;// coordenada y do centro da imagem@OverrideprotectedvoidpaintComponent(Graphicsg){super.paintComponent(g);g.drawImage(image,x,y,null);}publicPainel(){x=0;// posicao inicial da imagem em xy=0;// posicao inicial da imagem em yw=image.getWidth(null)/2;// coordenada x do centro da imagemh=image.getHeight(null)/2;// coordenada y do centro da imagemaddMouseMotionListener(newHandler1());// adicionando Handler}classHandler1implementsMouseMotionListener{@OverridepublicvoidmouseDragged(MouseEventevent){// pega as coordenadas do mouse e centraliza a imagem no mouse quando for arrastar x=event.getX()-w;y=event.getY()-h;repaint();}@OverridepublicvoidmouseMoved(MouseEventme){}}}
importjava.awt.BorderLayout;importjavax.swing.JFrame;importjavax.swing.JLabel;// Classe MainpublicclassMain{publicstaticvoidmain(String[]args){JFrameapplication=newJFrame("Programa");Painelpainel=newPainel();application.add(painel,BorderLayout.CENTER);application.add(newJLabel("Mensagem de fundo"),BorderLayout.SOUTH);application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);application.setSize(600,400);application.setVisible(true);}}
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,
J
Jack_Java
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.
J
Jack_Java
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?
importjava.awt.Graphics;importjava.awt.Point;importjava.awt.event.MouseEvent;importjava.awt.event.MouseMotionListener;importjava.awt.image.BufferedImage;importjava.io.IOException;importjava.net.URL;importjavax.imageio.ImageIO;importjavax.swing.JPanel;publicclassPainelextendsJPanel{Point[]locations=newPoint[3];BufferedImage[]images=newBufferedImage[3];publicPainel(){// Posicoes iniciais das imagenslocations[0]=newPoint(0,0);locations[1]=newPoint(200,0);locations[2]=newPoint(0,160);try{//Carregando imagensURLurl=this.getClass().getResource("imagemPequena0.png");BufferedImageimg=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(IOExceptione){}addMouseMotionListener(newHandler1());// adicionando Handler}@OverrideprotectedvoidpaintComponent(Graphicsg){super.paintComponent(g);// Desenhando imagens de acordo com as posicoes setadasfor(inti=0;i<images.length;i++){BufferedImagebi=images[i];Pointp=locations[i];g.drawImage(bi,p.x,p.y,null);}}classHandler1implementsMouseMotionListener{@OverridepublicvoidmouseDragged(MouseEventevent){}@OverridepublicvoidmouseMoved(MouseEventme){}}}
importjava.awt.BorderLayout;importjavax.swing.JFrame;importjavax.swing.JLabel;// Classe MainpublicclassMain{publicstaticvoidmain(String[]args){JFrameapplication=newJFrame("Programa");Painelpainel=newPainel();application.add(painel,BorderLayout.CENTER);application.add(newJLabel("Mensagem de fundo"),BorderLayout.SOUTH);application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);application.setSize(600,400);application.setVisible(true);}}
Obrigado por ter lido.
M
Marky.Vasconcelos
Guarde a posição das imagens e interaja com a correta baseada no ACTION_DOWN do MouseEvent.
J
Jack_Java
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.
M
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.
J
Jack_Java
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.
Trabalhando na solução.
Obrigado pela ajuda.
P
PauloRobertoAC
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?
importjava.awt.*;importjava.awt.event.MouseAdapter;importjava.awt.event.MouseEvent;importjavax.swing.ImageIcon;importjavax.swing.JLabel;importjavax.swing.JPanel;publicclassMesasextendsJPanel{JLabelbg,objeto;publicMesas(){//PainelsetLayout(null);objeto=newJLabel();objeto.setBounds(newRectangle(0,0,300,284));objeto.addMouseMotionListener(newMouseAdapter(){//movimenta o objeto@OverridepublicvoidmouseDragged(MouseEvente){moveLabel(e.getX(),e.getY());}});add(objeto);bg=newJLabel(newImageIcon(this.getClass().getResource("/bg.jpg")));bg.setBounds(0,-10,2000,1500);add(bg);}publicvoidaddMesas(Stringurl){//adiciona um objeto do tipo imageobjeto.setIcon(newImageIcon(this.getClass().getResource(url)));}publicvoidmoveLabel(intx,inty){objeto.setLocation(x,y);objeto.repaint();}}