Java:按住鼠标时基于2D数组填充图形
所以我有一个JPanel,它由2D数组的内容填充。我有一个鼠标监听器,按下时会改变单元格的颜色。我的问题是,是否有可能让用户将鼠标拖动到一行单元格上,并将其连续着色?我研究过鼠标运动监听器,但这似乎没有帮助Java:按住鼠标时基于2D数组填充图形,java,swing,graphics,mouselistener,mousemotionevent,Java,Swing,Graphics,Mouselistener,Mousemotionevent,所以我有一个JPanel,它由2D数组的内容填充。我有一个鼠标监听器,按下时会改变单元格的颜色。我的问题是,是否有可能让用户将鼠标拖动到一行单元格上,并将其连续着色?我研究过鼠标运动监听器,但这似乎没有帮助 有什么想法吗?您可以将MouseMotionListener的mouseDragged()方法与MouseListener的mousePressed()方法结合使用 mousePressed()方法将处理简单的单击而不移动,而mouseDragged()将处理任何已完成的拖动。我结合了我为回
有什么想法吗?您可以将
MouseMotionListener的mouseDragged()
方法与MouseListener的mousePressed()
方法结合使用
mousePressed()
方法将处理简单的单击而不移动,而mouseDragged()
将处理任何已完成的拖动。我结合了我为回答您的原始问题而编写的代码,以便更好地阐明每件事的作用,如果您能回答其他问题,我将不胜感激
package stackoverflow.answers;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class JPanelPaint {
JPanel panel;
JFrame frame;
BufferedImage image;
public JPanelPaint() {
image = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < image.getWidth(); i++) {
for (int j=0; j < image.getHeight(); j++) {
/* I'm just initializing the image with an arbitrary color (white in this case), you can easily change this. */
image.setRGB(i, j, new Color((int)(255 ), (int)(255 ), (int)(255 )).getRGB());
}
}
frame = new JFrame("JPanel Paint");
panel = new JPanel() {
@Override
public void paint(Graphics g) {
super.paint(g);
Rectangle rect = g.getClipBounds();
g.setColor(Color.white);
g.fillRect(rect.x, rect.y, rect.width, rect.height);
for (int i = 0; i < image.getWidth(); i++) {
for (int j=0; j < image.getHeight(); j++) {
/* Set the color of the "quadpixel" to that of the original cell on the image. */
g.setColor(new Color(image.getRGB(i, j)));
g.fillRect(j*4, i*4, 4, 4);
}
}
}
};
panel.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent arg0) { }
@Override
public void mouseEntered(MouseEvent arg0) { }
@Override
public void mouseExited(MouseEvent arg0) { }
@Override
public void mousePressed(MouseEvent arg0) {
/* Y and X are swapped, just a quirk in the JRE */
/* I'm just setting the pixel with an arbitrary color (black in this case), you can easily change this. */
image.setRGB(arg0.getY() / 4, arg0.getX() / 4, new Color(0, 0, 0).getRGB());
panel.repaint();
}
@Override
public void mouseReleased(MouseEvent arg0) { }
});
panel.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent arg0) {
/* Y and X are swapped, just a quirk in the JRE */
/* I'm just setting the pixel with an arbitrary color (black in this case), you can easily change this. */
image.setRGB(arg0.getY() / 4, arg0.getX() / 4, new Color(0, 0, 0).getRGB());
panel.repaint();
}
@Override
public void mouseMoved(MouseEvent arg0) { }
});
panel.setPreferredSize(new Dimension(200, 200));
frame.add(panel);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
panel.repaint();
}
public static void main(String[] args) {
new JPanelPaint();
}
}
package stackoverflow.answers;
导入java.awt.*;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
导入java.awt.event.MouseMotionListener;
导入java.awt.image.buffereImage;
导入javax.swing.*;
公共类JPanelPoint{
JPanel小组;
JFrame框架;
缓冲图像;
公共JPanelPaint(){
image=新的buffereImage(50,50,buffereImage.TYPE_INT_ARGB);
对于(int i=0;i
如果扩展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);
}
}
import java.awt.AWTEvent;
导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.event.MouseEvent;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类绘图测试{
//示例JPanel。单击并拖动它以创建线条。
静态类DragPanel扩展了JPanel{
私有静态最终长serialVersionUID=1L;
静态类线{
int-x1,y1,x2,y2;
}
私有最终列表行=新的ArrayList();
私有行draggedLine;//如果不拖动,则为null
公共绘图板(){
//即使未注册侦听器,也启用鼠标事件处理
enableEvents(awteEvent.MOUSE_EVENT_MASK | awteEvent.MOUSE_MOTION_EVENT_MASK);
}
@凌驾
公共组件(图形g){
超级组件(g);
g、 设置颜色(颜色为黑色);
g、 fillRect(0,0,getWidth(),getHeight());
//绘制保存的线
g、 setColor(Color.WHITE);
用于(行:行)
g、 抽绳(线x1、线y1、线x2、线y2);
//绘制当前活动线(如果有)
if(DragedLine!=null){
g、 setColor(Color.RED);
g、 抽绳(draggedLine.x1、draggedLine.y1、draggedLine.x2、draggedLine.y2);
}
}
//动作和按下/释放都是MouseEvent,
//我们可以通过事件处理程序覆盖将MouseEvents定向到这里
//和基于事件ID的句柄。
私有无效handleMouseEvent(MouseeEvent e){