繁体   English   中英

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

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

继续,测试代码。 程序运行时,您可以在面板上绘制,但是只要调整大小,油漆就会消失。 知道为什么或如何解决这个问题吗? 我很乐意提供帮助!

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-包含要在其上进行绘画的面板的类

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

两件事:首先,在扩展JComponent ,您应该真正覆盖paintCompontent而不是paint

其次,在paintComponent内部,需要呈现用户绘制的所有线条。 这意味着您需要在绘制它们时将它们存储起来,然后每次都将它们全部渲染到paintComponent内部。 这是因为在需要重新渲染窗口的任何时候都会调用paintComponent (例如,当窗口最小化然后还原时)。 在这种情况下,Swing不会“记住”您将哪些像素设置为哪种颜色。 而是调用paintComponent并希望您重新创建它们。

另外,当您覆盖paintComponent ,您很可能希望在执行任何渲染工作之前先调用super.paintComponent

,但是只要调整大小,油漆就会消失。 知道为什么或如何解决这个问题吗?

如果要进行增量绘画,则有两种常用方法:

  1. 保留要绘制的对象的ArrayList,然后在每次重新绘制组件时重新绘制所有Object。
  2. 将对象直接绘制到BufferedImage上。 然后,每次都会自动重新绘制BufferedImage。

有关更多信息和每种方法的工作示例,请参见自定义绘画方法。

暂无
暂无

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

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