简体   繁体   English

每当调整JFrame的大小时,为什么我的JPanel上的油漆会清除?

[英]Why does the paint clear on my JPanel whenever the JFrame is resized?

Go ahead, test the code. 继续,测试代码。 When the program is running, you can draw on the panel, but whenever it resized, the paint disappears. 程序运行时,您可以在面板上绘制,但是只要调整大小,油漆就会消失。 Any idea why or how to solve this? 知道为什么或如何解决这个问题吗? I would love the help! 我很乐意提供帮助!

Window.java --The GUI class Window.java-GUI类

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JSeparator;
import javax.swing.JToolBar;

public class Window extends JFrame implements ComponentListener {

    public Window(){

        this.setSize(700, 700);
        this.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        this.setJMenuBar(menubar);
        this.add(new PaintPanel());
        this.setTitle("JPaint");
        this.setBackground(Color.WHITE);
        this.add(TOOL_BAR, BorderLayout.NORTH);
        TOOL_BAR.add(BUTTON);
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        this.add(PAINT_PANEL);
        menubar.add(FILE);
        FILE.setMnemonic(KeyEvent.VK_F);
        FILE.add(NEW);
        FILE.add(NEW_OPEN_SEPARATOR);
        FILE.add(OPEN);
        FILE.add(SAVE);
        FILE.add(SAVE_AS);
        FILE.add(SEPARATOR);
        FILE.add(EXIT);
        menubar.add(Box.createHorizontalGlue());
        menubar.add(HELP);
        HELP.add(ABOUT);
        HELP.add(GNU_PUBLIC_LICENSE);

        this.setVisible(true);

        NEW.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                PAINT_PANEL.repaint();

            }

        });

        OPEN.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                final JFileChooser FILE_CHOOSER = new JFileChooser();
                int CHOSEN_FILE = FILE_CHOOSER.showOpenDialog(FILE_CHOOSER);

            }

        });

        SAVE.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                final JFileChooser SAVE_FILE_CHOOSER = new JFileChooser();
                SAVE_FILE_CHOOSER.showSaveDialog(null);
                Container c = frame.getContentPane();
                BufferedImage SAVED_IMAGE = new BufferedImage(c.getWidth(), c
                        .getHeight(), BufferedImage.TYPE_INT_ARGB);
                c.paint(SAVED_IMAGE.getGraphics());
                try {
                    ImageIO.write(SAVED_IMAGE, "PNG", new File("test.png"));
                } catch (IOException e1) {
                    // If unable to save image for 'Exception' reason.
                    e1.printStackTrace();
                }

            }

        });

        EXIT.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                System.exit(0);

            }

        });

        ABOUT.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                JOptionPane
                        .showMessageDialog(frame,
                                "Created by Matthew Hanzelik for "
                                        + "open source use!");

            }

        });
        GNU_PUBLIC_LICENSE.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(frame, "gpl.txt");

            }

        });

    }

    /**
     * Serial Version
     */
    private static final JFrame frame = new JFrame();

    private static final long serialVersionUID = 5259700796854880162L;

    private static final JMenuBar menubar = new JMenuBar();
    private static final JMenu FILE = new JMenu("File");
    private static final JMenu HELP = new JMenu("Help");
    private static final JMenuItem SAVE = new JMenuItem("Save");
    private static final JMenuItem EXIT = new JMenuItem("Exit");
    private static final JSeparator SEPARATOR = new JSeparator();
    private static final JSeparator NEW_OPEN_SEPARATOR = new JSeparator();
    private static final JMenuItem NEW = new JMenuItem("New");
    private static final JMenuItem OPEN = new JMenuItem("Open");
    private static final JMenuItem SAVE_AS = new JMenuItem("Save as...");
    private static final JMenuItem ABOUT = new JMenuItem("About");
    private static final JMenuItem GNU_PUBLIC_LICENSE = new JMenuItem(
            "GNU Public License");
    private static final JToolBar TOOL_BAR = new JToolBar();
    private static final JButton BUTTON = new JButton("Test");
    private static final PaintPanel PAINT_PANEL = new PaintPanel();

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Window GUI = new Window();
            }

        });

    }

    @Override
    public void componentHidden(ComponentEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void componentMoved(ComponentEvent arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void componentResized(ComponentEvent arg0) {
        // TODO Auto-generated method stub
        System.out.println("resized");
    }

    @Override
    public void componentShown(ComponentEvent arg0) {
        // TODO Auto-generated method stub

    }

}

PaintPanel --The class that contains the panel on which to paint on PaintPanel-包含要在其上进行绘画的面板的类

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JPanel;

@SuppressWarnings("serial")
public class PaintPanel extends JPanel {
    MouseMotionListener theListener;
    Graphics g;
    MouseListener theListening;
    int x, y, x1, y1;
    boolean inside;

    public PaintPanel() {
        x = 0;
        y = 0;
        x1 = -99;
        y1 = -99;
        inside = false;
        theListener = new MouseMotionListener() {
            public void mouseDragged(MouseEvent arg0) {
                if (inside) {
                    repaint();
                }
            }

            public void mouseMoved(MouseEvent arg0) {
            }
        };
        theListening = new MouseListener() {

            public void mouseClicked(MouseEvent arg0) {

            }

            public void mousePressed(MouseEvent arg0) {

            }

            public void mouseReleased(MouseEvent arg0) {
                x1 = -99;
                y1 = -99;
            }

            public void mouseEntered(MouseEvent arg0) {
                inside = true; 
                x1 = -99;
                y1 = -99; 
            }

            public void mouseExited(MouseEvent arg0) {
                inside = false; 
                x1 = -99;
                y1 = -99;
            }
        };
        this.setBackground(Color.WHITE);
        this.setVisible(true);
        this.addMouseMotionListener(theListener);
        this.addMouseListener(theListening);
    }

    @Override
    public void paint(Graphics g) {

        try {
            if (x1 == -99) { 


                x = getMousePosition().x;
                x1 = x; 
                y = getMousePosition().y;
                y1 = y; 
            } else
            {
                x = getMousePosition().x;
                y = getMousePosition().y;
                g.drawLine(x, y, x1, y1);
                x1 = x;
                y1 = y;
            }
        } catch (Exception ex) {
        }
    }
}

Two things: first, when extending a JComponent , you should really override paintCompontent , not paint . 两件事:首先,在扩展JComponent ,您应该真正覆盖paintCompontent而不是paint

Secondly, inside of your paintComponent , you need to render all of the lines that the user has drawn. 其次,在paintComponent内部,需要呈现用户绘制的所有线条。 This means that you need to store them as they are drawn, and then render them all inside of paintComponent every time. 这意味着您需要在绘制它们时将它们存储起来,然后每次都将它们全部渲染到paintComponent内部。 This is because paintComponent gets called any time the window needs to be re-rendered (for example, when the window has been minimized and then restored). 这是因为在需要重新渲染窗口的任何时候都会调用paintComponent (例如,当窗口最小化然后还原时)。 Swing does not "remember" which pixels you've set to which colors in this case. 在这种情况下,Swing不会“记住”您将哪些像素设置为哪种颜色。 Instead, it calls paintComponent and expects you to re-create them. 而是调用paintComponent并希望您重新创建它们。

Also, when you override paintComponent , you will most likely want to call super.paintComponent before doing any of your rendering work. 另外,当您覆盖paintComponent ,您很可能希望在执行任何渲染工作之前先调用super.paintComponent

, but whenever it resized, the paint disappears. ,但是只要调整大小,油漆就会消失。 Any idea why or how to solve this? 知道为什么或如何解决这个问题吗?

If you want to do incremental painting then there are two common approaches: 如果要进行增量绘画,则有两种常用方法:

  1. Keep an ArrayList of the Objects you want to paint and then repaint all the Object every time the component is repainted. 保留要绘制的对象的ArrayList,然后在每次重新绘制组件时重新绘制所有Object。
  2. Paint your objects directly to a BufferedImage. 将对象直接绘制到BufferedImage上。 Then the BufferedImage will be repainted automatically every time. 然后,每次都会自动重新绘制BufferedImage。

See Custom Painting Approaches for more information and working examples of each approach. 有关更多信息和每种方法的工作示例,请参见自定义绘画方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM