2013-05-15 57 views
0

我正在製作一個模擬NHL選秀彩票的程序,在屏幕右側應該有一個JTextField,並在左側繪製草圖球,以便反彈。我創建了一個名爲Ball的類來實現Runnable,並在我的主草稿類中作爲Thread運行。但是,當我的draw方法調用repaint()時,JTextArea不顯示。我嘗試切換重繪()重新驗證(),但球然後不移動。然後我嘗試調用repaint()和revalidate(),但它的作用與repaint()相同。 這裏是我的DraftLottery類的代碼:JTextArea不顯示時重繪(),但圖形不更新時,重新驗證()?

package ca.WiltzSports.DraftLottery; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 
import java.util.Random; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 

import ca.WiltzSports.DraftLottery.DraftBall.Ball; 

public class DraftLottery extends JFrame { 
public static final long serialVersionUID = 89L; 

int teams; 
String[] teamNames; 
int[] balls; 
JTextArea display; 
JPanel screen; 
JPanel animation; 
List<String> entries; 
public static List<Ball> ball; 
String [] draftOrder; 
Random rand; 
int counter = 1; 
javax.swing.Timer t; 
public static int width = 1024; 
public static int height = 768; 
Graphics dbg; 
Image dbImage; 
int i = 0; 

public DraftLottery(int teams, String[] teamNames, int[] balls){ 
    t = new javax.swing.Timer(2000, new ActionListener(){ 
     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      draft(); 
     } 

    }); 
    ball = new ArrayList<Ball>(); 
    rand = new Random(); 
    this.teams = teams; 
    this.teamNames = teamNames; 
    this.balls = balls; 
    this.screen = new JPanel(); 
    this.animation = new JPanel(); 
    display = new JTextArea(20,50); 
    display.setBackground(Color.BLACK); 
    display.setForeground(Color.YELLOW); 
    draftOrder = new String[teams]; 
    this.entries = new ArrayList<String>(); 
    addTeamBalls(); 
    setSize(width,height); 
    setVisible(true); 
    setLocationRelativeTo(null); 
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    setTitle("Draft Lottery"); 
    setLayout(new BorderLayout()); 
    screen.add(display); 
    add("East", new JScrollPane(display)); 
    add("West", animation); 
    t.start(); 
} 

@Override 
public void paint(Graphics g){ 
    dbImage = createImage(getWidth(), getHeight()); 
    dbg = dbImage.getGraphics(); 
    Graphics2D g2d = (Graphics2D) dbg; 
    draw(g2d); 
    g.drawImage(dbImage, 0, 0, this); 
    Ball.runBalls(ball); 
} 

public void draw(Graphics2D g2d){ 
    for (Ball b: ball){ 
     b.draw(g2d); 
    } 
    revalidate(); 
    repaint(); 
} 

public void addTeamBalls(){ 
    for (int c = 0; c < teamNames.length; c++){ 
     for (int j = 0; j < balls[c]; j++){ 
      entries.add(teamNames[c]); 
      ball.add(new Ball(rand.nextInt(width/2 - Ball.SIZE), rand.nextInt(height - Ball.SIZE), teamNames[c], i++)); 
     } 
    } 
} 

public void draft(){ 
    int q = 0; 
    String [] e = entries.toArray(new String[entries.size()]); 
    String draftedTeam; 
    int index = rand.nextInt(entries.size()); 
    draftedTeam = e[index]; 
    if(!draftedTeam.equals("X")){ 
     display.append("" + counter++ + ". " + draftedTeam + "\n"); 
     for(int c = 0; c < e.length; c++){ 
      if (e[c].equals(draftedTeam)){ 
       e[c] = "X"; 
      } 
     } 
     removeBalls(); 
    }else { 
     boolean again = false; 
     for (int c = 0; c < e.length; c++){ 
      if (!e[c].equals("X")){ 
       again = true; 
      } 
     } 
     if(again){ 
     }else{ 
      t.stop(); 
      display.append("DRAFT LOTTERY COMPLETE"); 
     } 
    } 
    entries = Arrays.asList(e); 
} 

public void removeBalls(){ 
    Ball [] bs; 
    int q = 0; 
    for (Ball b: ball){ 
     if (b.getTeamName().equals("X")){ 
      continue; 
     }else{ 
      q++; 
     } 
    } 
    bs = new Ball[q]; 
    q = 0; 
    for (Ball b: ball){ 
     if (!b.getTeamName().equals("X")){ 
      bs[q++] = b; 
     } 
    } 
    ball = Arrays.asList(bs); 
} 

}

任何幫助將greaty讚賞。 非常感謝!

+2

'revalidate(); repaint();'應該在'draft()'方法的末尾。至少,他們絕對不應該從'paintComponent'(通過你的'draw()'方法)被調用:這將創建一個無限的繪畫循環 –

回答

3

你有許多問題:

  1. 你覆蓋的頂層容器的paint方法。這通常不被推薦,因爲它不是雙緩衝的,並且可以通過動畫和其他油漆更新產生閃爍。

  2. 您未能撥打super.paintpaint方法負責將所有的底漆方法放在一起,包括paintComponents;但由於你不允許paint做它的工作,它不是爲你渲染這些組件。

相反,

  1. 創建一個自定義組件,從類似JPanel延伸。

  2. 將動畫的所有必需邏輯添加到此組件。

  3. 覆蓋它的paintComponent方法並將所有動畫和自定義繪畫添加到它。

  4. 將其添加到框架。

查看Performing Custom PaintingPainting in AWT and Swing瞭解更多詳情。

+0

非常感謝你的建議,這是這種建議,使這些問題網站去,我真的很感激它! –