我正在研究這個小型賽馬模擬器,並堅持下去。我希望用戶首先選擇比賽中的馬匹數量(2-6)並點擊「開始」按鈕。然後,我想繪製/繪製賽馬和馬匹(用圓圈表示)。出於某種原因,當代碼達到創建一個馬的實例的時候,它永遠不會被拖入框架。 以下是代碼。我錯過了什麼?繪製一個可運行的JPanel
Main.java:
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
RaceTrack myRace = new RaceTrack();
myRace.setVisible(true);
}
});
}
}
RaceTrack.java:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.Border;
public class RaceTrack extends JFrame implements Runnable {
public RaceTrack() {
initUI();
}
public static int selectedRaceSize = 2;
private void initUI() {
final Container pane = getContentPane();
String horseNum[] = { "2", "3", "4", "5", "6" };
JPanel buttonPanel = new JPanel();
Border border = BorderFactory.createTitledBorder("Please select number of horses:");
buttonPanel.setBorder(border);
ButtonGroup buttonGroup = new ButtonGroup();
JRadioButton aRadioButton;
// For each String passed in:
// Create button, add to panel, and add to group
for (int i = 0, n = horseNum.length; i < n; i++) {
if (i == 0) {
// Default selection
aRadioButton = new JRadioButton(horseNum[i], true);
} else {
aRadioButton = new JRadioButton(horseNum[i]);
}
buttonPanel.add(aRadioButton);
buttonGroup.add(aRadioButton);
}
pane.add(buttonPanel, BorderLayout.PAGE_START);
final JPanel raceTrackPanel = new JPanel(null);
final JButton startButton = new JButton("Start!");
startButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
startButton.setEnabled(false);
Horse horse1 = new Horse("horse1");
raceTrackPanel.add(horse1);
pane.add(raceTrackPanel, BorderLayout.CENTER);
repaint();
}
});
pane.add(startButton, BorderLayout.PAGE_END);
startButton.setBounds(50, 200, 300, 30);
setTitle("Horse Race v1.0");
setSize(400, 300);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
@Override
public void run() {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
repaint();
}
}
Horse.java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class Horse extends JPanel implements Runnable {
Thread runner;
public Horse() {
}
public Horse(String threadName) {
runner = new Thread(this, threadName);
runner.start();
}
public void run() {
this.repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(new Color(252, 211, 61));
g2d.drawOval(20, 25, 10, 10);
g2d.fillOval(20, 25, 10, 10);
}
}
我改寫了我的根據你的建議完整的代碼。我從來沒有學過數據模型和視圖,所以我仍然試圖理解這裏發生了什麼。其中一個問題是:Race類也可以作爲我的框架嗎?如果不是,我應該爲它使用不同的類還是隻在我的Main類中創建它? – coyote1982
@ coyote1982:你的JFrame存在可以容納TrackPanel,也可能是一個菜單。您的JFrame是視圖的一部分。種族是模型的一部分。您需要編寫控制器類來將模型和視圖連接在一起(一個或多個線程)。我看到了你的代碼中的線程,所以我想你可以做到這一點。看看這篇文章,看看如何把一個Swing GUI放在一起。 http://java-articles.info/articles/?p=196 –
感謝你的精彩指南,在過去的幾天裏,我取得了很多進展。我的程序即將完成。我仍然必須編寫比賽結果對話框,但在開始之前,我遇到了一個問題:我無法弄清楚真正讓馬匹移動的正確方法。每匹馬都有自己的HorseRunnable模擬其隨機進展。我還創建了RaceRunnable,每隔50毫秒重新繪製一次TrackPanel(通過睡眠,然後重繪)。我可以向您發送該程序,以便我可以更好地解釋嗎? – coyote1982