Wyświetlanie pozycji kursora.

0

Witam! Chciałbym prosić was o pomoc przy klepaniu jednego programu. Jego zadaniem jest wyświetlanie aktualnej pozycji kursora. Cały problem leży w tym, że chcę, by czytał on pozycję kursora z całego ekranu. Jeżeli używam takiego np. kodu:

package bot.main;

import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;

public class PositionPointerPanel extends JPanel implements MouseMotionListener {
	private static final long serialVersionUID = 1L;
	private JTextArea textArea;
	
	public PositionPointerPanel() {
		textArea = new JTextArea();
		textArea.setEditable(false);
		
		JScrollPane scrollPane = new JScrollPane(textArea,
				JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		scrollPane.setPreferredSize(new Dimension(800,300));
		this.add(scrollPane);

		this.setPreferredSize(new Dimension(840,340));
		this.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
		
		this.addMouseMotionListener(this);
	}
	
	private void progressOutput(String description, MouseEvent ev) {
		textArea.append(description + " (x,y): (" + ev.getX() + ", " + ev.getY() + ")" + System.getProperty("line.separator"));
		textArea.setCaretPosition(textArea.getDocument().getLength());
	}
	
	public void mouseMoved(MouseEvent ev) {
		progressOutput("Mouse Moved", ev);
	}
	
	public void mouseDragged(MouseEvent ev) {
		progressOutput("Mouse Dragged", ev);
	}
	
    private static void createAndShowGUI() {
        JFrame frame = new JFrame("Position Pointer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        JComponent newContentPane = new PositionPointerPanel();
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);
        
        frame.pack();
        frame.setVisible(true);
    }

	
	public static void main(String[] args) {
		UIManager.put("swing.boldMetal", Boolean.FALSE);
        
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
	}
}

To program wypisuje współrzędne tylko wtedy, gdy mysz porusza się w oknie programu, co jest sensowne, bo to właśnie do tego okna przypisany jest MouseMotionListener. Tylko co zrobić, by MouseMotionListener brał pod uwagę także to, co jest poza oknem?

Z góry dziękuję za wszystkie odpowiedzi =)

0

Ja zacząłbym od poszukania czy JVM Suna nie ma jakiejś udostępnionej metody, która to robi, a na której bazuje AWT, a jeżeli nie to pozostaje chyba tylko JNI/JNA i dostęp do stanu myszy za pomocą API systemu.

0

Raczej niebardzo, pod windą chyba okienka dostają o tym jakieś eventy, a gdzie indziej mogą nie itd.

		Timer t = new Timer();
		
		TimerTask tt = new TimerTask(){
			Point last = MouseInfo.getPointerInfo().getLocation();
			
			public void run() {
				Point p = MouseInfo.getPointerInfo().getLocation();
				if(p.x != last.x || p.y != last.y)
				{
					System.out.println("Mouse moved");
					last = p;
				}
			}
			
		};
		
		t.schedule(tt, 100, 100);

Coś takiego naskrobałem, ale to zjada pamięć, bo ciągle tworzy trochę obiektów...
Oczywiście jvm daje radę, zrobi gc kiedy trzeba, ale pamięć będzie skakać :P

można przez reflection api z toolkita wywoływać getMouseInfoPeer() i kazać mu fillować nasz point, żeby oszczędzić tworzenie obiektów...

0

O tak zjada zdecydowanie mniej pamięci

import java.awt.*;
import java.awt.peer.MouseInfoPeer;
import java.lang.reflect.*;
import java.util.*;

public class MouseInfoPeerHack {

	public static void main(String[] args) throws Exception {
		Timer t = new Timer();
		
		final Point p = new Point(0,0);
		
		Method getMouseInfoPeer = Toolkit.class.getDeclaredMethod("getMouseInfoPeer");
		
		getMouseInfoPeer.setAccessible(true);
		
		final MouseInfoPeer peer = (MouseInfoPeer) getMouseInfoPeer.invoke(Toolkit.getDefaultToolkit());
		peer.fillPointWithCoords(p);
		
		TimerTask tt = new TimerTask(){
			Point last = p;
			Point current = new Point(0,0);
			public void run() {
				try
				{
					peer.fillPointWithCoords(current);
					
					if(current.x != last.x || current.y != last.y)
					{
						System.out.println("Mouse moved");
						Point tmp = last;
						last = current;
						current = tmp;
					}
					
				} catch (Exception e) {
					this.cancel();
					e.printStackTrace();
				}
			}
		};
		t.schedule(tt, 100, 100);
	}
}
0

Dzięki, właśnie czegoś takiego szukałem!

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