Как использовать объект Graphics класса Outer? - PullRequest
0 голосов
/ 05 сентября 2018

Я изучаю java awt и swing libs.В этой программе я пытаюсь эмулировать карандашный инструмент из MSPaint. Он отлично работает, когда я занимаюсь программированием в одном классе, однако не работает, когда я использую Outer Класс для прослушивания моих движений мыши. Я предполагаю, что мне не удается получить объект приложения 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();
    }
}

By не работает, я имею в виду, что рамка появляется, но «карандашный инструмент» не рисует линии

1 Ответ

0 голосов
/ 06 сентября 2018

Если вы хотите сделать это с JavaFX , вы можете прочитать это руководство по документации, которое содержит точный пример того, что вы ищете. Просто скачайте 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.
    }
}

Если вы хотите, вы также можете объединить два метода, потому что Canvas - это Component (поэтому его можно добавить к панели содержимого основного фрейма в примере Swing).

Если вы хотите получить доступ к MouseEvent из SwingCanvas из другого класса, вы можете расширить MouseAdapter и добавить его на панель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...