什么是Paint的替代和重绘功能?

时间:2014-12-31 07:34:54

标签: java swing graphics jframe awt

在java中是否有任何可以用paint()repaint()替换的函数。

我有一个场景。

有一个三角形(三角1)。当用户点击三角形时,将出现另一个三角形(三角形2),第一个(三角形1)将从屏幕上删除。 (使用JFramepaint()repaint())编码

到目前为止我已经实现了它。但问题是当我用鼠标输出窗口最小化或改变窗口大小时,它只是再次绘制三角形1 而不是三角形2 OR 如果我拨打g2d.clearRect(0, 0, 1000, 1000);
triangle.reset();

,请清除整个屏幕

注意:这两个函数都是删除前一个三角形(三角形1)。

是否有任何函数在最小化或窗口大小改变时不应更改状态?

或者我们可以根据情景覆盖repaint()或其他任何帮助。

这是工作代码。执行它,单击三角形然后最小化并再次查看。你会更清楚地解决问题。

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

2 个答案:

答案 0 :(得分:2)

paint()repaint()工作正常,但您没有使用它们,因为它们的设计目的是使用它们。窗口系统不会保持组件外观的持久图像。它希望您的组件能够按需重新绘制其整个外观(例如,当窗口调整大小或未最小化时)。

如果你使用getGraphics()抓取一个Graphics对象并在组件上绘制一些东西,那么当你需要重新绘制整个组件时,你绘制的东西确实会丢失。因此,您不应该这样做,而是确保您的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);
}

或者,如果您尝试在屏幕上保留多个三角形,例如,要在每次点击时添加新的三角形,您应该将它们添加到list个形状中,只要组件需要,就会绘制这些形状重新粉刷:

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

答案 1 :(得分:2)

您的mouseClicked方法不应创建新的 Triangle 对象。重置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;
}