Przesuwanie JLabela

0

Witam,
chcialem napisac applet , w ktorym za pomoca myszki mozna przesuwac poszczegolne graficzne komponenty. Oto co do tej pory udalo mi sie skodzic:

import javax.swing.;
import java.awt.
;
import java.awt.event.*;

public class panl extends JPanel implements MouseMotionListener
{
ImageIcon obraz;
JLabel etyk;

int m;
int n;

public panl()
{
	setLayout(null);
    setBackground(Color.white);
           
    obraz = new ImageIcon("button.gif");
    etyk = new JLabel(obraz);
    etyk.setBounds(50, 50, 30, 30);
    add(etyk);
    
    setVisible(true);
    addMouseMotionListener(this);
         
}

public void mouseMoved(MouseEvent evt)
{
}
public void mouseDragged(MouseEvent evt)
{
	
	m = evt.getX();
	n = evt.getY();
	if(etyk.contains(m, n))
	{
	etyk.setBounds(m, n, 30, 30);
	}		
}

}

Problem polega na tym, ze "etyk.contains" sprawdza, czy m i n jest zawarte nie w rzeczywistym polozeniu JLabela etyk, ustawionym przez setBounds, ale traktuje go, jakby znajdowal sie na poczatku ukladu wspolrzednych (w lewym gornym rogu). Przez to obrazek zmienia swoje polozenie nie po klikniecu na obrazek, ale po klikniecu na pole ograniczone przez setBounds, rozpoczynajace sie w punktach 0,0.

Byc moze "etyk.contains" jest zlym rozwiazaniem. Probowalem z "etyk.addMotionListener(this)". Rzeczywiscie - komponent przesuwal sie dopiero po kliknieciu na niego myszka, jednak zaczynal wowczas "wariowac", czyli pojawiac sie w roznych miejscach. Mysle, ze jest to spowodowane tym, ze wspolrzedne kursora sa odczytywane w takim przypadku tylko z tego komponentu, a nie z calego panela, przez co maja wartosci np. minusowe, ktore se przypisywane do m i n.

Prosze o propozycje rozwiazania problemu.

Pozdrawiam.

0

Osobiście nigdy nie używam mouseDragged z dwóch powodów:

  1. Komunikat wlczenia jest wtórny w stosunku do najbardziej pierwotnych komunikatów wciśnięcia i przesuwania
  2. "Due to platform-dependent Drag&Drop implementations, MOUSE_DRAGGED events may not be delivered during a native Drag&Drop operation"

Krótko mówiąc słaba kontrola tego czym jest konkretne wleczenie i tragiczna przenośność.
Dlatego najlepiej mieć pełną kontrolę nad myszą - początkiem wleczenia, kolejnymi przesunięciami i zakończeniem wleczenia.
Tu masz kod (najważniejszy fragment) dwóch listenerów, które łącznie powodują przesuwanie dowolnego komponentu na ekranie przez wleczenie myszą na jego powierzchni. Działają dla każdego okna top-level, ale również powinny działać dla każdego komponentu po zmianie przeliczania lokacji z ekranowej na lokalną.
Przy okazji prawy klawisz myszy zamyka okno (to można usunąć).

	private Point punktWleczenia = new Point();

	private class SłuchaczMyszy extends MouseAdapter
	{
		@Override public void mousePressed( MouseEvent e )
		{
			switch( e.getButton() )
			{
				case MouseEvent.BUTTON1: //ustala punkt zaczepienia
					punktWleczenia.x = e.getX();
					punktWleczenia.y = e.getY();
					break;
				case MouseEvent.BUTTON2: //zamyka okno
					dispose();
					break;
			}
		}
	}
	private class SłuchaczRuchuMyszy extends MouseMotionAdapter
	{
		@Override public void mouseDragged(MouseEvent e)
		{
			//przykład maski koniecznie wciśniętych
			int ustawione = InputEvent.BUTTON1_DOWN_MASK;
			//przykład maski koniecznie puszczonych
			int zwolnione =
				InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK;
			int maska = ustawione | zwolnione;
			//zmiana położenia okna gdy wleczenie LPM bez ctrl i shift
			if( (e.getModifiersEx() & maska) == ustawione )
				//ustawia lokację okna we wsp. ekranu względem punktu zaczepienia.
				setLocation(e.getXOnScreen() - punktWleczenia.x,
					e.getYOnScreen() - punktWleczenia.y);
		}
	}

1 użytkowników online, w tym zalogowanych: 0, gości: 1