java - 使用带有 Swing 的鼠标绘制(单色)数组的最简单方法是什么?

标签 java arrays swing

我一直在寻找一种在屏幕上绘制黑白阵列的方法。这是一个简单的数组,只有 20x20。我打算做的是用鼠标绘制一个数组,以便每个像素在单击时从黑色“切换”到白色并返回,然后将数组作为一组 boolean 值(或整数)传递给另一个函数。目前我正在使用 Swing。我确实记得使用过 Swing 在 Canvas 上绘图,但我仍然找不到实际用法。我应该使用 Canvas 还是依赖 JToggleButtons?

最佳答案

您可以简单地使用 JFrame(或其他 Swing 组件)并覆盖 paint(Graphics) 方法来绘制 boolean 矩阵的表示形式(请注意,在对于像 JPanel 这样的轻量级组件,您应该覆盖 paintComponent(Graphics)。这将为您提供所需的点击和拖动功能(这很难实现使用单个 Swing 组件的网格)。

正如其他人评论的那样,AWT Canvas 不会为您提供 Swing 组件未提供的任何内容,您将在下面的示例中看到我使用了 createBufferStrategy 方法也出现在 JFrame 上以确保无闪烁显示。

smiley face

请注意,我的示例相当简单,因为它会切换您拖过的每个像素,而不是通过单击操作来确定您是处于“绘画”模式还是“删除”模式,然后在持续时间内专门应用黑色或白色像素的阻力。

public class Grid extends JFrame {
    private static final int SCALE = 10; // 1 boolean value == 10 x 10 pixels.
    private static final int SIZE = 20;

    private boolean[][] matrix = new boolean[SIZE][SIZE];
    private boolean painting;
    private int lastX = -1;
    private int lastY = -1;

    public Grid() throws HeadlessException {
        setPreferredSize(new Dimension(SIZE * SCALE, SIZE * SCALE));
        setResizable(false);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setBackground(Color.WHITE);

        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                painting = true;
                tryAdjustValue(e.getPoint());
            }

            public void mouseReleased(MouseEvent e) {
                painting = false;
                lastX = -1;
                lastY = -1;
            }
        });

        addMouseMotionListener(new MouseMotionListener() {
            public void mouseDragged(MouseEvent e) {
                tryAdjustValue(e.getPoint());
            }

            public void mouseMoved(MouseEvent e) {
                tryAdjustValue(e.getPoint());
            }
        });
    }

    private void tryAdjustValue(Point pt) {
        int newX = pt.x / SCALE;
        int newY = pt.y / SCALE;

        if (painting && isInRange(newX) && isInRange(newY) && (newX != lastX || newY != lastY)) {
            // Only invert "pixel" if we're currently in painting mode, both array indices are valid
            // and we're not attempting to adjust the same "pixel" as before (important for drag operations).
            matrix[newX][newY] = !matrix[newX][newY];
            lastX = newX;
            lastY = newY;
            repaint();
        }
    }

    private boolean isInRange(int val) {
        return val >= 0 && val < SIZE;
    }

    public void paint(Graphics g) {
        super.paint(g);

        for (int x=0; x<SIZE; ++x) {
            for (int y=0; y<SIZE; ++y) {
                if (matrix[x][y]) {
                    g.fillRect(x * SCALE, y * SCALE, SCALE, SCALE);
                }
            }
        }
    }

    public static void main(String[] args) {
        Grid grid = new Grid();
        grid.pack();
        grid.setLocationRelativeTo(null);
        grid.createBufferStrategy(2);
        grid.setVisible(true);
    }
}

关于java - 使用带有 Swing 的鼠标绘制(单色)数组的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7641190/

相关文章:

java - Mule Dataweave 日期时间从完整日期时间转换为短日期时间

java - 基本 Spring-Security MVC 应用程序中的 404 错误

java - 终止 JFrame 关闭上的运行线程

java - 将 Action 监听器添加到 jpanel

java - Android 布局文件中无法识别自定义 XML 属性

java - 将一个项目拆分成两个独立的项目有什么意义?

删除对象数组时出现 C++ 堆异常

javascript - 在 node.js 中处理大型 json 数组

arrays - 如何使用关联数组并与索引数组匹配?

java - JFrame 的尺寸不正确