使用 java swing 绘制笔划...笔划不显示

Drawing pen strokes using java swing...strokes don't show up

所以我这里有两个 class:

PhotoComponent class:

(这个class是把一个特定的图片作为一个JComponent来处理。当"flipped"我想画笔画而不是有一个图片。所以我用一个矩形替换图片,尝试在上面画笔。)

public class PhotoComponent extends JComponent {

private Image pic;
private boolean flipped;

private int contentAreaWidth;
private int contentAreaHeight;
p
@Override
public void paintComponent(Graphics g) {
    //Does all the drawing and contains whatever state information is associated with the photo
    //create an action event to auto call repaint
    //call repaint anytime flip was changed to true or false

    System.out.println("Draw: " + draw + ", Pic: " + pic);
    if (draw && pic != null) {
        super.paintComponent(g);

        System.out.println("width using this: " + this.getWidth() + ", actual width of JPanel: " + contentAreaWidth);
        System.out.println("height using this: " + this.getHeight() + ", actual height of JPanel: " + contentAreaHeight);

        g2 = (Graphics2D) g;
        int x = (contentAreaWidth - pic.getWidth(null)) / 2;
        int y = (contentAreaHeight - pic.getHeight(null)) / 2;
        if (!flipped) {
            g2.drawImage(pic, x, y, null);

        } else if (flipped) {
            g2.setColor(Color.WHITE);
            g2.fillRect(x,y,pic.getWidth(null), pic.getHeight(null));
            g2.drawRect(x, y, pic.getWidth(null), pic.getHeight(null));
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            if (drawingMode) {
                g2.setPaint(Color.RED);
                if (drawOval) {
                    penStrokes.put(ovalX, ovalY);
                    if (penStrokes != null) {
                        for (Integer xCoor : penStrokes.keySet()) {
                            g2.setPaint(Color.RED);
                            int brushSize = 5;
                            g2.fillOval((xCoor - (brushSize / 2)), (penStrokes.get(xCoor) - (brushSize / 2)), brushSize, brushSize);
                            //System.out.println("SIZE OF HASHTABLE: " + penStrokes.size());
                        }
                    }
                    System.out.println("Filling an oval!" + ovalX + ", " + ovalY);
                }
            } else if (textMode) {
                g2.setPaint(Color.YELLOW);
                if (drawRect) {
                    rectDimensions.add(rectX);
                    rectDimensions.add(rectY);
                    rectDimensions.add(rectWidth);
                    rectDimensions.add(rectHeight);

                    for (int i = 0; i < rectDimensions.size(); i+=4) {
                        g2.fillRect(rectDimensions.get(i), rectDimensions.get(i+1), rectDimensions.get(i+2), rectDimensions.get(i+3));
                        g2.drawRect(rectDimensions.get(i), rectDimensions.get(i+1), rectDimensions.get(i+2), rectDimensions.get(i+3));
                    }
                }
            }

            System.out.println("This is being called again!");
        }

    }

}
public void setRectangle(int x, int y, int width, int height) {
    drawRect = true;
    rectX = x;
    rectY = y;
    rectWidth = width;
    rectHeight = height;
}

public void removeRectangle() {
    drawRect = false;
}

public int[] setOval(int currentX, int currentY) {
    drawOval = true;
    int[] toReturn = {ovalX, ovalY};
    ovalX = 

注意上面的 DRAWLINE() 方法。我在给定的点上绘图,重新绘制,并将旧变量设置为当前变量。

主要class:

private static PhotoComponent img;
private static JFrame frame;

private static JPanel contentArea;

//Mouse Coordinates for PenStrokes
private static int oldX, oldY;

//Mouse Coordinates for Sticky Notes
private static Point clickPoint;

public static void main (String[] args) {
    frame = new JFrame("PhotoManip");
    img = null;
    contentArea = null;
    oldX = 0;
    oldY = 0;
    setupMenubar(frame);
    setupJFrame(frame);
}

private static void addPhotoComponent(File file) {

            }
            if (img.getTextMode()) {
                img.removeRectangle();
                clickPoint = null;
            }

        }
    });

    img.addMouseMotionListener(new MouseAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            if (img.getDrawingMode()) {
                if (withinRange(e.getX(), e.getY())) {
                    int[] toUpdate = img.setOval(e.getX(), e.getY());
                    oldX = toUpdate[0];
                    oldY = toUpdate[1];
                    img.repaint();
                }
            }
            if (img.getTextMode()) {
                if (withinRange(e.getX(), e.getY())) {
                    Point dragPoint = e.getPoint();
                h, height);
                    img.repaint();
                }
            }

        }
    });

    if (img!=null) {
        contentArea.add(img);
    }
}

private static boolean withinRange(int x, int y) {
    if (x > img.getX() && x < img.getX() + img.getWidth()) {
        if (y > img.getY() && y < img.getY() + img.getHeight()) {
            return true;
        }
    }
    return false;
}

private static void flipImage() {
    if (!img.isFlipped()) {
        img.setFlipped(true);
    } else if (img.isFlipped()) {
        img.setFlipped(false);
    }
}

drawLine() 在上面这个主 class 中被调用,当发生鼠标拖动时。问题是笔画似乎没有显示出来。

我知道程序正在调用 g2.fillOval() 因为我之后正在打印验证语句。

另外,我已经创建了当按下并拖动鼠标时打印语句并且它们得到了正确的坐标?

为什么没有出现红色笔划?我很困惑。这是我的代码的结构方式吗?

你的问题的症结在于你试图在 paintComponent 方法之外绘制一些东西,这是永远不受支持的。无论你绘制什么,都会被下一次 paintComponent 的调用覆盖,这几乎会立即发生。我们可以通过存储椭圆的坐标并在 paintComponent 内绘制它来解决这个问题,而不是尝试在 paintComponent 方法之外的图形对象上绘制。请参阅下面的代码:

首先我们要将以下变量添加到您的 PhotoComponent class:

private boolean drawOval = false;
private int ovalX = 0;
private int ovalY = 0;

然后我们将添加控制它们的方法:

public int[] setOval(int currentX, int currentY) {
    drawOval = true;
    int[] toReturn = {ovalX, ovalY};
    ovalX = currentX;
    ovalY = currentY;
    return toReturn;
}

public void removeOval() {
    drawOval = false;
}

之后我们可以更改 paintComponent 方法让它根据这些变量绘制椭圆:

@Override
public void paintComponent(Graphics g) {
    //Does all the drawing and contains whatever state information is associated with the photo
    //create an action event to auto call repaint
    //call repaint anytime flip was changed to true or false
    super.paintComponent(g);
    g2 = (Graphics2D) g;
    int x = (contentAreaWidth - pic.getWidth(null)) / 2;
    int y = (contentAreaHeight - pic.getHeight(null)) / 2;
    if (!flipped) {
        g2.drawImage(pic, x, y, null);

    } else if (flipped) {
        g2.setColor(Color.WHITE);
        g2.fillRect(x, y, pic.getWidth(null), pic.getHeight(null));
        g2.drawRect(x, y, pic.getWidth(null), pic.getHeight(null));
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(Color.RED);
    }

    //took the code you already used for drawing the oval and moved it here
    if (drawOval) {
        g2.setPaint(Color.RED);
        int brushSize = 5;
        g2.fillOval((ovalX - (brushSize / 2)), (ovalY - (brushSize / 2)), brushSize, brushSize);
    }
}

最后更改 addPhotoComponent 方法来更新这些变量,而不是尝试直接绘制椭圆:

private static void addPhotoComponent(File file) {
    Image image = null;
    try {
        image = ImageIO.read(file);
    } catch (IOException e2) {
        System.out.println("ERROR: Couldn't get image.");
    }

    img = new PhotoComponent(image, contentArea);
    img.revalidate();

    img.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() == 2) {
                // your code here
                System.out.println("You flipped the photo!!!");
                flipImage();
                img.repaint();
            }
        }

        @Override
        public void mousePressed(MouseEvent e) {
            img.setOval(e.getX(), e.getY());
        }
        @Override
        public void mouseReleased(MouseEvent e) {
            img.removeOval();
        }
    });

    img.addMouseMotionListener(new MouseAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            int[] toUpdate = img.setOval(e.getX(), e.getY());
            oldX = toUpdate[0];
            oldY = toUpdate[1];
        }
    });

    if (img != null) {
        contentArea.add(img);
    }
}