2012-12-21 2 views
3

나는 기본적으로 MS 그림판의 단순화 된 버전 인 드로잉 보드 프로그램을 생성합니다. 대부분의 경우 작동하지만 게시판에 그릴 때 현재 선택된 UI 요소가 그리기 영역에 표시됩니다.Java에서 사용자 정의 페인팅 - JPanel에 UI 요소 그리기

super.paintComponent (g)를 호출 할 때 효과가있는 paintComponent를 시도했지만 다음 객체를 그리기 전에 그리기 영역을 지웠습니다. 나는 업데이트를 무시하고 거기에 println 문을 넣었습니다. 결코 호출되지 않습니다.

배경의 JPanel을 빨간색으로 설정했기 때문에 맨 위에있는 버튼이 빨간색으로 표시되어이 버튼의 배경을 알 수 있습니다. 그래서 분명히 하단 JPanel의 일부입니다. 레이아웃에 BorderLayout을 사용하고 있습니다. 여기

enter image description here

이 (제거 어떤 관련이없는 비트) 내 코드입니다 : 현재 선택한 UI 요소가 도면 영역에 표시되는 경우

public class JSPaint extends JFrame implements Serializable 
{  
    private static final long serialVersionUID = -8787645153679803322L; 
    private JFrame mainFrame; 
    private JPanel bp; 
    private JButton ... 
    private DrawingArea da; 

    public JSPaint() 
    { 
     setTitle("JS Paint"); 
     setSize(1024, 768); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     // Drawing area 
     da = new DrawingArea(); 

     setLayout(new BorderLayout()); 

     // add the buttons to the panel 
     buttonPanel(); 

     // Add the drawing area 
     add(bp, BorderLayout.SOUTH); 
     bp.setBackground(Color.RED); 
     add(da, BorderLayout.CENTER); 
     da.setBackground(Color.BLUE); 

     setVisible(true);   
    } 

    // I put it here too just in case 
    @Override 
    public void update(Graphics g) 
    { 
     System.out.println("update in JSPaint called."); 
     paint(g); 
    } 

    /* 
    * Creates the panel for the buttons, creates the buttons and places them on 
    * the panel 
    */ 
    public void buttonPanel() 
    { 
     // Create the panel for the buttons to be placed in 
     bp = new JPanel(); 

     saveButton = new JButton("Save"); 
     loadButton = new JButton("Load"); 
     //more buttons 

     bp.add(saveButton); 
     bp.add(loadButton); 
     //more buttons 

     // ActionListeners 

     colorButton.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent ae) 
      { 
       System.out.println("color"); 
       da.color(); 
      } 
     });    
    } 

    public class DrawingArea extends JPanel 
    {   
     private static final long serialVersionUID = -8299084743195098560L; 
     boolean dragged = false; 

     @Override 
     public void update(Graphics g) 
     { 
      System.out.println("Update in DrawingArea called"); 
      paint(g); 
     } 

     /* 
     * Draws the selected shape onto the screen and saves it into a Stack. 
     * 
     */ 
     public void draw() 
     { 
      this.addMouseMotionListener(new MouseMotionListener() 
      {     
       public void mouseDragged(MouseEvent me) 
       { 
        dragged = true; 
       } 

       public void mouseMoved(MouseEvent me) {} 
      }); 

      //more listeners... 
      }); 
     } 

     /* 
     * Draws the selected String onto the screen when the mouse is held down. 
     * 
     */ 
     public void brush() 
     { 
      this.addMouseMotionListener(new MouseMotionListener() 
      {     
       public void mouseDragged(MouseEvent me) 
       { 
        // If we are in drawing mode, draw the String. Create a new 
        // Figure Object and push it onto the Stack 
        if(activeButton == "brush") 
        { 
         startPoint = me.getPoint(); 

         Figure fig = new Figure("String", startPoint, null, currentColor); 
//      figures.push(calculate(fig)); 
         toPaint.push(calculate(fig)); 
         repaint(); 
        } 
       } 

       public void mouseMoved(MouseEvent me) {} 
      });   
     } 

     // more of the same... 

     public void paint(Graphics g) 
     {       
      toSave.addAll(toPaint); 

      while(!toPaint.isEmpty()) 
      { 
       Figure f = toPaint.pop(); 
       String t = f.type; 

       if(f.color != null) 
       { 
        g.setColor(f.color); 
       } 

       switch(t) 
       { 
        case "Rectangle": g.drawRect(f.x1, f.y1, f.width, f.height); 
         break; 
        case "Oval": g.drawOval(f.x1, f.y1, f.width, f.height); 
         break;   
        case "Line": g.drawLine(f.x1, f.y1, f.x2, f.y2); 
         break; 
        case "Clear": 
         g.fillRect(0, 0, da.getWidth(), da.getHeight()); 
         clearStack(toSave); 
         break; 
        case "String": g.drawString(f.toPrint, f.x1, f.y1); 
         break; 
       } 
      } 
     } 
    } 

    private class Figure implements Serializable 
    { 
     private static final long serialVersionUID = 4690475365105752994L; 
     String type, toPrint; 
     Color color; 
     Point start; 
     Point end; 
     int x1, y1, x2, y2, width, height; 

     public Figure(String figureType, 
      Point startPoint, Point endPoint, Color figureColor) 
     { 
      type = figureType; 
      color = figureColor; 
      start = startPoint; 
      end = endPoint; 
     } 

     // Rect, Oval 
     public Figure(String figureType, int figureX, int figureY, 
      int figureWidth, int figureHeight, Color figureColor) 
     { 
      type = figureType; 
      x1 = figureX; 
      y1 = figureY; 
      width = figureWidth; 
      height = figureHeight; 
      color = figureColor; 
     } 

     // more shapes 
    } 

    public static void main(String args[]) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new JSPaint(); 
      } 
     }); 
    } 
} 
+1

그림 영역을 유지하려면'BufferedImage'를 사용해야하고,'paintComponent'가 호출 될 때'drawImage'를 사용하여 화면에 복사해야합니다. 버퍼가 유효하지 않게되고 페인트 호출 사이에 다른 데이터로 채워지므로 화면을 지우지 않기 위해 페인트를 다시 정의하고 싶지는 않습니다. – yiding

+2

''pack()'을 호출하는 곳을 보여주는 [sscce] (http://sscce.org/)를 포함하도록 질문을 편집하십시오. – trashgod

+1

@yiding * "그림 영역을 유지하려면 BufferedImage를 사용해야합니다."* 이미지가 있으면 레이블에 표시 할 수도 있습니다. –

답변

0

, 이것은 단지 하나의 이유가 있습니다 : 당신이 Graphics 객체에 문제가 있거나, 번역을 호출하거나, 완료되었을 때 변환을 재설정하지 않을 수도 있습니다. (정확히 사용 된 번역 예제는 this 링크를 참조하십시오).

+0

감사! 나는이 프로젝트에서 오랜 휴식을 취했지만 결국은 다시 돌아갈 계획이다. 이 사실을 알면 알려 드리겠습니다. 나는 그것을 조사 할 것이다 ... 감사합니다! – jacky

관련 문제