what is Alternative of Paint and repaint function?

时光总嘲笑我的痴心妄想 提交于 2019-12-11 07:52:12

问题


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");
            }
        }
    }
}

回答1:


paint() and repaint() work fine, but you are not using them as they are designed to be used. The window system doesn't keep a persistent image of what a component looks like. It expects your component to be able to repaint its entire appearance on demand (such as when the window is resized or un-minimized).

If you grab a Graphics object with getGraphics() and draw something on the component, the stuff you draw will indeed be lost if/when the entire component needs to be repainted. So you should not do that, but instead make sure your paintComponent method has all the information it needs to completely repaint the component.


If you only want one triangle on the screen at once, do not create a separate variable triangle2. Just replace the one triangle you have by altering your mouse click handler as follows:

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");
    }
}

Your paintComponent method should call super.paintComponent to ensure the background is painted, but otherwise you do not need to change it:

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

Alternatively if you are trying to keep multiple triangles on the screen, for example, to add a new one at every click, you should add them into a list of shapes which will be drawn whenever the component needs to be repainted:

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);
}

Then to control the set of shapes that is on screen, manipulate the contents of the list, and call repaint();.

For instance, to add a new shape to the ones on screen:

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

To remove all shapes from the screen:

shapes.clear();
repaint();

You should also make sure that you switch to the Swing thread at the start of the program, because it is not safe to interact with Swing components from the main thread. In main:

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



回答2:


Your mouseClicked method should not create a new Triangle object. After resetting triangle just add new points to it. Also don't draw in this method but call 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");
        }
    }

Now if you want many triangles you should have a collection of Polygons. Like this :

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;
}


来源:https://stackoverflow.com/questions/27717816/what-is-alternative-of-paint-and-repaint-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!