如何使用外部类中的类的Graphics对象

时间:2018-09-05 18:39:39

标签: java swing graphics

我正在学习java awt和swing libs。在此程序中,我试图从MSPaint模仿铅笔工具。当我在单个类中进行编程时,它工作正常,但是,当我使用外部时,它不起作用听我的Mouse动作的类。我的猜测是我无法获取应用程序的Graphics对象,请向我介绍我要去哪里的地方。谢谢!
这是代码

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;

public class Paint extends Canvas {

    Paint() {
        Outer obj=new Outer(this);
        JFrame frame=new JFrame("Paint");
        frame.setSize(400,400);
        frame.add(this);
        frame.addMouseMotionListener(obj);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new Paint();
    }
}

class Outer implements MouseMotionListener {

    static int x,y,x1,y1;

    Paint ob;

    Outer(Paint ob) {
        this.ob=ob;
    }

    public void mouseDragged(MouseEvent me) {
        Graphics g=ob.getGraphics();
        x1=me.getX();
        y1=me.getY();
        _paint_(g,x,y,x1,y1);
        x=x1;
        y=y1;
    }

    public void _paint_(Graphics g,int x,int y,int x1,int y1) {
        g.drawLine(x,y,x1,y1);
    }

    public void mouseMoved(MouseEvent me) {
        y=me.getY();
        x=me.getX();
    }
}

不起作用,表示框架出现了,但是“铅笔工具”没有画线

1 个答案:

答案 0 :(得分:0)

如果要使用 JavaFX 进行此操作,则可以阅读this文档的教程,其中包含您所寻找内容的精确示例。只需下载CanvasDoodleTest.zip并运行它即可。

如果要使用 Java Swing 进行此操作,通常可以这样做,如下所示:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class SwingCanvas extends JPanel implements MouseListener, MouseMotionListener {
    private final Path2D pencilPath; //This will be the Shape we are going to paint in 'myPaint(...)' method.

    public SwingCanvas() {
        pencilPath = new Path2D.Double(); //Create a new path object, i.e. a set of points and lines between them.

        super.addMouseListener(this); //Register this object as its MouseListener (for the mousePressed event).
        super.addMouseMotionListener(this); //Register this object as its MouseMotionListener (for the mouseDragged event).
        super.setPreferredSize(new Dimension(400, 200)); //Set the preferred size of the component (i.e. the size we want the panel to start with).
        super.setBackground(Color.WHITE); //[Optional] Setting the background color of the panel to white.
        super.setOpaque(true); //Opaque components are responsible to paint their full contents. This is the default behaviour of JPanel, so this is an optional call here.
    }

    /**
     * Overriding paintComponent(...) tells Swing how to paint the panel.
     * @param graphics 
     */
    @Override
    public void paintComponent(final Graphics graphics) {
        super.paintComponent(graphics); //Call this in order to clear previous painting state and start over.
        final Graphics2D g2d = (Graphics2D) graphics.create(); //Create a Graphics2D object to paint.
        try {
            myPaint(g2d); //Call our custom paint method.
        }
        catch (final RuntimeException re) { //Catch any exception in our myPaint (eg a NullPointerException) (if any).
            System.err.println(re); //Handle the exception in some way.
        }
        finally {
            g2d.dispose(); //ALWAYS dispose the CREATED Graphics2D object.
        }
    }

    /**
     * Do whatever painting you need here.
     * In our case, we draw the full path the pencil has followed.
     * @param g2d The {@link Graphics2D} object to paint on.
     */
    protected void myPaint(final Graphics2D g2d) {
        g2d.draw(pencilPath);
    }

    @Override
    public void mousePressed(final MouseEvent e) {
        pencilPath.moveTo(e.getX(), e.getY()); //Move the drawing pencil (without drawing anything new) to the new position.
    }

    @Override
    public void mouseClicked(final MouseEvent e) {
        //Do nothing.
    }

    @Override
    public void mouseReleased(final MouseEvent e) {
        //Do nothing.
    }

    @Override
    public void mouseEntered(final MouseEvent e) {
        //Do nothing.
    }

    @Override
    public void mouseExited(final MouseEvent e) {
        //Do nothing.
    }

    @Override
    public void mouseMoved(final MouseEvent e) {
        //Do nothing.
    }

    @Override
    public void mouseDragged(final MouseEvent e) {
        if (pencilPath.getCurrentPoint() == null) //If the initial point of the path is not set (via a call to "moveTo(...)") then:
            pencilPath.moveTo(e.getX(), e.getY()); //Register the new point from which the new lines will be drawn.
        else
            pencilPath.lineTo(e.getX(), e.getY()); //Register a new line in the path to be drawn.
        repaint(); //Notify Swing to repaint the component (which will call paintComponent(...) which will call myPaint(...) which will paint the pencilPath...
    }

    public static void main(final String[] args)  {
        final JFrame frame = new JFrame("SwingPaint pencil"); //Creates a new application's window.
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Tells the new window to close the application if the user closes the window.
        frame.getContentPane().add(new SwingCanvas()); //Add our custom painting panel to the window's content pane.
        frame.pack(); //Automatic sizing of the window, based on preferred sizes of contained components.
        frame.setLocationRelativeTo(null); //Put the window in the center of the screen.
        frame.setVisible(true); //Pop the window.
    }
}

如果需要,您还可以结合使用这两种方法,因为CanvasComponent(因此可以在Swing示例中将其添加到主框架的内容窗格中。)

如果要从另一个类访问MouseEvent中的SwingCanvas个,则可以扩展MouseAdapter并将其添加到面板中。