[英]How do I repaint a component by using a JButton in Java?
我正在嘗試用Java編寫一個簡單的GUI骰子游戲,稱為HighLow。 基本上,用戶的初始余額為50英鎊,他們可以選擇三種不同的下注金額,如果選擇“低”,那么骰子必須落在2、3、4、5或6上,並支付1:1,如果他們選擇“高”,骰子必須落在8、9、10、11或12上並支付1:1。 如果他們選擇七號骰子,那么骰子必須落在七號上並支付4:1的賠率。 有兩個骰子,因此應將兩個的值相加。 這不是我的問題的重點,只是以為我會澄清這一點,以便您了解游戲的重點。
我完全不熟悉面板,事件處理以及類似的內容,因此我目前正在學習中,但是在解決該問題時遇到了一些困難。 我有五個類:Dice.java由getFaceValue()和throwDie()方法組成,用於模擬骰子的隨機拋出。 DiceFace.java創建帶有點/點的骰子。 DiceFaceViewer.java是框架類。 DiceFaceComponent是兩個骰子的組件,而GamePanel是所有JButton和JComboBox等所在的面板。
到目前為止,這就是我要做的事情:創建一個框架,將面板上的按鈕等固定在其中,然后將骰子圖像添加到該框架中。 我想要的是每當我單擊“擲骰子”按鈕時,將骰子以隨機的面孔重塗到框架上。 如果我打開和關閉窗口,它現在正在做的只是生成一張隨機的面孔。
骰子
import java.util.Random;
public class Dice {
// Instance variables
private int faceValue;
private int sides;
private Random generator;
public Dice(int s) {
generator = new Random();
sides = s;
faceValue = generator.nextInt(sides) + 1;
}
// Simulates the throw of a die landing on a random face.
public int throwDie() {
return faceValue = (int)(Math.random() * sides) + 1;
}
// Returns the current face value of the die
public int getFaceValue() {
return faceValue;
}
// Set face value of die
public void setValue(int v) {
faceValue = v;
}
}
骰子臉
import java.awt.*;
import java.awt.geom.*;
public class DiceFace {
// Holds the seven possible dot positions on a standard die
private Ellipse2D.Double[] dots = new Ellipse2D.Double[7];
private Rectangle box;
private int xLeft;
private int yTop;
private int side;
private int diceValue;
public DiceFace(int s, int x, int y, int v) {
side = s; // Dimension of dice face
xLeft = x; // xPos
yTop = y; // yPos
diceValue = v; // Pip value
}
public void draw(Graphics2D g2) {
box = new Rectangle(xLeft, yTop, side, side);
makeDots();
// Black background
g2.setColor(Color.BLACK);
g2.fill(box);
// White dots on black
g2.setColor(Color.WHITE);
// Draw dots
if (diceValue == 1)
g2.fill(dots[0]);
else if (diceValue == 2) {
g2.fill(dots[1]); g2.fill(dots[2]);
}
else if (diceValue == 3) {
g2.fill(dots[0]); g2.fill(dots[1]); g2.fill(dots[2]);
}
else if (diceValue == 4) {
g2.fill(dots[1]); g2.fill(dots[2]);
g2.fill(dots[3]); g2.fill(dots[4]);
}
else if (diceValue == 5) {
g2.fill(dots[0]); g2.fill(dots[1]);
g2.fill(dots[2]); g2.fill(dots[3]); g2.fill(dots[4]);
}
else if (diceValue == 6) {
g2.fill(dots[1]); g2.fill(dots[2]); g2.fill(dots[3]);
g2.fill(dots[4]); g2.fill(dots[5]); g2.fill(dots[6]);
}
}
public void makeDots() {
int w = side/6; // Dot width
int h = side/6; // Dot height
dots[0] = new Ellipse2D.Double(xLeft + (2.5 * side)/6,
yTop + (2.5 * side)/6, h, w);
dots[1] = new Ellipse2D.Double(xLeft + (3.75 * side)/6,
yTop + (3.75 * side)/6, h, w);
dots[2] = new Ellipse2D.Double(xLeft + (1.25 * side)/6,
yTop + (1.25 * side)/6, h, w);
dots[3] = new Ellipse2D.Double(xLeft + (1.25 * side)/6,
yTop + (3.75 * side)/6, h, w);
dots[4] = new Ellipse2D.Double(xLeft + (3.75 * side)/6,
yTop + (1.25 * side)/6, h, w);
dots[5] = new Ellipse2D.Double(xLeft + (1.25 * side)/6,
yTop + (2.5 * side)/6, h, w);
dots[6] = new Ellipse2D.Double(xLeft + (3.75 * side)/6,
yTop + (2.5 * side)/6, h, w);
}
}
DiceFaceViewer
import java.awt.*;
import javax.swing.*;
public class DiceFaceViewer {
public static void main(String[] args) {
// Create frame
JFrame frame = new JFrame();
// Set frame attributes
frame.getContentPane().setPreferredSize(new Dimension(360, 320));
frame.pack();
frame.setTitle("High Low");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
// Set location of frame to centre screen
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int w = frame.getSize().width;
int h = frame.getSize().height;
int x = (dim.width-w)/2;
int y = (dim.height-h)/2;
frame.setLocation(x, y);
DiceFaceComponent component = new DiceFaceComponent();
frame.add(component);
// Add panel to frame
GamePanel panel = new GamePanel();
frame.add(panel, BorderLayout.NORTH);
frame.setVisible(true);
}
}
DiceFaceComponent
import java.awt.*;
import javax.swing.*;
public class DiceFaceComponent extends JComponent {
// Instance variables
private int faceValue1;
private int faceValue2;
public DiceFaceComponent() {
faceValue1 = new Dice(6).getFaceValue();
faceValue2 = new Dice(6).getFaceValue();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Recover Graphics2D
Graphics2D g2 = (Graphics2D) g;
DiceFace dice1 = new DiceFace(75, 66, 160, faceValue1); // s, x, y, v
dice1.draw(g2);
repaint();
DiceFace dice2 = new DiceFace(75, 219, 160, faceValue2);
dice2.draw(g2);
repaint();
}
}
游戲面板
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GamePanel extends JPanel {
private int balance = 50;
public GamePanel() {
// Components
JRadioButton highButton = new JRadioButton("High");
JRadioButton lowButton = new JRadioButton("Low");
JRadioButton sevensButton = new JRadioButton("Sevens");
// Button group
ButtonGroup bg = new ButtonGroup();
bg.add(highButton);
bg.add(lowButton);
bg.add(sevensButton);
add(highButton);
add(lowButton);
add(sevensButton);
// Array to hold bet amounts
String betAmounts[] = {"£10", "£5", "£1"};
// Bets combo box
JComboBox bets = new JComboBox(betAmounts);
add(bets);
// Balance
JLabel bal = new JLabel(" Balance: £" + balance);
add(bal);
// Throw dice button
final JButton throwButton = new JButton("Throw Dice");
add(throwButton, FlowLayout.RIGHT);
class Action implements ActionListener {
Dice dice = new Dice(6);
public void actionPerformed(ActionEvent e) {
dice.throwDie();
dice.getFaceValue();
}
}
throwButton.addActionListener(new Action());
}
}
不要在任何paint
方法中調用重新繪制。 這將導致重繪管理器安排另一個重繪事件,最終消耗您的CPU並停止您的編程。
而是為更新潛水者面值的動作偵聽器調用repaint
。
骰子和骰子DiceFaceComponent
之間也沒有任何聯系,它永遠不會知道應該繪制什么值。
另外,在您的DiceFace
類中,我不會在每次抽獎時都重新創建“點”,這只是浪費。 而是在構造函數中創建它們。
paintComponent
方法也是如此,不必費心重新創建DiceFace,在構造類並根據需要更新其面值時只需創建兩個引用。
我將使用Dice
作為將所有各種元素聯系在一起的基本模型。 通過使用諸如ChangeListerner
類的東西, Dice
可能會通知各個組件發生了更改,從而允許它們更新屏幕。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.