Mapear área clicavel

4 respostas
P

Olá galera,…

Quero saber se é possível mapear uma área na tela de um JFrame e torna-la clicavel…

É pq tenho uma img de fundo e queria mapear partes dessa imagem, e ao clicar em determinas partes, acorrece algum evento…
Mas para isso precisaria de um mapeamento perfeito…
É possível fazer isso com elementos 2D???

Exemplo: criar um retangulo, posiciona-lo exatamente em um local da tela e torna-lo clicavel, mas seria mt importante q se atribuisse a esse retangulo transparência… para aparecer somente a img de fundo…

Na verdade eu quero a possibilidade de mapear a tal img, e atribuir evento a esse mapa…

Poxa… é possivel até em HTMl…
Provavelmete JAVA deve ter algo que possibilite isso tb… Java é Java … né?? E eu iniciante…rsrsrs

Valew galera…
Abração!!!

4 Respostas

_

Hum, não sei se tem algo pronto, mas faria algo como:

public class Test
{
	public static void main( String args[] )
	{
		JFrame frame = new JFrame();

		JPanel panel = new JPanel();
		panel.setLayout( null );

		ImageIcon icon = new ImageIcon( "d:/image.jpg" );
		int width = icon.getIconWidth();
		int height = icon.getIconHeight();
		JLabel image = new JLabel( icon );
		image.setBounds( 0, 0, width, height );

		JPanel areaClicavel1 = new JPanel();
		areaClicavel1.setName( "área 1" );
		// para teste
		areaClicavel1.setBackground( Color.CYAN );
		areaClicavel1.setBounds( 10, 20, 50, 50 );
		areaClicavel1.addMouseListener( getMouseListener() );

		JPanel areaClicavel2 = new JPanel();
		areaClicavel2.setName( "área 2" );
		areaClicavel2.setBackground( Color.BLACK );
		areaClicavel2.setBounds( 30, 60, 40, 40 );
		areaClicavel2.addMouseListener( getMouseListener() );

		panel.add( areaClicavel1 );
		panel.add( areaClicavel2 );

		panel.add( image );

		frame.setSize( width, height );
		frame.add( panel );
		frame.setLocationRelativeTo( null );

		frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
		frame.setVisible( true );
	}

	private static MouseListener getMouseListener()
	{
		return new MouseAdapter()
		{
			@Override
			public void mouseClicked( MouseEvent e )
			{
				System.out.println( ( ( JComponent ) e.getSource() ).getName() );
			}
		};
	}
}

Se você precisa de mais formas do que um simples quadrado seria necessário fazer um esquema um bom tanto mais complexo que guardaria uma Collection de objetos java.awt.Shape. Quando a JLabel com a imagem recebesse um click, iteraria sobre a collection e chamaria o método Shape.contains( x, y ) passando as coordenadas do evento.
Então, baseado num mapeamento Shape <-> ação, o método pertinente seria invocado.

_

Hum, achei interessante o problema e resolvi inventar um treco aqui:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ImageMapper extends JPanel
{
	private ImageIcon image;
	private List< ActionShape > shapes;

	private boolean debugMode = true;
	
	public ImageMapper( ImageIcon image, List< ActionShape > shapes )
	{
		this.image = image;
		this.shapes = shapes;

		JLabel label = new JLabel( image );
		add( label );
		label.addMouseListener( new MouseAdapter()
		{
			@Override
			public void mouseClicked( MouseEvent e )
			{
				handleClick( e.getX(), e.getY() );
			}

		} );
	}

	private void handleClick( int x, int y )
	{
		Point point = new Point( x, y );
		
		for( ActionShape shapeAction : shapes )
		{
			// continua iterando mesmo se encontra o ponto certo
			// pois podem haver Shapes que se sobrepõe
			if( shapeAction.contains( point ) )
				shapeAction.invoke();
		}
	}

	@Override
	public void paint( Graphics g )
	{
		super.paint( g );
		
		if( debugMode )
		{
			Graphics2D g2d = ( Graphics2D ) g;
		
			for( ActionShape shapeAction : shapes )
				shapeAction.paint( g2d );
		}
	}	
}

class ActionShape
{
	public Shape shape;
	private ActionListener listener;

	public ActionShape( Shape shape, ActionListener listener )
	{
		this.shape = shape;
		this.listener = listener;
	}
	
	// para debug
	public void paint( Graphics2D graphics )
	{
		graphics.fill( shape );
	}
	
	public boolean contains( Point p )
	{
		return shape.contains( p );
	}
	
	// deve ser reescrito para atender a sua necessidade
	// por hora usando porcamente ActionListener
	public void invoke()
	{
		listener.actionPerformed( null );
	}
}

E a classe para teste:

import java.awt.BorderLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.GeneralPath;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JFrame;

public class ImageMapperTest
{
	public static void main( String args[] )
	{
		JFrame frame = new JFrame();

		ImageIcon icon = new ImageIcon( "d:/lipe/temp/hand.jpg" );

		List< ActionShape > shapes = new ArrayList< ActionShape >();

		shapes.add( new ActionShape( new Rectangle( 10, 10, 50, 50 ),
				new ActionListener()
				{
					public void actionPerformed( ActionEvent e )
					{
						method1();
					}
				} ) );

		GeneralPath path = new GeneralPath();
		path.moveTo( 100, 100 );
		path.lineTo( 200, 200 );
		path.curveTo( 200, 200, 150, 250, 100, 200 );
		path.closePath();
		shapes.add( new ActionShape( path, new ActionListener()
		{
			public void actionPerformed( ActionEvent e )
			{
				method2();
			}
		} ) );

		ImageMapper mapper = new ImageMapper( icon, shapes);

		frame.setLayout( new BorderLayout() );
		frame.add( mapper, BorderLayout.CENTER );
		frame.pack();
		
		frame.setLocationRelativeTo( null );

		frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
		frame.setVisible( true );
	}

	public static void method1()
	{
		System.out.println( "method1()" );
	}

	public static void method2()
	{
		System.out.println( "method2()" );
	}
}
C

Criar um JButton com um icone não resolve ?

P

Valew Filipe…
Ajudou abessa!!!
Mas sabe como é iniciante né…??..rsrs
Tem que ler tudo depois ir no site da sun verificar o q tal coisa faz…rsrsr e assim vai…

Valew mesmo!
Abração!

Criado 2 de maio de 2006
Ultima resposta 2 de mai. de 2006
Respostas 4
Participantes 3