簡體   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