これは、フレームの左側に所定の数のアイコンが始まり、画面を横切って右側に移動するアニメーションです。各アイコンは、コンテナの単一列のGridLayout内の行を塗りつぶす独自のJPanelに描画され、各JPanelは独自のスレッドでレースします。JPanelに線が描画されていない
フィニッシュラインはコンテナにペイントされているはずですが、表示されません。これは、スイングタイマーの方が良い方法です。私はRacerのJPanel不透明度をfalseに設定しようとしましたが、これはうまくいきません。フィニッシュラインのペイントを実行するには、どうすれば他のスレッドを得ることができますか?
動作していないコード:
gui = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(finishLineXPos, 0, finishLineXPos, windowHeight);
}
};
フルコード:各アイコンは、独自のJPanelに引き出され
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class Races2 {
private JFrame frame;
private JPanel gui; // to hold all components
private int finishLineXPos; // x-coordinate of finish line
private Icon racerImg;
private int racerImgWidth;
private int racerImgHeight;
private int numOfRacers;
private ArrayList<Racer> racers;
private Racer winner;
private int windowHeight;
private int windowWidth;
public Races(int num) {
numOfRacers = num;
racerImg = new ImageIcon("races.png");
racerImgWidth = racerImg.getIconWidth();
racerImgHeight = racerImg.getIconHeight();
windowHeight = racerImgHeight * numOfRacers;
windowWidth = racerImgWidth * 20;
finishLineXPos = racerImgWidth * 18; // two icon widths from the right
frame = new JFrame("Off to the Races - by Brienna Herold");
frame.setResizable(false); // prevents window resizing which affects painting
gui = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(finishLineXPos, 0, finishLineXPos, windowHeight);
}
};
gui.setLayout(new GridLayout(numOfRacers,1));
gui.setPreferredSize(new Dimension(windowWidth, windowHeight));
// Create and add racers to gui panel
racers = new ArrayList<Racer>();
for (int i = 0; i < numOfRacers; i++) {
Racer racer = new Racer();
gui.add(racer);
racers.add(racer);
}
// Start racers
for (Racer racer : racers) {
Thread racerThread = new Thread(racer);
racerThread.start();
}
frame.add(gui);
frame.pack();
frame.setVisible(true);
}
protected class Racer extends JPanel implements Runnable {
private int lastPosX;
private int posX;
public Racer() {
posX = 0;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
racerImg.paintIcon(this, g, posX, 0);
posX += Math.random() * 20;
}
@Override
public void run() {
// While the race has not been won yet, proceed with race
while (winner == null) {
repaint();
try {
Thread.sleep(100); // slows down racing a bit
} catch (InterruptedException ex) {
ex.printStackTrace();
}
// If racer passes specified x-coordinate, set it as winner
if (posX >= finishLineXPos) {
System.out.println("Winner: " + this.getName());
winner = this;
}
}
}
}
}
RacerクラスはJPanelまたはSwingコンポーネントクラスではなく、その位置を知っている論理クラスである必要があります。論理クラスは、描画または描画メソッドを呼び出して描画することもできます。これらのRacerオブジェクトのメインのグラフィックスJPanelインスタンスを与え、メインのJPanelに描画させます。スレッドの束ではなく、単一のSwing Timerでアニメーションを動かす。 –
gui JPanelのグラフィックは、追加している他のコンポーネントによって隠されていることに注意してください。だからあなたはそれが何かを描くのを見ていないのです。 –
@DontKnowMuchButGettingBetter、各Racerの背景が透明であれば、guiのラインはまだ表示されないはずですか? – briennakh