簡體   English   中英

如何在Java中使用JButton重新繪制組件?

[英]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.

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