JavaFX Progress Bar不会更新 [英] JavaFX Progress Bar doesn't update

查看:153
本文介绍了JavaFX Progress Bar不会更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经搜索了所有其他问题,但没有运气。我已经尝试了不同的事情超过四个小时并且完全没有进展(或错误,这更令人沮丧)所以我想我最终会问这里。

I've searched through all the other issues with this, but with no luck. I have been trying different things for over four hours and have gotten absolutely no progress (or errors, which is even more frustrating) so I figured I would finally ask here.

我正在开发一个小型的生存游戏,作为一个侧面项目来教我自己更多关于Java UI元素。玩家清除食物等等,这是一场对抗饥饿和口渴的比赛。我的情况是这样的:

I am working on a small survival game as a side project to teach myself more about Java UI elements. The player scavenges for food and such, and it is a race against starvation and thirst. The situation I have is such:

游戏打开一个控制器(MainController),它有几个条形指示角色的统计数据;对于这个例子,我们会说饥饿和渴望。

The game opens into a controller (MainController) that has several bars indicating the character's stats; for this example, we'll say Hunger and Thirst.

玩家可以点击按钮打开角色的库存,其中包括他们的食物。这将在新控制器(InventoryController)上打开一个新窗口,其中列出了与角色库存项目对应的按钮。

The player can click a button to open the character's inventory, which includes their food. This opens a new window on a new controller (InventoryController) that lists buttons corresponding to the character's inventory items.

当玩家点击食物项目时,角色的饥饿感会下降,并且相关的ProgressBar也应该下降。

When the player clicks a food item, the character's Hunger drops, and the associated ProgressBar should drop as well.

问题是:角色的内部饥饿状态下降,ProgressBar的进度下降,但是栏从未在视觉上更新,即使它在内部也是如此。

Issue is: The character's internal hunger stat drops, and the ProgressBar's progress drops, but the bar never updates visually, even though it did internally.

作为一个简单的例子:

public class MainController implements Initializable {

    @FXML private ProgressBar hungerBar;

    public void initialize(URL url, ResourceBundle rb) {
        updateBars();
    }    

    public void updateBars(){
        hungerBar.setProgress(CC.pc.getHunger()/100);
    }
}

这首先是它成功获得角色的饥饿感,将其除以100,然后设置条形(在本例中为.40)。没有问题。栏出现并且已满40%。但是,当我打开并使用第二个控制器时,没有任何反应。

This works at first. It successfully get's the character's hunger, divides it by 100, and then sets the bar (in this case, to .40). No issues. The bar appears and is 40% full. However, when I open and use the second Controller, nothing happens.

public class InventoryController implements Initializable {


    @Override
    public void initialize(URL url, ResourceBundle rb) {
    }    

    @FXML private void feedVenison(ActionEvent event) throws Exception{

        FXMLLoader loader = new FXMLLoader(getClass().getResource("Main.fxml"));
        loader.load();
        PlayController c = loader.<PlayController>getController();

        //Stuff that does the math and changes the character's stats here;
        //cut short for clarity.

        c.updateBars();
    }
}

我可以添加一些打印命令,例如一个System.out.println(hungerBar.getProgress()),看看一切都运行得很好。角色的饥饿感降低,反过来,栏的进度也会更新,并且在功能上更低。然而,酒吧永远不会改变,无论在.01和1之间的哪个地方设置。

I can add in a few Print commands, such as a System.out.println(hungerBar.getProgress()), and see that everything functions perfectly fine. The Character's hunger decreases, and in turn, the bar's progress is updated and is, functionally, lower. However, the bar never changes, no matter where between .01 and 1 it is set.

我已经尝试过并尝试过我的智慧结束!我显然做错了,我确信它很明显,但我不知道是什么。没有错误,它只是不起作用。我刚刚使用错误的工具来完成这项工作吗?给出了什么?

I've tried and tried and I'm at my wits end! I'm obviously doing something wrong, and I'm sure it is obvious, but I have no idea what. There's no errors, it just doesn't work. Am I just using the wrong tool for this job? What gives?

更新1:

更多的挖掘让我这个问题 ,这与我想要做的非常相似。不幸的是,它也没有答案。它有一条评论可以导致这个Oracle doc ,我试图实施。

More digging brought me to this question, which is very similar to what I am trying to do. Unfortunately, it has no answers either. It has a comment that leads to this Oracle doc, which I attempted to implement.

public void updateBars(){

    DoubleProperty hunger = new SimpleDoubleProperty(CC.pc.getHunger());
    hungerBar.progressProperty().bind(hunger);

}

但是再一次,我得到完全相同问题。条形图在内部更新,但UI永远不会更改,并始终显示不正确的静态金额。我该怎么办?

But once again, I get the exact same issue. The bar updates internally, yet the UI never changes and always displays a static amount that is incorrect. What do I do?

更新2:

我一直在挖,但是每当我想我找到答案时,它就会一遍又一遍地做同样的事情。试过这个,但结果相同。

I keep digging, but every time I think I have found the answer it just does the exact same thing over and over again. Tried out this, but same result.

public void updateBars(){

    maybeWillWork();

}

public void maybeWillWork()
 {
    Platform.runLater(new Runnable() {
        @Override public void run() {
           hungerBar.setProgress(CC.pc.getHunger()/100);
           System.out.println("It ran!");
        }
    });
}

完全相同的结果。

请。我究竟做错了什么?我拒绝相信整个StackOverflow被像我这样简单的ProgressBar所困扰;有人必须知道我犯了什么愚蠢的错误。

Please. What am I doing wrong? I refuse to believe that the entirety of StackOverflow is stumped by a simple ProgressBar like I am; someone has to know what stupid mistake I am making.

更新3:

那令人沮丧,但我得到了它的工作。我已经在下面发布了答案。

Well that was frustrating, but I got it to work. I have posted the answer below.

推荐答案

你的方法出了什么问题



您正在初始化控制器时更新该值,但您只是对该值进行快照。

What you're doing wrong in your approach

You're updating the value when the controller is initialized, but you're only making a "snapshot" of the value.

即使您使用该属性(更新1 ),您正在创建一个最初使用当前值填充的独立属性,但该属性中存储的值永远不会更新。

Even if you're using the property (Update 1) you're creating a independent property that is initially filled with the current value, but the value stored in the property is never updated.

但你再次打电话给 updateBars(),对吧?您这样做但是为此创建了一个带有新控制器实例的新场景,因此您不会调整显示的场景,而是调整从未显示的其他场景。

But you're calling updateBars() again, right? You do this but you create a new scene with a new controller instance for this purpose, so you do not adjust the scene that is displayed but some other scene that is never displayed.

因此,更新永远不会到达当前显示的场景。

For this reason the updates never reach the scene currently shown.

当然,您可以将现有控制器存储在方便的位置并访问它,但这样您就会增加你的程序的凝聚力。

Of course you could store the existing controller in a convenient location and access it, but this way you increase the cohesion of your program.

更好的方法是创建一个模型类并添加可观察的属性。您只需创建此类的单个实例,并将其传递到访问它的任何位置。通过观察程序的属性部分感兴趣的值可以更新自己:

A better approach would be to create a model class and add observable properties. You only create a single instance of this class and pass it everywhere where it's accessed. By observing the properties parts of your program "interested" in the value can update themselfs:

public class Model {

    private final DoubleProperty hunger = new SimpleDoubleProperty();

    public DoubleProperty hungerProperty() {
        return hunger;
    }

    public void setHunger(double value) {
        hunger.set(value);
    }

    public double getHunger() {
        return hunger.get();
    }

}

模型实例可以传递给控制器采用本问题中提到的方法之一:传递参数JavaFX FXML

The model instance can be passed to the controllers by one of the approaches mentioned in this question: Passing Parameters JavaFX FXML

例如

public class MainController {

    @FXML private ProgressBar hungerBar;

    public void setModel(Model model){
        hungerBar.progressProperty().bind(model.hungerProperty().divide(100d));
    }
}





public class InventoryController {

    @FXML private void feedVenison(ActionEvent event) throws Exception {
        model.setHunger(someNewValue);
    }

    private Model model;

    public void setModel(Model model){
        this.model = model;
    }
}

确保传递 使用您自己的 feedVenison 中的方法向两个控制器使用 Model 的相同实例方法 但仅在加载同时显示的场景时。 加载视图并使用包含 setModel的自定义界面的工厂方法可以帮助减少重复代码......

Make sure you're passing the same instance of Model to both controllers using the approach in your own feedVenison method but only when you load the a scene that is also displayed. A factory that loads the views and using a custom interface containtning the setModel method could help reduce duplicate code...

注意:您也可以通过使用课程中的属性来实现此目的用于 CC.pc ,但应避免使用静态成员传递信息的恕我直言。

Note: You could also achieve this by using a property in the class used for CC.pc, but IMHO using static members to pass information should be avoided.

这篇关于JavaFX Progress Bar不会更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆