什么是涂料的替代和重绘功能?(what is Alternative of Paint and re

2019-10-21 12:05发布

Is there any function which can be replaced with paint() and repaint()in java.

I have a scenario.

There is a triangle (Triangle 1). when user will click in triangle another triangle (Triangle 2) will appear and 1st (Triangle 1) will be removed from screen. (coded using JFrame, paint() and repaint())

I have achieved it so far. but problem is when I minimize or change size of window with mouse the output window, it just paint again Triangle 1 rather than Triangle 2. OR Clear the whole screen if i call g2d.clearRect(0, 0, 1000, 1000);
triangle.reset();

Note: These both functions are to remove previous triangle (Triangle 1).

Is there any function that state should not be changed on minimize or when window size changed ?

or can we override repaint() or anything helping according to scenario.

Here is the Working code. Execute it, Click in triangle then minimize and see again. You will get the problem more clearly.

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

public class Triangle_shape extends JFrame implements ActionListener {

    public static JButton btnSubmit = new JButton("Submit");

    public Triangle_shape() {
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setLayout(new BorderLayout());
        frame.add(new TrianglePanel(), BorderLayout.CENTER);
        frame.add(btnSubmit, BorderLayout.PAGE_END);
        frame.pack();
        frame.repaint();
        frame.setTitle("A Test Frame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public static class TrianglePanel extends JPanel implements MouseListener {

        private Polygon triangle, triangle2;

        public TrianglePanel() {
            //Create triangle
            triangle = new Polygon();
            triangle.addPoint(400, 550);        //left   
            triangle.addPoint(600, 550); //right
            triangle.addPoint(500, 350); //top

            //Add mouse Listener
            addMouseListener(this);

            //Set size to make sure that the whole triangle is shown
            setPreferredSize(new Dimension(300, 300));
        }

        /**
         * Draws the triangle as this frame's painting
         */
        @Override
        public void paintComponent(Graphics g) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.draw(triangle);
        }

        //Required methods for MouseListener, though the only one you care about is click
        public void mousePressed(MouseEvent e) {
        }

        public void mouseReleased(MouseEvent e) {
        }

        public void mouseEntered(MouseEvent e) {
        }

        public void mouseExited(MouseEvent e) {
        }

        /**
         * Called whenever the mouse clicks. Could be replaced with setting the
         * value of a JLabel, etc.
         */
        public void mouseClicked(MouseEvent e) {
            Graphics2D g2d = (Graphics2D) this.getGraphics();
            Point p = e.getPoint();
            if (triangle.contains(p)) {
                System.out.println("1");

                g2d.clearRect(0, 0, 1000, 1000);
                triangle.reset();
                g2d.setColor(Color.MAGENTA);
                triangle2 = new Polygon();
                triangle2.addPoint(600, 550);  // left
                triangle2.addPoint(700, 350); //top
                triangle2.addPoint(800, 550);  //right
                g2d.draw(triangle2);
            } else {
                System.out.println("Triangle dont have point");
            }
        }
    }
}

Answer 1:

paint()repaint()正常工作,但你不使用他们,因为他们的设计中使用。 窗口系统不保持一个什么样的组件看起来像一个持久的图像。 该公司预计您的组件能够重新绘制需求的整体外观(当窗口大小调整或取消最小化等)。

如果你抓住了Graphics对象getGraphics()和借鉴的东西在组件上,你画的东西的确会丢失,如果/当整个组件需要重新绘制。 所以,你不应该这样做,而是要确保你paintComponent方法都需要完全重新绘制该组件的信息。


如果你只是想在屏幕上一个三角形一次,不创建一个单独的变量triangle2 。 只需更换你必须改变你的鼠标点击处理程序如下一个三角形:

public void mouseClicked(MouseEvent e) {
    Point p = e.getPoint();
    if (triangle.contains(p)) {
        triangle = new Polygon();
        triangle.addPoint(600, 550); // left
        triangle.addPoint(700, 350); //top
        triangle.addPoint(800, 550); //right
        repaint();
    } else {
        System.out.println("Point not in triangle");
    }
}

paintComponent方法应该调用super.paintComponent ,以确保背景画,否则你并不需要去改变它:

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    g2d.draw(triangle);
}

相反,如果你试图让屏幕上的多个三角形,例如,在每一次点击添加一个新的,你应该将它们添加到列表将被绘制每当组件需要重新绘制形状:

private final List<Shape> shapes = new ArrayList<>();

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D)g;
    for (Shape s : shapes)
        g2d.draw(s);
}

然后以控制所述组的形状即在屏幕上的,操作列表的内容,并调用repaint();

举例来说,一个新的形状添加到屏幕上的那些:

Polygon triangle = new Polygon();
triangle.addPoint(200, 300);
triangle.addPoint(200, 200);
triangle.addPoint(300, 200);
shapes.add(triangle);
repaint();

要清除屏幕上的所有图形:

shapes.clear();
repaint();

你还应该确保你在程序开始切换到Swing线程,因为它是不安全的从主线程Swing组件进行交互。 在main

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame();
            .
            .
            .
            frame.setVisible(true);
        }
    });
}


Answer 2:

mouseClicked方法不应该创建一个新的三角形物体。 复位后triangle只是增加新的指向它。 也不要在这个方法来绘制,但称之为repaint

   public void mouseClicked(MouseEvent e) {
        Point p = e.getPoint();
        if (triangle.contains(p)) {
            System.out.println("1");
            triangle.reset();            // change the current triangle
            triangle.addPoint(600, 550); // new left
            triangle.addPoint(700, 350); // new top
            triangle.addPoint(800, 550); // new right
            repaint();                   // force repainting
        } else {
            System.out.println("Triangle dont have point");
        }
    }

现在如果你想许多三角形,你应该有一个收集Polygon秒。 像这样 :

public static class TrianglePanel extends JPanel implements MouseListener {
    private Vector<Polygon> triangles;

    public TrianglePanel() {
        n = 0;
        // Create an empty collection
        triangles = new Vector<Polygon>();

        //Create first triangle
        Polygon triangle = new Polygon();
        triangle.addPoint(400, 550); //left   
        triangle.addPoint(600, 550); //right
        triangle.addPoint(500, 350); //top

        // Add the triangle to the collection
        triangles.add(triangle);

        //Add mouse Listener
        addMouseListener(this);

        //Set size to make sure that the whole triangle is shown
        setPreferredSize(new Dimension(300, 300));
    }

    /**
     * Draws the triangles as this frame's painting
     */
    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        for (Polygon p : triangles) // Draw all triangles in the collection
            g2d.draw(p);
    }

    //Required methods for MouseListener, though the only one you care about is click
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}

    /**
     * Called whenever the mouse clicks. Could be replaced with setting the
     * value of a JLabel, etc.
     */
    public void mouseClicked(MouseEvent e) {
        Graphics2D g2d = (Graphics2D) this.getGraphics();
        Point p = e.getPoint();
        // Do what you want with p and the collection
        // For example : remove all triangles that contain the point p
        ListIterator<Polygon> li = triangles.listIterator();
        while (li.hasNext()) {
            if (li.next().contains℗) li.remove();
        }
        // Do what you want to update the list
        // For example: Add a new triangle...
        Polygon triangle = new Polygon();
        triangle.addPoint(600+n, 550);  // left
        triangle.addPoint(700+n, 350);  //top
        triangle.addPoint(800+n, 550);  //right
        triangles.add(triangle); // add the new triangle to the list
        n += 10; // next new triangle will be "moved" right
        repaint();
    }
    private int n;
}


文章来源: what is Alternative of Paint and repaint function?