我正在 java 中制作一个简单的绘图程序,我可以绘图,但是当我最小化 window 或调整大小时,我绘制的内容就会消失。我怎样才能让他们留下来?

I am making a simple paint program in java, I can draw but when I minimize the window or resize what I painted goes away. How do I get them to stay?

这是我目前所拥有的,我尝试创建绘图函数只是为了测试它是否可行。调色板只是另一个 gui window,一旦我首先解决了这个保存问题,它就会有颜色选项

import csc260final.Palette;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JOptionPane;


/**
*
* @author Jared Hughes
*/
public class Canvas extends javax.swing.JFrame {

/**
 * Creates new form Canvas
 */


Draw line;
private int curX, curY, oldX, oldY;
public Graphics2D g2;
Palette palette;



public Canvas() {

    initComponents();
    palette = new Palette();
    palette.setVisible(true);



}
public void draw(){

     g2 = (Graphics2D) jPanel1.getGraphics();
     g2.setColor(Color.yellow);
     g2.setStroke(new BasicStroke(10));
     g2.drawLine(oldX, oldY, curX, curY);

}

public void paint(Graphics g){

    Graphics2D g2 = (Graphics2D)g;
    super.paint(g);




}



/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    jButton1 = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jPanel1.setBackground(new java.awt.Color(255, 255, 255));
    jPanel1.setPreferredSize(new java.awt.Dimension(1130, 550));
    jPanel1.setRequestFocusEnabled(false);
    jPanel1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
        public void mouseDragged(java.awt.event.MouseEvent evt) {
            jPanel1MouseDragged(evt);
        }
        public void mouseMoved(java.awt.event.MouseEvent evt) {
            jPanel1MouseMoved(evt);
        }
    });
    jPanel1.addMouseListener(new java.awt.event.MouseAdapter() {
        public void mouseClicked(java.awt.event.MouseEvent evt) {
            jPanel1MouseClicked(evt);
        }
        public void mouseEntered(java.awt.event.MouseEvent evt) {
            jPanel1MouseEntered(evt);
        }
        public void mouseExited(java.awt.event.MouseEvent evt) {
            jPanel1MouseExited(evt);
        }
        public void mousePressed(java.awt.event.MouseEvent evt) {
            jPanel1MousePressed(evt);
        }
        public void mouseReleased(java.awt.event.MouseEvent evt) {
            jPanel1MouseReleased(evt);
        }
    });

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 1130, Short.MAX_VALUE)
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 550, Short.MAX_VALUE)
    );

    jButton1.setText("jButton1");

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jButton1)
            .addGap(94, 94, 94))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 28, Short.MAX_VALUE)
            .addComponent(jButton1)
            .addContainerGap())
    );

    pack();
}// </editor-fold>                        

private void jPanel1MousePressed(java.awt.event.MouseEvent evt) {                                     
    // TODO add your handling code here:
    // save x and y when mouse is pressed        
     curX = evt.getX();
     curY = evt.getY();
     oldX = curX;
     oldY = curY; 


}                                    

private void jPanel1MouseDragged(java.awt.event.MouseEvent evt) {                                     
    // TODO add your handling code here:
    // get x and y when mouse is dragged

     curX = evt.getX();
     curY = evt.getY();

     g2 = (Graphics2D) jPanel1.getGraphics();
     g2.setColor(Color.yellow);
     g2.setStroke(new BasicStroke(10));
     g2.drawLine(oldX, oldY, curX, curY);

     oldX = curX;
     oldY = curY; 



}                                    

private void jPanel1MouseClicked(java.awt.event.MouseEvent evt) {                                     
    // TODO add your handling code here:      


}                                    

private void jPanel1MouseEntered(java.awt.event.MouseEvent evt) {                                     
    // TODO add your handling code here:
}                                    

private void jPanel1MouseMoved(java.awt.event.MouseEvent evt) {                                   
    // TODO add your handling code here:
}                                  

private void jPanel1MouseExited(java.awt.event.MouseEvent evt) {                                    
    // TODO add your handling code here:
}                                   

private void jPanel1MouseReleased(java.awt.event.MouseEvent evt) {                                      
    // TODO add your handling code here:


}                                     

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(Canvas.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(Canvas.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(Canvas.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(Canvas.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>


    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new Canvas().setVisible(true);
        }
    });
}

// Variables declaration - do not modify                     
private javax.swing.JButton jButton1;
private javax.swing.JPanel jPanel1;
// End of variables declaration                   

}

您的 Swing 绘图未正确完成。您不应使用通过在组件上调用 getGraphics() 获得的 Graphics 对象进行绘制。这将 return 一个短暂的 Graphics 对象,冒着消失图形或更糟的风险,一个 NullPointerException。相反,直接或通过在 BufferedImage 上绘制(是的,您可以通过 getGraphics() 获取其 Graphics 对象)间接绘制 JPanel 的 paintComponent(...) 方法,然后在 paintComponent 方法中将 BufferedImage 绘制到 GUI .

有用的Java教程:

小吹毛求疵:

  • 避免提供与核心 Java 类 冲突的 类 名称,例如 Canvas。这将有助于防止混淆他人和你未来的自己。
  • 在这里发布代码时,如果您努力将其格式化,包括明智地使用空行,我们将不胜感激。您上面的代码有几个大的空白区域,很难遵循。在这里或那里有一个空行是可以的,但是很多,不是那么多。

例如:

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.*;

@SuppressWarnings("serial")
public class TestDrawingCanvas extends JPanel {
    private DrawingCanvas drawingCanvas = new DrawingCanvas();

    public TestDrawingCanvas() {
        JPanel btnPanel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
        btnPanel.add(new JButton(new ClearAction()));

        setLayout(new BorderLayout());
        add(drawingCanvas, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.PAGE_END);
    }

    private class ClearAction extends AbstractAction {
        public ClearAction() {
            super("Clear Canvas");
            putValue(MNEMONIC_KEY, KeyEvent.VK_C);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            drawingCanvas.clear();
        }
    }

    private static void createAndShowGui() {
        TestDrawingCanvas mainPanel = new TestDrawingCanvas();

        JFrame frame = new JFrame("Drawing Canvas");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

@SuppressWarnings("serial")
class DrawingCanvas extends JPanel {
    private static final int PREF_W = 800;
    private static final int PREF_H = 600;
    public static final Color LINE_COLOR = Color.YELLOW;
    public static final Stroke IMG_STROKE = new BasicStroke(10f);
    private Color lineColor = LINE_COLOR;
    private BufferedImage image;

    public DrawingCanvas() {
        setBackground(Color.WHITE);
        image = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (image != null) {
            g.drawImage(image, 0, 0, this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    public void setLineColor(Color lineColor) {
        this.lineColor = lineColor;
    }

    public void clear () {
        image = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
        repaint();
    }

    private class MyMouse extends MouseAdapter {
        private Graphics2D imgG2d;
        private Point p1;

        @Override
        public void mousePressed(MouseEvent e) {
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }

            imgG2d = image.createGraphics();
            imgG2d.setColor(lineColor);
            imgG2d.setStroke(IMG_STROKE);
            p1 = e.getPoint();
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            drawLine(e);
            imgG2d.dispose();
            p1 = null;
            imgG2d = null;
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            drawLine(e);
            p1 = e.getPoint();
        }

        private void drawLine(MouseEvent e) {
            if (imgG2d == null || p1 == null) {
                return;
            }
            Point p2 = e.getPoint();
            int x1 = p1.x;
            int y1 = p1.y;
            int x2 = p2.x;
            int y2 = p2.y;
            imgG2d.drawLine(x1, y1, x2, y2);
            repaint();
        }
    }
}