javaFX 8 中的投票栏

Voting bar in javaFX 8

我有一个问题,如何在 Java 中创建实时更新百分比

<div class="meter">
    <span id="bar1" style="width: 50%">test</span> 
    <span id="bar2" style="width: 50%">test</span>
</div>

你可以看到它有一个 Bar(仪表),比方说 1000px,里面有两个 bar。如果有人投票给第一队 bar1 是 100% 而 bar2 是 0% 那么在仪表中只有 bar1.

我尝试使用 Java动态改变宽度的 FX 8 矩形,但因为它不更新所以不起作用。

Main.java

package application;

import java.awt.geom.Rectangle2D;
import java.io.IOException;

import org.jibble.pircbot.IrcException;
import org.jibble.pircbot.NickAlreadyInUseException;

import application.TwitchBot.Test;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextArea;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.scene.paint.Paint;


public class Main extends Application implements Test{
     //local interface stuff
    TextArea output = new TextArea();
    Rectangle bar1 = new Rectangle();
    Rectangle bar2 = new Rectangle();

    double MID = 315;

    Stage secondStage = new Stage();        
    Pane BarPane = new Pane();
    Scene Bar = new Scene(BarPane, 650, 150, Color.GREEN);

    @Override
    public void start(Stage primaryStage) throws NickAlreadyInUseException, IOException, IrcException {

        //Stage 1
        StackPane root = new StackPane();
        Scene scene = new Scene(root, 300, 250);

        output.setEditable(false);
        root.getChildren().add(output);
        output.appendText("/// WELCOME TO THE TWITCH BOT PREALPHA ///");

        primaryStage.setTitle("Twitch Bot");
        primaryStage.setScene(scene);
        primaryStage.show();

        //create Stage2


        BarPane.setStyle("-fx-background-color:#00FF00");
        BarPane.setPrefSize(200,200);


        //BAR 1
        Rectangle bar1 = new Rectangle();
        bar1.setX(10);
        bar1.setY(50);
        bar1.setWidth(MID);
        bar1.setHeight(50);
        bar1.setFill(Color.BLUE);

        //Bar 2
        Rectangle bar2 = new Rectangle();
        bar2.setX(MID);
        bar2.setY(50);
        bar2.setWidth(650-MID-10);
        bar2.setHeight(50);
        bar2.setFill(Color.RED);

        BarPane.getChildren().addAll(bar1,bar2);

        secondStage.setTitle("Second Stage");
        secondStage.setScene(Bar); 
        secondStage.show(); 


        //Start BOT
        TwitchBot bot = new TwitchBot();
        bot.interfaceCallback = this;
        bot.setVerbose(true);
        bot.connect("irc.twitch.tv", 6667, "oauth:XXXXXXX");
        bot.joinChannel("#XXXXXXX");

    }
    public void stop(){
        System.exit(0);
    }
    public static void main(String[] args){
        launch(args);
    }
    @Override
    public void printScreen(String message) {
        Platform.runLater(new Runnable(){

            @Override
            public void run() {
                output.appendText("\n");
                output.appendText(message); 
                secondStage.show(); 
            }

        }); 
    }
    @Override
    public void setPercent(double Team1, double Team2) {
        MID = ((650*Team1)/100)-10;
        Platform.runLater(new Runnable(){
            @Override
            public void run() {
                System.out.println(MID);
                bar1.setWidth(MID);
                bar2.setX(MID);
                bar2.setWidth(650-MID-10);
            }
        }); 

    }
    @Override
    public void setTeamnames(String Team1, String Team2) {
        Platform.runLater(new Runnable(){
            @Override
            public void run() {

            }
        }); 

    }
}

TwitchBot.java

    package application;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Properties;

import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import org.jibble.pircbot.*;

public class TwitchBot extends PircBot {

    // Count Votes
    double VoteT1 = 0;
    double VoteT2 = 0;
    double TotalVotes = 0;
    double T1percent = 0;
    double T2percent = 0;

    // User Arry (Every user can vote 1 time
    String users[] = new String[0];

    // Files
    File configFile = new File("config.properties");
    String team1 = "team1.txt";
    String team2 = "team2.txt";
    String teamnames = "teams.txt";

    // Write Channel
    String Channel = "#XXXXX";

    // Name
    String BotName = "DotaLanBot";

    // Default Keywords
    String Voting = "!voteing"; //Vote Statistics

    // Default Properties
    String Team1 = "none";
    String Team2 = "none";
    String Power = "XXX";

    public Test interfaceCallback;

    public interface Test{
        public void printScreen(String message);
        public void setPercent(double Team1, double Team2);
        public void setTeamnames(String Team1, String Team2);
    }

    public TwitchBot() {
        loadSettings();

        this.setName("dotalanbot");
        sendMessage(Channel, "Hi I'm your Bot");
        //writeInfile(teamnames, Team1 + "  vs  " + Team2);
        T1percent = 50;
        T2percent = 50;
    }

    public void onMessage(String channel, String sender, String login,String hostname, String message) {
        //Chat ausgabe in Textfeld
        interfaceCallback.printScreen(sender+": "+message);


        if (message.equalsIgnoreCase("!win " + Team1)) {
            if (check(sender)) {
                System.out.println("vote team1");
                System.out.println(sender);
                VoteT1++;
                TotalVotes++;
                sendMessage(Channel, "Vote for " + Team1);
                T1percent = calcPercent(VoteT1);
                T2percent = calcPercent(VoteT2);
                interfaceCallback.setPercent(T1percent,T2percent);
            //  users(sender);
            }
        }
        if (message.equalsIgnoreCase("!win " + Team2)) {
            if (check(sender)) {
                System.out.println("vote team1");
                System.out.println(sender);
                VoteT2++;
                TotalVotes++;
                sendMessage(Channel, "Vote for " + Team2);
                T1percent = calcPercent(VoteT1);
                T2percent = calcPercent(VoteT2);
                interfaceCallback.setPercent(T1percent,T2percent);
                //users(sender);
            }
        }
        if (message.equalsIgnoreCase(Voting)) {
            System.out.println(Team1 + ":" + VoteT1 + " Votes");
            System.out.println(Team2 + ":" + VoteT2 + " Votes");
            System.out.println("Total Votes:" + TotalVotes);
            sendMessage(Channel, Team1 + ":" + VoteT1 + " Votes  ||  " + Team2
                    + ":" + VoteT2 + " Votes  ||  " + "Total Votes:"
                    + TotalVotes);
        }

        if (message.equalsIgnoreCase("!resetvote")) {
            if (sender.equalsIgnoreCase(Power)) {
                sendMessage(Channel, "Voteing Reset");
                resetvote();
            }
        }

        if (message.equalsIgnoreCase("!test")) {
                sendMessage(Channel, "Test");
        }

        if(message.length()>9){
        if ((message.substring(0, 9)).equalsIgnoreCase("!setteam1" )) {
            if (sender.equalsIgnoreCase(Power)) {
                sendMessage(Channel, "Team 1 set to = "+message.substring(10));
                Team1 = message.substring(10);
            }
        }

        if ((message.substring(0, 9)).equalsIgnoreCase("!setteam2" )) {
            if (sender.equalsIgnoreCase(Power)) {
                sendMessage(Channel, "Team 2 set to = "+message.substring(10));
                Team2 = message.substring(10);
            }
        }
        }
    }

    //reset Voteing
    private void resetvote(){
        //writeInfile(teamnames, Team1 + "  vs  " + Team2);
        T1percent = 50;
        T2percent = 50;
        interfaceCallback.setPercent(T1percent,T2percent);
        String users[] = new String[0];
        saveSettings();
    }

    // write user to array
    private void users(String user) {
        String[] temp = new String[users.length + 1];
        temp[temp.length - 1] = user;
        users = temp;
    }

    // Check if user votes before
    private boolean check(String user) {
        for (int i = 0; i < users.length; i++) {
            if (user.equalsIgnoreCase(users[i])) {
                return false;
            }
        }
        return true;
    }

    // CALS PERCENT
    private double calcPercent(double calc) {
        double result = (calc / TotalVotes) * 100;
        return result;
    }

    // SETTINGS STUFF
    private void saveSettings() {
        // wirte Prop
        try {
            Properties props = new Properties();

            props.setProperty("Team1", Team1);
            props.setProperty("Team2", Team2);
            props.setProperty("Power", Power);

            FileWriter writer = new FileWriter(configFile);
            props.store(writer, "settings");
            writer.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
        } catch (IOException ex) {
            // I/O error
        }
    }

    private void loadSettings() {
        // Read
        try {
            FileReader reader = new FileReader(configFile);
            Properties props = new Properties();
            props.load(reader);

            Team1 = props.getProperty("Team1");
            Team2 = props.getProperty("Team2");
            Power = props.getProperty("Power");

            reader.close();
        } catch (FileNotFoundException ex) {
            // file does not exist
        } catch (IOException ex) {
            // I/O Error
        }
    }

}

您添加到场景图中(通过 BarPane.getChildren().addAll(...))的 Rectangle 与您在 start(...) 方法之外引用的不同。因此,当您在 setPercent(...) 中使用 bar1.setWidth(...)bar2.setWidth(...) 更新它们时,您并没有更新显示的 Rectangle

问题是您在 class 定义的开头使用

声明了实例变量
Rectangle bar1 = new Rectangle();
Rectangle bar2 = new Rectangle();

然后在 start(...) 方法中,声明具有相同名称的局部变量:

@Override
public void start(Stage primaryStage) {
    // ...
    Rectangle bar1 = new Rectangle();
    // ...
    Rectangle bar2 = new Rectangle();
    // ...
}        

因为你在这里再次声明了它们,所以它们不是同一个变量。

要解决此问题,只需删除 start(...) 方法中的声明,即:

@Override
public void start(Stage primaryStage) {
    // ...
    bar1 = new Rectangle();
    // ...
    bar2 = new Rectangle();
    // ...
}        

最好也删除 class 顶部的初始化。这样,如果您确实犯了错误,您会在尝试访问它们时立即收到通知,并带有 NullPointerException。所以:

public class Main extends Application implements Test{

    //...

    Rectangle bar1 ;
    Rectangle bar2 ;

    // ...

    @Override
    public void start(Stage primaryStage) {

        // ...

        bar1 = new Rectangle();
        // ...

        bar2 = new Rectangle();
        // ...
    }

    // ...
}