Java Paint未在Swing中绘制 [英] Java paint not drawing in Swing

查看:44
本文介绍了Java Paint未在Swing中绘制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作绘画程序,但是在拖动鼠标时无法绘制线条.看来涂料一直在刷新,因此只绘制了鼠标的当前位置.我对此有些陌生,因此如何在拖动鼠标时将所有行显示在JPanel上?谢谢,这就是我所拥有的:

I'm trying to make a paint program, but I'm having trouble with drawing lines when dragging the mouse. It appears that the paint keeps on refreshing and so it only draws the current position of my mouse. I a bit new to this, so how would I be able to get all the lines to show on the JPanel when dragging the mouse? Thanks, and here is what I have:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;

public class DrawingPanel extends JPanel{

    Point start;
    Point end;
    static Color c = Color.black;
    DrawingPanel(){
        addMouseMotionListener(new ml());
        addMouseListener(new ml());
    }
    public class ml implements MouseMotionListener, MouseListener{
        public void mouseMoved(MouseEvent ev){}
        public void mousePressed(MouseEvent e){
            end = e.getPoint();
        }
        public void mouseDragged(MouseEvent e){
            start = end;
            end=e.getPoint();
            repaint();
        }
        public void mouseReleased(MouseEvent e){
            start=null;
            end=null;
        }
        public void mouseClicked(MouseEvent e){}
        public void mouseEntered(MouseEvent e){}
        public void mouseExited(MouseEvent e){}
    }
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.setColor(c);
        if(start!=null){
            Graphics2D g2 = (Graphics2D) g;
            g2.setStroke(new BasicStroke(5));
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.drawLine(start.x, start.y, end.x, end.y);


        }

    }
}

推荐答案

有多种方法可以解决您的问题.@MattiasF和@MadProgrammer是正确的:Swing在做它应该做的事情.您的 paintComponent 方法应该重新绘制整个场景,而不是添加到上一个场景.

There are multiple ways to solve your problem. @MattiasF and @MadProgrammer are correct: Swing is doing what it should be doing. Your paintComponent method is supposed to repaint the entire scene, not add onto the previous one.

到目前为止,建议的解决方案导致一个应用程序正在执行矢量图形:您正在记住原始的绘制操作,并且在每个绘制上都在执行每个绘制操作(Java2D对其进行了一些优化,因为它实际上并不会重新绘制屏幕上当前不可见的区域,但是要弄清楚哪些区域是可见的,哪些区域不可见也需要花费时间.

The solutions suggested so far result in an application that is doing vector graphics: you are remembering the original drawing operations, and on every paint, you are executing every one of them (Java2D optimises some of it, because it will not really redraw the areas that are not currently visible on the screen, but it also takes time to figure out which areas are visible and which ones not)

优点是,如果您需要更大或更小的图像,则可以完美地缩放绘图操作.缺点是,一旦存储了许多绘图操作,它可能会变慢,并且不能(轻松地)进行位图操作.

The advantages are that you can scale the drawing operations perfectly if you need a bigger or smaller image. The disadvantages are that it may be slower once you have stored many drawing operations, and that you cannot (easily) do bitmap manipulations.

另一种方法是位图方法.您可以在内存中建立绘图的位图,然后在 paintComponent 方法中将位图绘制到屏幕上.

Another approach to this is the bitmap approach. You build up a bitmap of your drawing so far in memory, and in the paintComponent method you draw the bitmap onto the screen.

优点是通常更快.它还允许位图操作,并且通常也更容易针对此模型进行编程,因为您可以在需要时进行绘制,而不是在内存中构建一系列绘制操作.缺点是它使用更多的内存(直到您执行许多绘图操作为止),并且您无法再完美地缩放图像.

The advantage is that it's usually faster. It also allows bitmap operations, and it is also often easier to program against this model as you can just draw when you need it, rather than build op a list of drawing operations in memory. The disadvantages are that it uses more memory (until you have many drawing operations) and that you cannot perfectly scale your image up and down anymore.

要使您的示例与保存在内存中的位图一起工作,请将 image imageGraphics 字段添加到您的类中,并替换鼠标侦听器 ml 以及 paintComponent 方法和以下代码:

To make your example work with a bitmap kept in memory, add the fields image and imageGraphics into your class, and replace your mouse listener ml as well as the paintComponent method with the code below:

private BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
private Graphics2D imageGraphics = image.createGraphics();

public class ml extends MouseAdapter implements MouseMotionListener, MouseListener {

    public void mousePressed(MouseEvent e) {
        end = e.getPoint();
    }

    public void mouseDragged(MouseEvent e) {
        start = end;
        end = e.getPoint();

        imageGraphics.setColor(c);
        imageGraphics.setStroke(new BasicStroke(5));
        imageGraphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        imageGraphics.drawLine(start.x, start.y, end.x, end.y);

        repaint();
    }

    public void mouseReleased(MouseEvent e) {
        start = null;
        end = null;
    }
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.drawImage(image, null, 0, 0);
}

您将立即看到缩放问题.位图缓冲区是500x500像素,它将不会绘制任何超出它的内容.这基本上与Microsoft Paint的工作方式相同:开始绘制之前,您需要知道画布的大小.

You will immediately see the problem with scaling. The bitmap buffer is 500x500 pixels, and anything outside it will not be drawn. This is basically the same way that Microsoft paint works: you need to know the canvas size before you start drawing.

这篇关于Java Paint未在Swing中绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆