所以我有一个由二维数组内容填充的JPanel。我有一个鼠标监听器,可以在按下时更改单元格的颜色。我的问题是,是否有可能让用户将鼠标拖过一行单元格并连续着色它们?我已经研究过鼠标运动监听器,但这似乎没什么帮助。
有什么想法吗?
答案 0 :(得分:1)
您可以将mouseDragged()
的{{1}}方法与MouseMotionListener
的{{1}}方法结合使用。
mousePressed()
方法将处理一个没有移动的简单点击,MouseListener
将处理任何拖动。我将我为原始问题here的答案编写的代码结合起来,以便更好地阐明所有内容的作用,并且非常感谢您对其他问题的回复。
mousePressed()
答案 1 :(得分:1)
如果扩展JPanel,则不需要鼠标侦听器。只需启用鼠标事件,然后覆盖组件的鼠标事件处理程序。一般逻辑是:
if mouse pressed {
dragging = true
begin drag
}
if mouse dragged and dragging == true {
process drag
}
if mouse released and dragging == true {
dragging = false
finalize drag
}
以下是一个例子:
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DragTest {
// example JPanel. click and drag on it to create lines.
static class DragPanel extends JPanel {
private static final long serialVersionUID = 1L;
static class Line {
int x1, y1, x2, y2;
}
private final List<Line> lines = new ArrayList<Line>();
private Line draggedLine; // null if not dragging
public DragPanel() {
// enable mouse event processing even if no listeners are registered
enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
// draw saved lines
g.setColor(Color.WHITE);
for (Line line : lines)
g.drawLine(line.x1, line.y1, line.x2, line.y2);
// draw currently active line if there is one
if (draggedLine != null) {
g.setColor(Color.RED);
g.drawLine(draggedLine.x1, draggedLine.y1, draggedLine.x2, draggedLine.y2);
}
}
// does the work; since motion and press/release are all MouseEvent,
// we can just direct MouseEvents here from the event handler overrides
// and handle based on event ID.
private void handleMouseEvent(MouseEvent e) {
if (e.getID() == MouseEvent.MOUSE_PRESSED && e.getButton() == MouseEvent.BUTTON1) {
// begin drag by initializing a new Line at mouse position
if (draggedLine == null) {
draggedLine = new Line();
draggedLine.x1 = draggedLine.x2 = e.getX();
draggedLine.y1 = draggedLine.y2 = e.getY();
e.consume();
}
} else if (e.getID() == MouseEvent.MOUSE_DRAGGED) {
// if drag in progress, update line endpoint
if (draggedLine != null) {
draggedLine.x2 = e.getX();
draggedLine.y2 = e.getY();
e.consume();
}
} else if (e.getID() == MouseEvent.MOUSE_RELEASED && e.getButton() == MouseEvent.BUTTON1) {
// if drag in progress, accept new line and end drag
if (draggedLine != null) {
draggedLine.x2 = e.getX();
draggedLine.y2 = e.getY();
lines.add(draggedLine);
draggedLine = null;
e.consume();
}
}
if (e.isConsumed())
repaint();
}
@Override
public void processMouseMotionEvent(MouseEvent e) {
handleMouseEvent(e); // pass to our handler, may consume event
super.processMouseMotionEvent(e); // in case there are registered listeners
}
@Override
public void processMouseEvent(MouseEvent e) {
handleMouseEvent(e); // pass to our handler, may consume event
super.processMouseEvent(e); // in case there are registered listeners
}
}
public static final void main(String[] args) {
JFrame frame = new JFrame("Panel Drag Example");
frame.getContentPane().add(new DragPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(640, 480);
frame.setVisible(true);
}
}
扩展JPanel通常比添加内联类的侦听器更好,因为它为您提供了一个完全独立的可重用组件。