2016-10-06 9 views
1

まで表示されませんので、私はここで二つのクラスがあります。ドローイングペンはJavaのスイングを使用してストローク...ストロークは

PhotoComponentクラス:

を(このクラスは、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 = 

NOTEをDRAWLINE()メソッドABOVE。私は与えられた点を描画し、再描画し、古い変数を現在の変数に設定しています。

メインクラス: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

問題にもう少しコンテキストを追加しました。つまり、paintChart()メソッド内で描画されたストロークをすべて移動する必要があると言っていますか? – dan139

+0

私は以下のように回答を掲載しました。私はあなたの完全なコードを持っていないので、私は実際にコンパイルして実行することはできませんが、うまくいくはずです。そうでない場合は私に知らせてください。私はあなたにそれを働かせるために何を変えるべきかを理解する手助けをします。 – nhouser9

答えて

2

問題の要点は、決してサポートされていないpaintComponentメソッドの外に何かを描画しようとしていることです。何を描画しても、次のコールpaintComponentによって上書きされます。これはほぼ即座に発生します。これを解決するには、paintComponentメソッドの外のグラフィックスオブジェクトを描画するのではなく、楕円の座標を格納してpaintComponentに描画します。私たちはあなたのPhotoComponentクラスに次の変数を追加しようとしている

まず:

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

その後、我々はそれらを制御するためのメソッドを追加します:

我々は変更することができます。その後
public int[] setOval(int currentX, int currentY) { 
    drawOval = true; 
    int[] toReturn = {ovalX, ovalY}; 
    ovalX = currentX; 
    ovalY = currentY; 
    return toReturn; 
} 

public void removeOval() { 
    drawOval = false; 
} 

以下のコードを参照してください。 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'メソッドでこれらの座標を参照して何かを描画します。 upvoteを覚えておいてください。これが助けになったら、コードを編集するのにかなり時間を費やしました。 – nhouser9

+0

誰にでもこれを落とした人に:20分かけてコードを編集して、正しく機能することを確認しました。少なくともあなたができることは、これが悪い答えだと思った理由についてのコメントを残すのに5秒かかります。 – nhouser9

関連する問題