簡體   English   中英

Java新手無法弄清楚如何使用繪畫方法

[英]New to java can't figure out how to use paint method

我正在嘗試學習繪畫方法,並使球在框架上移動。 到目前為止,這是我的代碼。 w =。

我目前有兩個班級,一個是主班,一個是球班。

這是導入java.awt的主要類。 ; 導入javax.swing。 ;

public class PaintTest extends JPanel {
int x = 0;
int y = 0;

public void moveBall(){
    x = x + 1;
    y = y + 1;
}
public static void main(String[] args){
    JFrame frame = new JFrame();
    frame.setSize(500,500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    Ball ball = new Ball(x,y);

    while(true){
        ball.moveBall();
        repaint();
    }
    }
protected void paintComponent(Graphics g){
    super.paintComponent(g);

    Graphics2D g2 = (Graphics2D) g;

    g.setColor(Color.magenta);
    g.drawLine(0,100,500,100);
    g.drawLine(0,101,500,101);
    g.drawLine(0,102,500,102);
    g.drawLine(0,103,500,103);

    g2.fillOval(x,y,35,35);
}
}

這是球課

 public class Ball {

   int x,y;

   public Ball(int x, int y){
this.x = x;
this.y = y;
}
}

現在,當我進行編譯時,出現錯誤消息,即使我從Ball類調用它也無法在PaintTest類中找到符號ball。 我知道重畫錯誤,因為我不知道在它前面放什么。

  1. 在JPanel中繪制
  2. 在其paintComponent方法中而不是在其paint方法中—這為您提供了雙重緩沖。
  3. 在您的覆蓋中調用上級的paintComponent方法。 這使JPanel可以做家政繪圖,包括在其舊位置刪除橢圓形圖像。
  4. 不要使用while (true)循環,因為這可能會導致嚴重的Swing線程問題。 請改用Swing計時器。
  5. 在Swing計時器中,增加動畫變量,然后調用repaint() 這將告訴Swing重新繪制組件,這將在新位置重新繪制橢圓形。
  6. 不要猜這些東西,因為Swing圖形編碼是另一種野獸,這會導致沮喪。 而是查看教程。 您可以在此處找到Swing教程和其他Swing資源的鏈接: Swing信息 另請參閱使用Swing執行自定義繪畫
  7. Graphics2D好東西:RenderingHints可用於消除圖像鋸齒。
  8. 更多Graphics2D好東西:可以在需要時使用筆觸繪制粗線。

例如:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

@SuppressWarnings("serial")
public class PaintTest extends JPanel {
   private static final int PREF_W = 600;
   private static final int PREF_H = PREF_W;
   private static final int TIMER_DELAY = 20;
   private static final Stroke STROKE = new BasicStroke(5f);
   private int x;
   private int y;

   public PaintTest() {
      new Timer(TIMER_DELAY, new TimerListener()).start();
   }

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

      // to smooth graphics
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

      g2.setColor(Color.magenta);
      Stroke initialStroke = g2.getStroke();
      g2.setStroke(STROKE);
      g.drawLine(0, 100, 500, 100);
      g2.setStroke(initialStroke);

      g2.fillOval(x, y, 35, 35);
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private class TimerListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent e) {
         x++;
         y++;
         repaint();
      }
   }

   private static void createAndShowGui() {
      PaintTest mainPanel = new PaintTest();

      JFrame frame = new JFrame("PaintTest");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

您必須將paintComponent方法放入JPanel中。 您可以使用類似的方法來做到這一點。

JPanel panel = new JPanel(){

    @Overide
    public void paintComponent(Graphics g){
        super.paint();
        // Draw Stuff Here

    }

};

您沒有使球在框架上移動的原因是您沒有調用repaint方法。 您應該在線程上執行此操作。

Thread th = new Thread(new Runnable(){
    @Overide
    public void run(){
        while(frame.isVisible()){
            ball.moveBall();     
            panel.repaint();
            try{Thread.sleep(5);}catch(Exception e){e.printStackTrace();}
        }
    }
});

另外,為什么要使ball成為PaintTest類的實例? 要只獲得一個框架和球,您需要添加一個名為Ball的類,並使用該類創建一個實例:

public class Ball{

    int x, y;

    public Ball(int x, int y){
        this.x = x;
        this.y = y;
    }
} 

這就是為什么要獲得2幀的原因。

然后,您將希望擺脫主類中的x和y變量。 要使用此類創建實例,您可以執行以下操作:

Ball ball = new Ball(x, y);

然后在paintComponent方法中繪制球:

g.fillOval(ball.x, ball.y, 35, 35);
  • 您沒有調用repaint(); 方法。
  • 您不需要y + 1部分。
  • 不要使用while(true)循環,而應該使用for循環。
  • 您沒有調用super.paint()方法。
  • 您沒有使用任何Thread.sleep() ,它使球瞬間移動。

這是代碼:

import java.awt.*;
import javax.swing.*;

public class PaintTest extends JFrame {
int x = 8;
int y = 30;

public void moveBall(){
x = x + 1;
//y = y + 1;
try{
    Thread.sleep(500);
} catch(InterruptedException e){

}
repaint();
}
public static void main(String[] args){
PaintTest frame1 = new PaintTest();
PaintTest ball = new PaintTest();

for(int i = 0; i<100; i++){
//while(true){
    ball.moveBall();
}
}

public PaintTest() {
super("Paint Test");
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


setVisible(true);
}

public void paint(Graphics g){

Graphics2D g2 = (Graphics2D) g;
super.paint(g);
super.paint(g2);
g.setColor(Color.magenta);
g.drawLine(0,100,500,100);
g.drawLine(0,101,500,101);
g.drawLine(0,102,500,102);
g.drawLine(0,103,500,103);

g.fillOval(x,y,35,35);
}
}

此代碼將使球非常緩慢地在屏幕上移動。 如果要加快速度,請將Thread.sleep(miliseconds)部分中的毫秒數更改為較小的毫秒數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM