2013-08-30 40 views
2

我有一個JPanel,我在其中繪製線條以創建鉛筆幻覺。該面板位於ScrollPane無需重新驗證即可調整面板的尺寸

當我調整面板的大小時,將自動調用revalidate()方法,並且此面板中的所有繪製線都消失了。有沒有什麼辦法讓我的畫線與新的尺寸一致?

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.AdjustmentEvent; 
import java.awt.event.AdjustmentListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
/** 
* 
* @author Sanjeev 
*/ 
public class WorkArea extends JFrame implements ActionListener, MouseListener, MouseMotionListener 
{ 
private final int PEN_OP   = 1; 
private final int ERASER_OP  = 2; 
private final int SCROLL_OP  = 3; 
private int mousex    = 0; 
private int mousey    = 0; 
private int prevx     = 0; 
private int prevy     = 0; 
private boolean initialPen  = true; 
private boolean initialEraser  = true; 
private int eraserLength   = 5; 
private int opStatus   = PEN_OP; 
private Color mainColor   = new Color(0,0,0); 
private int drawPanelHeight  =1000; 

    public WorkArea() 
    { 
     initComponents(); 
     setLocationRelativeTo(null); 
     pencilButton.addActionListener(this); 
     eraserButton.addActionListener(this); 
     drawPanel.addMouseMotionListener(this); 
     drawPanel.addMouseListener(this); 
     drawPanel.add(new TestPane()); 
     this.addMouseListener(this); 
     this.addMouseMotionListener(this); 
    } 

    private void initComponents() { 

     headerPanel = new javax.swing.JPanel(); 
     backButton = new javax.swing.JLabel(); 
     headerImage = new javax.swing.JLabel(); 
     controlPanel = new javax.swing.JPanel(); 
     scrollButton = new javax.swing.JButton(); 
     pencilButton = new javax.swing.JButton(); 
     eraserButton = new javax.swing.JButton(); 
     drawingPanel = new javax.swing.JPanel(); 
     drawingScrollPane = new javax.swing.JScrollPane(); 
     drawPanel = new javax.swing.JPanel(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     setTitle("v0.1"); 
     setBackground(new java.awt.Color(237, 254, 255)); 
     setBounds(new java.awt.Rectangle(0, 0, 513, 693)); 
     setResizable(false); 

     headerPanel.setBackground(new java.awt.Color(237, 254, 255)); 
     headerPanel.setPreferredSize(new java.awt.Dimension(513, 25)); 
     headerPanel.setLayout(null); 

     backButton.setBackground(new java.awt.Color(237, 254, 255)); 
     backButton.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N 
     backButton.setForeground(new java.awt.Color(255, 255, 255)); 
     backButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/back-arrow.png"))); // NOI18N 
     backButton.setText("Back"); 
     backButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); 
     backButton.setPreferredSize(new java.awt.Dimension(40, 20)); 
     headerPanel.add(backButton); 
     backButton.setBounds(0, 3, 40, 20); 

     headerImage.setBackground(new java.awt.Color(237, 254, 255)); 
     headerImage.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N 
     headerImage.setForeground(new java.awt.Color(255, 255, 255)); 
     headerImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/topbar_ipad_wide.png"))); // NOI18N 
     headerImage.setText("Work Area"); 
     headerImage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER); 
     headerImage.setPreferredSize(new java.awt.Dimension(513, 25)); 
     headerPanel.add(headerImage); 
     headerImage.setBounds(0, 0, 513, 25); 

     controlPanel.setBackground(new java.awt.Color(237, 254, 255)); 
     controlPanel.setPreferredSize(new java.awt.Dimension(90, 670)); 
     controlPanel.setLayout(null); 

     scrollButton.setBackground(new java.awt.Color(237, 254, 255)); 
     scrollButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/up_down_ipad.png"))); // NOI18N 
     scrollButton.setPreferredSize(new java.awt.Dimension(60, 60)); 
     scrollButton.addMouseListener(new java.awt.event.MouseAdapter() { 
      public void mouseClicked(java.awt.event.MouseEvent evt) { 
       scrollButtonMouseClicked(evt); 
      } 
     }); 
     controlPanel.add(scrollButton); 
     scrollButton.setBounds(20, 570, 60, 60); 

     pencilButton.setBackground(new java.awt.Color(237, 254, 255)); 
     pencilButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/pencil_ipad.png"))); // NOI18N 
     pencilButton.addMouseListener(new java.awt.event.MouseAdapter() { 
      public void mouseClicked(java.awt.event.MouseEvent evt) { 
       pencilButtonMouseClicked(evt); 
      } 
     }); 
     controlPanel.add(pencilButton); 
     pencilButton.setBounds(20, 450, 60, 60); 

     eraserButton.setBackground(new java.awt.Color(237, 254, 255)); 
     eraserButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/eraser_ipad.png"))); // NOI18N 
     eraserButton.addMouseListener(new java.awt.event.MouseAdapter() { 
      public void mouseClicked(java.awt.event.MouseEvent evt) { 
       eraserButtonMouseClicked(evt); 
      } 
     }); 
     controlPanel.add(eraserButton); 
     eraserButton.setBounds(20, 510, 60, 60); 

     drawingPanel.setBackground(new java.awt.Color(237, 254, 255)); 
     drawingPanel.setPreferredSize(new java.awt.Dimension(420, 670)); 
     drawingPanel.setLayout(null); 

     drawingScrollPane.setBorder(null); 
     drawingScrollPane.setPreferredSize(new java.awt.Dimension(423, 1000)); 

     drawPanel.setBackground(new java.awt.Color(237, 254, 255)); 
     drawPanel.setPreferredSize(new java.awt.Dimension(400, 1000)); 
     drawPanel.setLayout(null); 
     drawingScrollPane.setViewportView(drawPanel); 

     drawingPanel.add(drawingScrollPane); 
     drawingScrollPane.setBounds(0, 0, 424, 670); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 513, Short.MAX_VALUE) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addComponent(headerPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 513, javax.swing.GroupLayout.PREFERRED_SIZE)) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(layout.createSequentialGroup() 
        .addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE) 
        .addGap(0, 423, Short.MAX_VALUE))) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 
        .addGap(0, 93, Short.MAX_VALUE) 
        .addComponent(drawingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 420, javax.swing.GroupLayout.PREFERRED_SIZE))) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 693, Short.MAX_VALUE) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(layout.createSequentialGroup() 
        .addComponent(headerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) 
        .addGap(0, 668, Short.MAX_VALUE))) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 
        .addGap(0, 23, Short.MAX_VALUE) 
        .addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 670, javax.swing.GroupLayout.PREFERRED_SIZE))) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 
        .addGap(0, 23, Short.MAX_VALUE) 
        .addComponent(drawingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 670, javax.swing.GroupLayout.PREFERRED_SIZE))) 
     ); 

     pack(); 
    }      

    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     if (e.getActionCommand() == "Pen") 
     opStatus = PEN_OP; 

     if (e.getActionCommand() == "Eraser") 
     opStatus = ERASER_OP; 

     if(e.getActionCommand() == "Scroll") 
     opStatus = SCROLL_OP; 
    } 

    private void pencilButtonMouseClickedTest(java.awt.event.MouseEvent evt) 
    {           
     opStatus = PEN_OP; 
     Graphics g = drawPanel.getGraphics(); 

     if (initialPen) 
     { 
     setGraphicalDefaults(evt); 
     initialPen = false; 
     g.drawLine(prevx,prevy,mousex,mousey); 
     } 
     if (mouseHasMoved(evt)) 
     { 
     mousex = evt.getX(); 
     mousey = evt.getY(); 
     g.drawLine(prevx,prevy,mousex,mousey); 
     prevx = mousex; 
     prevy = mousey; 
     } 
    } 

    private void eraserButtonMouseClickedTest(java.awt.event.MouseEvent evt) 
    { 
     opStatus = ERASER_OP; 
     Graphics g = drawPanel.getGraphics(); 

     if (initialEraser) 
     { 
     setGraphicalDefaults(evt); 
     initialEraser = false; 
     mousex = evt.getX(); 
     mousey = evt.getY(); 
     System.out.println("Initial Eraser ::::::::x's value is : "+prevx+" , "+mousey+" and y's value is : "+mousex+" , "+mousey); 
     g.setColor(new java.awt.Color(237,254,255)); 
     g.fillRect(mousex-eraserLength, mousey-eraserLength,eraserLength*2,eraserLength*2); 
     //g.setColor(Color.black); //Eraser Border 
     g.drawRect(mousex-eraserLength,mousey-eraserLength,eraserLength*2,eraserLength*2); 
     prevx = mousex; 
     prevy = mousey; 
     } 

     if (mouseHasMoved(evt)) 
     { 
     System.out.println("Eraser ::::::::x's value is : "+prevx+" , "+mousey+" and y's value is : "+mousex+" , "+mousey); 
     g.setColor(new java.awt.Color(237,254,255)); 
     g.drawRect(prevx-eraserLength, prevy-eraserLength,eraserLength*2,eraserLength*2); 

     mousex = evt.getX(); 
     mousey = evt.getY(); 

     /* Draw eraser block to panel */ 
     g.setColor(new java.awt.Color(237,254,255)); 
     g.fillRect(mousex-eraserLength, mousey-eraserLength,eraserLength*2,eraserLength*2); 
     g.setColor(Color.black);//Eraser Border 
     g.drawRect(mousex-eraserLength,mousey-eraserLength,eraserLength*2,eraserLength*2); 
     prevx = mousex; 
     prevy = mousey; 
     } 
    } 


    private void scrollButtonMouseClicked(java.awt.event.MouseEvent evt) {           
     opStatus = SCROLL_OP; 
     drawingScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 

     @Override 
     public void adjustmentValueChanged(AdjustmentEvent e) 
     { 
     int extent,curValue; 
     extent = drawingScrollPane.getVerticalScrollBar().getModel().getExtent(); 
     curValue = drawingScrollPane.getVerticalScrollBar().getValue()+extent; 
     if(curValue==drawPanel.getHeight()) 
     { 
     System.out.println("value of scroll equals to Max value...."); 
     drawPanel.setPreferredSize(new Dimension(423,drawPanelHeight*4));  
     } 
     System.out.println("Value: " + curValue + " Max: " + drawingScrollPane.getVerticalScrollBar().getMaximum()); 
     } 
     }); 
    }           

    private void eraserButtonMouseClicked(java.awt.event.MouseEvent evt) {           
     eraserButtonMouseClickedTest(evt); 
     updateMouseCoordinates(evt); 
    }           

    private void pencilButtonMouseClicked(java.awt.event.MouseEvent evt) {           
     opStatus = PEN_OP; 

    }           




    public boolean mouseHasMoved(MouseEvent e) 
    { 
    return (mousex != e.getX() || mousey != e.getY()); 
    } 

public void setGraphicalDefaults(MouseEvent e) 
{ 
    mousex = e.getX(); 
    mousey = e.getY(); 
    prevx = e.getX(); 
    prevy = e.getY(); 
} 

@Override 
    public void mouseDragged(MouseEvent e) 
    { 
     updateMouseCoordinates(e); 

     switch (opStatus) 
     { 
      case PEN_OP : pencilButtonMouseClickedTest(e); 
          break; 
      case ERASER_OP: eraserButtonMouseClicked(e); 
          break; 
      case SCROLL_OP: scrollButtonMouseClicked(e); 
          break; 
     } 
    } 

    public void mouseReleased(MouseEvent e) 
    { 
     updateMouseCoordinates(e); 

     switch (opStatus) 
     { 
      case PEN_OP : releasedPen(); 
          break; 
      case ERASER_OP : releasedEraser(); 
          break; 
     } 
    } 

    public void mouseEntered(MouseEvent e) 
    { 
    updateMouseCoordinates(e); 
    } 

    public void releasedPen() 
    { 
    initialPen = true; 
    } 

    public void releasedEraser() 
    { 
    initialEraser = true; 
    Graphics g = drawPanel.getGraphics(); 
    g.setColor(mainColor.white); 
    g.drawRect(mousex-eraserLength,mousey-eraserLength,eraserLength*2,eraserLength*2); 
    } 

    public void updateMouseCoordinates(MouseEvent e) 
    { 
    String xCoor =""; 
    String yCoor =""; 

    if (e.getX() < 0) xCoor = "0"; 
    else 
    { 
     xCoor = String.valueOf(e.getX()); 
    } 

    if (e.getY() < 0) xCoor = "0"; 
    else 
    { 
     yCoor = String.valueOf(e.getY()); 
    } 
    } 

    public static void main(String args[]) { 
     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(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (InstantiationException ex) { 
      java.util.logging.Logger.getLogger(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (IllegalAccessException ex) { 
      java.util.logging.Logger.getLogger(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
      java.util.logging.Logger.getLogger(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } 

     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new WorkArea().setVisible(true); 
      } 
     }); 
    }     
    private javax.swing.JLabel backButton; 
    private javax.swing.JPanel controlPanel; 
    private javax.swing.JPanel drawPanel; 
    private javax.swing.JPanel drawingPanel; 
    private javax.swing.JScrollPane drawingScrollPane; 
    private javax.swing.JButton eraserButton; 
    private javax.swing.JLabel headerImage; 
    private javax.swing.JPanel headerPanel; 
    private javax.swing.JButton pencilButton; 
    private javax.swing.JButton scrollButton;    

    @Override 
    public void mouseClicked(MouseEvent e) { 

    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
     updateMouseCoordinates(e); 
    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 
     updateMouseCoordinates(e); 
    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     updateMouseCoordinates(e); 
    } 
} 
+0

哪一部分component.getGraphics **很難理解? – kleopatra

+0

@kleopatra從component.getGraphics中,當尺寸改變等屬性時,您將無法在面板上保留圖形!爲此你需要使用paintComponent方法。但是這種技術也有其自身的侷限性! – Neo

+0

@kleopatra我認爲,而不是按下+ ve按鈕,你已經按下了ve按鈕! – Neo

回答

4

我假設你正在使用getGraphics()和渲染你出來把它畫到JPanel

你現在已經看到你爲什麼不應該這樣做。當部件重新塗漆時,先前塗漆的任何東西都會被清潔乾淨,並且您需要重新塗漆內容。

開始通過重寫paintComponent並在此方法中更新所有的行(不要忘記調用super.paintComponent

更多細節

例如見Performing Custom PaintingPainting in AWT and Swing ..

已更新,例如

這是答案的一個修改的版本MouseEvent is not registering a release when I release the mouse button其包括滾動窗格...

enter image description here

import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Point; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.UIManager; 

public class MouseDraggedTest { 

    public static void main(String[] args) { 
     new MouseDraggedTest(); 
    } 

    public MouseDraggedTest() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (Exception ex) { 
       } 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new JScrollPane(new TestPane())); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private Map<Point, List<Point>> mapPoints; 
     private Point currentPoint; 

     public TestPane() { 
      mapPoints = new HashMap<>(25); 
      MouseAdapter mouseListener = new MouseAdapter() { 
       @Override 
       public void mousePressed(MouseEvent e) { 
        currentPoint = e.getPoint(); 
        mapPoints.put(currentPoint, new ArrayList<Point>(25)); 
       } 

       @Override 
       public void mouseReleased(MouseEvent e) { 
        List<Point> points = mapPoints.get(currentPoint); 
        if (points.isEmpty()) { 
         mapPoints.remove(currentPoint); 
        } 
        currentPoint = null; 
       } 

       @Override 
       public void mouseDragged(MouseEvent me) { 
        List<Point> points = mapPoints.get(currentPoint); 
        points.add(me.getPoint()); 
        repaint(); 
       } 
      }; 
      addMouseListener(mouseListener); 
      addMouseMotionListener(mouseListener); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 800); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 

      for (Point startPoint : mapPoints.keySet()) { 
       List<Point> points = mapPoints.get(startPoint); 
       for (Point p : points) { 
        if (startPoint != null) { 
         g.drawLine(startPoint.x, startPoint.y, p.x, p.y); 
        } 
        startPoint = p; 
       } 
      } 
     } 
    } 
} 

與一個BufferedImage示例更新

因爲你需要的不僅僅是繪製提供更多的操作,你會發現它更容易使用BufferedImage作爲主繪圖表面和渲染這的**不要使用DrawingPanel

enter image description here

import java.awt.BasicStroke; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Point; 
import java.awt.Shape; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Ellipse2D; 
import java.awt.geom.Line2D; 
import java.awt.image.BufferedImage; 
import javax.swing.ButtonGroup; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JToggleButton; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class MyPicture { 

    public static void main(String[] args) { 
     new MyPicture(); 
    } 

    public MyPicture() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public enum DrawOperation { 

     Draw, 
     Erase 

    } 

    public class TestPane extends JPanel { 

     private DrawOperation op; 

     private JToggleButton pencil; 
     private JToggleButton eraser; 

     private DrawPane drawPane; 

     public TestPane() { 
      setLayout(new BorderLayout()); 

      drawPane = new DrawPane(); 

      MouseAdapter adapter = new MouseAdapter() { 

       private Point startPoint; 

       @Override 
       public void mouseEntered(MouseEvent e) { 
        drawPane.updateDrawCursor(e.getPoint(), op); 
       } 

       @Override 
       public void mouseExited(MouseEvent e) { 
        drawPane.removeDrawCursor(); 
       } 

       @Override 
       public void mousePressed(MouseEvent e) { 
        startPoint = e.getPoint(); 
       } 

       @Override 
       public void mouseReleased(MouseEvent e) { 
        startPoint = null; 
       } 

       @Override 
       public void mouseDragged(MouseEvent e) { 
        drawPane.applyOperation(startPoint, e.getPoint(), op); 
        drawPane.updateDrawCursor(e.getPoint(), op); 
        startPoint = e.getPoint(); 
       } 

       @Override 
       public void mouseMoved(MouseEvent e) { 
        drawPane.updateDrawCursor(e.getPoint(), op); 
       } 

      }; 

      drawPane.addMouseListener(adapter); 
      drawPane.addMouseMotionListener(adapter); 

      JPanel operations = new JPanel(new GridBagLayout()); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridwidth = GridBagConstraints.REMAINDER; 

      pencil = new JToggleButton("Draw"); 
      eraser = new JToggleButton("Erase"); 

      ButtonGroup bgOps = new ButtonGroup(); 
      bgOps.add(pencil); 
      bgOps.add(eraser); 

      operations.add(pencil, gbc); 
      operations.add(eraser, gbc); 

      pencil.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        op = DrawOperation.Draw; 
       } 
      }); 

      eraser.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        op = DrawOperation.Erase; 
       } 
      }); 

      add(operations, BorderLayout.WEST); 
      add(new JScrollPane(drawPane)); 
     } 

    } 

    public class DrawPane extends JPanel { 

     private BufferedImage image; 
     private Shape drawCursor; 
     private Point cursorPoint; 

     private int eraseSize = 20; 

     public DrawPane() { 
      image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB); 
      Graphics2D g2d = image.createGraphics(); 
      g2d.setBackground(Color.WHITE); 
      g2d.fillRect(0, 0, 400, 400); 
      g2d.dispose(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(400, 400); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      if (image != null) { 
       g2d.drawImage(image, 0, 0, this); 
      } 
      if (drawCursor != null && cursorPoint != null) { 
       int x = (cursorPoint.x - (drawCursor.getBounds().width)/2); 
       int y = (cursorPoint.y - (drawCursor.getBounds().height)/2); 
       g2d.translate(x, y); 
       g2d.draw(drawCursor); 
       g2d.translate(-x, -y); 
      } 
      g2d.dispose(); 
     } 

     public void updateDrawCursor(Point point, DrawOperation op) { 
      cursorPoint = point; 
      if (op != null) { 
       switch (op) { 
        case Draw: 
         drawCursor = new Ellipse2D.Float(0, 0, 4, 4); 
         break; 
        case Erase: 
         drawCursor = new Ellipse2D.Float(0, 0, eraseSize, eraseSize); 
         break; 
       } 
      } else { 
       drawCursor = null; 
      } 
      repaint(); 
     } 

     protected void removeDrawCursor() { 
      drawCursor = null; 
      repaint(); 
     } 

     protected void applyOperation(Point fromPoint, Point toPoint, DrawOperation op) { 
      if (image != null) { 

       if (op != null) { 
        Graphics2D g2d = image.createGraphics(); 
        switch (op) { 
         case Draw: 
          g2d.setColor(Color.BLACK); 
          g2d.draw(new Line2D.Float(fromPoint, toPoint)); 
          break; 
         case Erase: 
          g2d.setColor(Color.WHITE); 
          g2d.setStroke(new BasicStroke(eraseSize)); 
          g2d.draw(new Line2D.Float(fromPoint, toPoint)); 
          break; 
        } 
        g2d.dispose(); 
       } 

      } 
      repaint(); 
     } 
    } 
} 
+0

先生,我們可以在已創建的JPanel像drawPanel中添加此代碼嗎?因爲我在編寫drawPanel.paintComponent(g)時遇到了paintComponent()方法中的問題;它表示paintComponent(Graphics)已經在JComponent中保護了訪問。 – Neo

+1

你不應該自己調用paintComponent。它將被RepaintManager自動調用。你有沒有通讀提供的鏈接? – MadProgrammer

+0

現在我正在閱讀這些鏈接。在此之前,我只是試圖儘快實施它。 – Neo