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

时间:2014-05-16 16:07:34

标签: java swing jframe jpanel

继续,测试代码。程序运行时,您可以在面板上绘图,但无论何时调整大小,绘画都会消失。知道为什么或如何解决这个问题?我很乐意帮忙!

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

2 个答案:

答案 0 :(得分:2)

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

其次,在paintComponent内,您需要渲染用户绘制的所有行。这意味着您需要在绘制时存储它们,然后每次都在paintComponent内部渲染它们。这是因为只要窗口需要重新渲染(例如,窗口已经最小化然后恢复),就会调用paintComponent。在这种情况下,Swing不会“记住”您将哪些像素设置为哪种颜色。相反,它会调用paintComponent并希望您重新创建它们。

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

答案 1 :(得分:1)

  

,但每当它调整大小时,油漆就会消失。知道为什么或如何解决这个问题?

如果你想做增量绘画,那么有两种常见的方法:

  1. 保留要绘制的对象的ArrayList,然后在每次重新绘制组件时重新绘制所有Object。
  2. 将对象直接绘制到BufferedImage。然后每次都会自动重新绘制BufferedImage。
  3. 有关每种方法的更多信息和工作示例,请参阅Custom Painting Approaches