Wie kann man eine Linie zeichnen, deren Endpunkt dem Mauscursor folgt, die jedoch nur waagerecht oder senkrecht verläuft?
Der Trick besteht darin, ein KeyEvent abzufangen und dies beim Bewegen der Maus abzufragen. Hierzu wird zunächst eine Instanz eines KeyEvent gebildet. Ihr werden 5 Parameter übergeben:
- die das Ereignis auslösende Komponente, hier das JPanel
- ein int-Wert des Ereignis-Typs, hier ist es unerheblich was übergeben wird, da wir auf das Drücken und Loslassen der Tasten reagieren wollen
- ein long-Wert, der die Zeit des Events angibt, ebenfalls 0
- ein Modifier (z.B. InputEvent.CTRL_DOWN_MASK), auch dieser 0
- ein int-Wert, der den Key-Code der auslösenden Taste wiedergibt, auch hier übergeben wir 0, da wir auf das Drücken und Loslassen der Taste reagieren wollen
- ein int-Wert, der den Key-Code der Taste wiedergibt, die erzeugt werden soll, dies wollen wir nicht, somit verwenden wir KeyEvent.CHAR_UNDEFINED
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GeradeLinieZiehen extends JPanel implements MouseListener, MouseMotionListener, KeyListener {
private static final long serialVersionUID = 1L;
private int startX, startY, tempX, tempY;
private KeyEvent kEvent = new KeyEvent(this, KeyEvent.KEY_PRESSED, 0, 0, 0, KeyEvent.CHAR_UNDEFINED);
public GeradeLinieZiehen() {
this.setFocusable(true);
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.addKeyListener(this);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setPaintMode();
g2.drawLine(startX, startY, tempX, tempY);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(new GeradeLinieZiehen());
frame.setSize(400, 300);
frame.setTitle("Gerade Linien ziehen");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
startX = e.getX();
startY = e.getY();
}
public void mouseReleased(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
tempX = e.getX();
tempY = e.getY();
if (kEvent != null && kEvent.getKeyCode() == KeyEvent.VK_SHIFT) {
tempX = startX;
}
if (kEvent != null && kEvent.getKeyCode() == KeyEvent.VK_CONTROL) {
tempY = startY;
}
this.repaint();
}
public void mouseMoved(MouseEvent e) {
}
public void keyPressed(KeyEvent e) {
kEvent = e;
}
public void keyReleased(KeyEvent e) {
kEvent = null;
}
public void keyTyped(KeyEvent e) {
}
}
Im Konstruktor muss die Klasse beim KeyListener angemeldet und durch den Code
this.setFocusable(true);
explizit fokussierbar gesetzt werden, da dies ein JPanel nicht von
alleine ist.
Der KeyListener macht nun zweierlei:
- In der Methode keyPressed(KeyEvent e) weist er der neu erzeugten Ereignis-Instanz sein KeyEvent zu
- In der Methode keyReleased(KeyEvent e) setzt er diese wieder auf null
In der MouseMotionListener-Methode mouseDragged(MouseEvent
e) wird nun - vorausgesetzt die Ereignis-Instanz ist ungleich
null - der Endpunkt der zu zeichnenden Linie abhängig
von der gedrückten Linie auf den x- oder y-Wert der
Startposition gesetzt.
Der Rest des Codes entspricht 'Linie_ziehen'.
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.