2016-10-06 5 views
1

그래서 내가 여기에 두 개의 클래스가 표시되지 않습니다.그리기 펜 자바 스윙을 사용하여 스트로크 ... 스트로크

(이 클래스는 JComponent의 같은 특정 이미지를 처리하는 것입니다 때 내가 이미지를하는 대신 펜 스트로크를 그리려는 "튀 겼다."그래서 그 위에 펜 스트로크를 그릴 시도, 사각형과 이미지를 교체합니다.)

public class PhotoComponent extends JComponent { 

private Image pic; 
private boolean flipped; 

private int contentAreaWidth; 
private int contentAreaHeight; 
p 
@Override 
public void paintComponent(Graphics g) { 
    //Does all the drawing and contains whatever state information is associated with the photo 
    //create an action event to auto call repaint 
    //call repaint anytime flip was changed to true or false 

    System.out.println("Draw: " + draw + ", Pic: " + pic); 
    if (draw && pic != null) { 
     super.paintComponent(g); 

     System.out.println("width using this: " + this.getWidth() + ", actual width of JPanel: " + contentAreaWidth); 
     System.out.println("height using this: " + this.getHeight() + ", actual height of JPanel: " + contentAreaHeight); 

     g2 = (Graphics2D) g; 
     int x = (contentAreaWidth - pic.getWidth(null))/2; 
     int y = (contentAreaHeight - pic.getHeight(null))/2; 
     if (!flipped) { 
      g2.drawImage(pic, x, y, null); 

     } else if (flipped) { 
      g2.setColor(Color.WHITE); 
      g2.fillRect(x,y,pic.getWidth(null), pic.getHeight(null)); 
      g2.drawRect(x, y, pic.getWidth(null), pic.getHeight(null)); 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      if (drawingMode) { 
       g2.setPaint(Color.RED); 
       if (drawOval) { 
        penStrokes.put(ovalX, ovalY); 
        if (penStrokes != null) { 
         for (Integer xCoor : penStrokes.keySet()) { 
          g2.setPaint(Color.RED); 
          int brushSize = 5; 
          g2.fillOval((xCoor - (brushSize/2)), (penStrokes.get(xCoor) - (brushSize/2)), brushSize, brushSize); 
          //System.out.println("SIZE OF HASHTABLE: " + penStrokes.size()); 
         } 
        } 
        System.out.println("Filling an oval!" + ovalX + ", " + ovalY); 
       } 
      } else if (textMode) { 
       g2.setPaint(Color.YELLOW); 
       if (drawRect) { 
        rectDimensions.add(rectX); 
        rectDimensions.add(rectY); 
        rectDimensions.add(rectWidth); 
        rectDimensions.add(rectHeight); 

        for (int i = 0; i < rectDimensions.size(); i+=4) { 
         g2.fillRect(rectDimensions.get(i), rectDimensions.get(i+1), rectDimensions.get(i+2), rectDimensions.get(i+3)); 
         g2.drawRect(rectDimensions.get(i), rectDimensions.get(i+1), rectDimensions.get(i+2), rectDimensions.get(i+3)); 
        } 
       } 
      } 

      System.out.println("This is being called again!"); 
     } 

    } 

} 
public void setRectangle(int x, int y, int width, int height) { 
    drawRect = true; 
    rectX = x; 
    rectY = y; 
    rectWidth = width; 
    rectHeight = height; 
} 

public void removeRectangle() { 
    drawRect = false; 
} 

public int[] setOval(int currentX, int currentY) { 
    drawOval = true; 
    int[] toReturn = {ovalX, ovalY}; 
    ovalX = 

주를 DRAWLINE() 메소드 위. 주어진 시점에서 그리기, 다시 그리기, 그리고 이전 변수를 현재 변수로 설정하고 있습니다.

Main 클래스하십시오 mousedrag가 발생했을 때

private static PhotoComponent img; 
private static JFrame frame; 

private static JPanel contentArea; 

//Mouse Coordinates for PenStrokes 
private static int oldX, oldY; 

//Mouse Coordinates for Sticky Notes 
private static Point clickPoint; 

public static void main (String[] args) { 
    frame = new JFrame("PhotoManip"); 
    img = null; 
    contentArea = null; 
    oldX = 0; 
    oldY = 0; 
    setupMenubar(frame); 
    setupJFrame(frame); 
} 

private static void addPhotoComponent(File file) { 

      } 
      if (img.getTextMode()) { 
       img.removeRectangle(); 
       clickPoint = null; 
      } 

     } 
    }); 

    img.addMouseMotionListener(new MouseAdapter() { 
     @Override 
     public void mouseDragged(MouseEvent e) { 
      if (img.getDrawingMode()) { 
       if (withinRange(e.getX(), e.getY())) { 
        int[] toUpdate = img.setOval(e.getX(), e.getY()); 
        oldX = toUpdate[0]; 
        oldY = toUpdate[1]; 
        img.repaint(); 
       } 
      } 
      if (img.getTextMode()) { 
       if (withinRange(e.getX(), e.getY())) { 
        Point dragPoint = e.getPoint(); 
       h, height); 
        img.repaint(); 
       } 
      } 

     } 
    }); 

    if (img!=null) { 
     contentArea.add(img); 
    } 
} 

private static boolean withinRange(int x, int y) { 
    if (x > img.getX() && x < img.getX() + img.getWidth()) { 
     if (y > img.getY() && y < img.getY() + img.getHeight()) { 
      return true; 
     } 
    } 
    return false; 
} 

private static void flipImage() { 
    if (!img.isFlipped()) { 
     img.setFlipped(true); 
    } else if (img.isFlipped()) { 
     img.setFlipped(false); 
    } 
} 

drawLine()는,이 메인 클래스에 위라고합니다. 문제는 스트로크가 표시되지 않는 것입니다.

나중에 확인 문을 인쇄하기 때문에 프로그램에서 g2.fillOval()을 호출한다는 것을 알고 있습니다.

또한 마우스를 누르고 드래그하여 올바른 좌표를 얻었을 때 print 문을 만들었습니까?

왜 빨간색 선이 표시되지 않습니까? 나는 혼란스러워. 내 코드가 구조화 된 방식입니까?

+1

을가 공동 ords 변수의 일종으로 선을 저장할 수있다 그것을 'paintComponent' 내에서 참조하십시오. 그래픽 객체를 저장하려고하지 말고'paintComponent' 밖에서 그릴 수 있습니다. 'paintComponent'가 다시 호출되면 곧바로 덮어 쓰게 될 것입니다. – nhouser9

+0

문제에 대한 추가 컨텍스트를 추가했습니다. 따라서 paintComponent() 메서드 내에서 페인트 된 선을 모두 움직여야한다고 말하고 있습니까? – dan139

+0

아래 답변을 게시했습니다. 전체 코드가 없기 때문에 실제로 컴파일하고 실행할 수는 없지만 제대로 작동해야한다고 생각합니다. 그렇지 않은 경우 알려 주시면 변경을 위해 변경해야 할 사항을 파악하는 데 도움을 드리겠습니다. – nhouser9

답변

2

문제의 핵심은 지원되지 않는 paintComponent 메서드 외부에 무언가를 그려는 것입니다. 무엇을 그리든간에 paintComponent의 다음 호출로 덮어 쓰게되며 거의 즉시 발생합니다. 우리는 타원의 좌표를 저장하고 paintComponent 메서드 외부의 그래픽 객체를 그리는 대신 paintComponent 내에 그려서 해결할 수 있습니다. 우리가 변경할 수 있습니다 그 후

public int[] setOval(int currentX, int currentY) { 
    drawOval = true; 
    int[] toReturn = {ovalX, ovalY}; 
    ovalX = currentX; 
    ovalY = currentY; 
    return toReturn; 
} 

public void removeOval() { 
    drawOval = false; 
} 

을 :

private boolean drawOval = false; 
private int ovalX = 0; 
private int ovalY = 0; 

그런 다음 우리가 그들을 제어하기위한 방법을 추가합니다 :

먼저 우리는 당신의 PhotoComponent 클래스에 다음 변수를 추가하려고 : 코드는 아래를 참조하십시오 paintComponent 이러한 변수를 기반으로 타원형을 그리는 방법은 다음과 같습니다.

@Override 
public void paintComponent(Graphics g) { 
    //Does all the drawing and contains whatever state information is associated with the photo 
    //create an action event to auto call repaint 
    //call repaint anytime flip was changed to true or false 
    super.paintComponent(g); 
    g2 = (Graphics2D) g; 
    int x = (contentAreaWidth - pic.getWidth(null))/2; 
    int y = (contentAreaHeight - pic.getHeight(null))/2; 
    if (!flipped) { 
     g2.drawImage(pic, x, y, null); 

    } else if (flipped) { 
     g2.setColor(Color.WHITE); 
     g2.fillRect(x, y, pic.getWidth(null), pic.getHeight(null)); 
     g2.drawRect(x, y, pic.getWidth(null), pic.getHeight(null)); 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setPaint(Color.RED); 
    } 

    //took the code you already used for drawing the oval and moved it here 
    if (drawOval) { 
     g2.setPaint(Color.RED); 
     int brushSize = 5; 
     g2.fillOval((ovalX - (brushSize/2)), (ovalY - (brushSize/2)), brushSize, brushSize); 
    } 
} 

마지막으로 대신 직접 타원형 그릴 노력하는 그 변수를 업데이트 할 수있는 addPhotoComponent 방법 변경 : 당신이 할 수있는 방법으로 선을 그리려면

private static void addPhotoComponent(File file) { 
    Image image = null; 
    try { 
     image = ImageIO.read(file); 
    } catch (IOException e2) { 
     System.out.println("ERROR: Couldn't get image."); 
    } 

    img = new PhotoComponent(image, contentArea); 
    img.revalidate(); 

    img.addMouseListener(new MouseAdapter() { 
     @Override 
     public void mouseClicked(MouseEvent e) { 
      if (e.getClickCount() == 2) { 
       // your code here 
       System.out.println("You flipped the photo!!!"); 
       flipImage(); 
       img.repaint(); 
      } 
     } 

     @Override 
     public void mousePressed(MouseEvent e) { 
      img.setOval(e.getX(), e.getY()); 
     } 
     @Override 
     public void mouseReleased(MouseEvent e) { 
      img.removeOval(); 
     } 
    }); 

    img.addMouseMotionListener(new MouseAdapter() { 
     @Override 
     public void mouseDragged(MouseEvent e) { 
      int[] toUpdate = img.setOval(e.getX(), e.getY()); 
      oldX = toUpdate[0]; 
      oldY = toUpdate[1]; 
     } 
    }); 

    if (img != null) { 
     contentArea.add(img); 
    } 
} 
+0

답변 해 주셔서 감사합니다. 이 작품은 ...그러나 그것은 단지 빨간 점을 그립니다. 드래그 할 때 붉은 타원을 움직입니다. 실제로 좌표가 바뀔 때마다 새로운 타원형을 그리지 않습니다. 빨간색 점과 반대되는 실제 획이 될 수있는 방법이 있습니까? – dan139

+0

@ dan139 확실히, 우리가 여기에서했던 것과 비슷한 것을해야 할 것입니다. 단순히 그리기를 원하는 좌표를 저장하고,'paintComponent' 메쏘드에서 무언가를 그리는 좌표를 참조하십시오. 이 코드가 도움이된다면, 코드를 편집하는 데 꽤 많은 시간을 할애했다. – nhouser9

+0

누구든지이 것을 downvoted : 나는 그것이 제대로 작동하는지 확인하기 위해 코드를 편집하는 데 20 분을 보냈다. 당신이 할 수있는 최소한의 행동은 5 초를 남겨두고 이것이 왜 나쁜 대답이라고 생각하는지에 대한 의견을 남기십시오. – nhouser9