4

Java で Canvas に 2 つの線を描画しようとしており、2 つのメソッドを別々に呼び出していますが、2 つ目の線を描画すると、最初の線が消えます (Java が画面をクリアします)。どうすればそれを回避できますか? 2本の線が見たいです。ユーザーがマウスを使用して線を描画し、一方の線が描画されると、もう一方の線が消えないペイント チュートリアル (Windows 上のペイントのようなプログラムの作成方法) を見たことがあります。paint メソッドを呼び出すだけで、画面はクリアされません。

誰かが私を助けることができれば、私は感謝します。ありがとう。

クラスを見る

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JFrame;

public class CircuitTracePlotView extends JFrame {


    private CircuitTracePlot circuitTracePlot;

    public  CircuitTracePlotView() {


        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.getContentPane().add(circuitTracePlot = new CircuitTracePlot(), BorderLayout.CENTER);
        this.pack();
        this.setSize(250,250);
        this.setLocationRelativeTo(null);

        this.setVisible(true);
        circuitTracePlot.drawLine();
        circuitTracePlot.drawOval();
    }


}

class CircuitTracePlot extends Canvas {

    private final static short LINE = 1;
    private final static short OVAL = 2;
    private int paintType;

    private int x1;
    private int y1;
    private int x2;
    private int y2;

    public CircuitTracePlot() {
        this.setSize(250,250);
        this.setBackground(Color.WHITE);

    }

    private void setPaintType(int paintType) {
        this.paintType = paintType;
    }

    private int getPaintType() {
        return this.paintType;
    }

    public void drawLine() {
        this.setPaintType(LINE);
        this.paint(this.getGraphics());
    }

    public void drawOval() {
        this.setPaintType(OVAL);
        this.paint(this.getGraphics());
    }

    public void repaint() {
        this.update(this.getGraphics());
    }

    public void update(Graphics g) {
        this.paint(g);
    }

    public void paint(Graphics g) {
        switch (paintType) {
        case LINE:
            this.getGraphics().drawLine(10, 10, 30, 30);            
        case OVAL:
            this.getGraphics().drawLine(10, 20, 30, 30);
        }


    }


}

メインクラス

import javax.swing.SwingUtilities;

import view.CircuitTracePlotView;

public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                CircuitTracePlotView cr = new CircuitTracePlotView();
            }
        });
    }
}
4

2 に答える 2

4
  • paint(...)直接電話することはほとんどありません。これを行うのに必要な回数は、片手で数えることができます。
  • コンポーネントを呼び出して Graphics オブジェクトを取得しないでくださいgetGraphics()。非永続的な Graphics オブジェクトが返されるためです。代わりに、BufferedImage を描画してそれを paint メソッドで表示するか、paint メソッドで描画します (AWT の場合)。
  • これは Swing GUI であるため、AWT コンポーネントを使用して描画しないでください。JPanel を使用して、paintComponent(...)メソッドではなくメソッドをオーバーライドしますpaint(...)。そうしないと、自動ダブルバッファリングを含む Swing グラフィックスの利点がすべて失われます。
  • super.paintComponent(g)メソッドは、多くの場合、このメソッド内の最初のメソッド呼び出しとして、オーバーライドで呼び出す必要がありますpaintComponent(Graphics g)。これにより、コンポーネントは、消去する必要がある描画を消去するなど、独自のハウスキーピング ペイントを行うことができます。
  • Swing グラフィックスのチュートリアルを読んでください。これらのほとんどはそこで十分に説明されています。たとえば、こちらをご覧ください。

編集

  • 画像を保持するには、BufferedImage に描画してから、JPanel のpaintComponent(...)メソッドでその画像を表示することをお勧めします。
  • または、別のオプションとして、Shape オブジェクトの Collection を作成し、ArrayList<Shape>描画したい Shape で埋めてから、paintComponent(...)メソッドで Graphics オブジェクトを Graphics2D オブジェクトにキャストし、Shape コレクションを反復処理して、各形状を描画します。g2d.draw(shape)繰り返します。

Trash がコードを投稿してから...

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class CircuitTracePlot2 extends JPanel {

   private static final int PREF_W = 250;
   private static final int PREF_H = PREF_W;

   private int drawWidth = 160;
   private int drawHeight = drawWidth;
   private int drawX = 10;
   private int drawY = 10;
   private PaintType paintType = PaintType.LINE;

   public CircuitTracePlot2() {

   }

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

   public void setPaintType(PaintType paintType) {
      this.paintType = paintType;
      repaint();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (paintType == null) {
         return;
      }
      switch (paintType) {
      case LINE:
         g.drawLine(drawX, drawY, drawWidth, drawHeight);
         break;
      case OVAL:
         g.drawOval(drawX, drawY, drawWidth, drawHeight);
         break;
      case SQUARE:
         g.drawRect(drawX, drawY, drawWidth, drawHeight);

      default:
         break;
      }
   }

   private static void createAndShowGui() {
      final CircuitTracePlot2 circuitTracePlot = new CircuitTracePlot2();

      JFrame frame = new JFrame("CircuitTracePlot2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(circuitTracePlot);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);

      int timerDelay = 2 * 1000;
      new Timer(timerDelay , new ActionListener() {
         private int paintTypeIndex = 0;

         @Override
         public void actionPerformed(ActionEvent arg0) {
            paintTypeIndex++;
            paintTypeIndex %= PaintType.values().length;
            circuitTracePlot.setPaintType(PaintType.values()[paintTypeIndex]);
         }
      }).start();
   }

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

enum PaintType {
   LINE, OVAL, SQUARE;
}
于 2013-04-06T17:39:43.320 に答える
2

これは、@Hovercraft の役立つアドバイスの多くを実装したプログラムのバリエーションです。への呼び出しをコメントアウトしてsetPaintType()、効果を確認してください。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

/** @see http://stackoverflow.com/a/15854246/230513 */
public class Main {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                CircuitTracePlotView cr = new CircuitTracePlotView();
            }
        });
    }

    private static class CircuitTracePlotView extends JFrame {

        private CircuitTracePlot plot = new CircuitTracePlot();

        public CircuitTracePlotView() {
            this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            plot.setPaintType(CircuitTracePlot.OVAL);
            this.add(plot, BorderLayout.CENTER);
            this.pack();
            this.setLocationRelativeTo(null);
            this.setVisible(true);
        }
    }

    private static class CircuitTracePlot extends JPanel {

        public final static short LINE = 1;
        public final static short OVAL = 2;
        private int paintType;

        public CircuitTracePlot() {
            this.setBackground(Color.WHITE);
        }

        public void setPaintType(int paintType) {
            this.paintType = paintType;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            switch (paintType) {
                case LINE:
                    g.drawLine(10, 10, 30, 30);
                case OVAL:
                    g.drawOval(10, 20, 30, 30);
                default:
                    g.drawString("Huh?", 5, 16);
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(250, 250);
        }
    }
}
于 2013-04-06T18:01:58.427 に答える