簡體   English   中英

Java:在按住鼠標時填充基於2D數組的圖形

[英]Java: Filling in Graphics based on 2D array as mouse held down

所以我有一個由二維數組內容填充的JPanel。 我有一個鼠標監聽器,可以在按下時更改單元格的顏色。 我的問題是,是否有可能讓用戶將鼠標拖過一行單元格並連續着色它們? 我已經研究過鼠標運動監聽器,但這似乎沒有幫助。

有任何想法嗎?

可以使用mouseDragged()的方法MouseMotionListener與結合mousePressed()的方法MouseListener

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();
    }
}

如果擴展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通常比添加內聯類的偵聽器更好,因為它為您提供了一個完全獨立的可重用組件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM