【问题标题】:JavaFX Frozen GUI When adding Button on flow panelJavaFX Frozen GUI 在流面板上添加按钮时
【发布时间】:2018-10-24 11:40:16
【问题描述】:

如何在 JAVA FX Just like this987654321@ 中添加 5000 个按钮或标签到流面板而不冻结 GUI

为什么我需要这么多按钮 好吧,我不需要那么多,但至少需要 500 - 1000 个。因为我正在构建一个应用程序 Fonticon Tool

慢是可以的,但不是冻结 如果应用程序很慢并且需要几秒钟来显示所有按钮也没关系,但我不希望它冻结进度条和 GUI

工作原理 我有一个带有几个表的 SQLite database, 每个表都有一个values 的列表。一个对象给了我 ArrayList 值

我在寻找什么 我正在寻找类似的东西。

FlowPane fp = new FlowPane(); 

for(String fonticon_code : DatabaseTable.getlist()) //getlist() returns an array list of Strings
{
  fp.getChildren.add(new button().setGraphic(new FontIcon(fonticon_code)));

}

我也希望能够停止和重新启动线程

我累了什么 我试过线程,任务,平台。runLater(更新); 但我不确定我是否正确使用它们

【问题讨论】:

  • 嗨,Ash,如果您发布了整个程序,这将有助于回答。欢迎来到 SO!
  • 请提供一个minimal reproducible example 来说明问题。
  • 为什么需要 5000 个按钮?您的屏幕截图中甚至没有显示 100 个。您最好使用一些虚拟化控件,例如GridView。 5000 个节点的创建和布局不可避免地需要很长时间,GridView 会将创建的单元格数量减少到可见的单元格。
  • @fabian 我正在构建一个应用程序,它需要 FlowPane 上的几百个按钮。为什么要问 FlowPane?调整窗口大小时,FlowPane 中的所有内容都会重新排列
  • 按照@fabian 的建议使用GridView

标签: java javafx concurrency


【解决方案1】:

这里是 MCVE 使用 ControlsFX GridView

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import org.controlsfx.control.GridCell;
import org.controlsfx.control.GridView;

/**
 *
 * @author blj0011
 */
public class JavaFXApplication287 extends Application
{

    @Override
    public void start(Stage primaryStage)
    {
        ObservableList observableList = FXCollections.observableArrayList(Font.getFamilies());
        GridView<String> myGrid = new GridView(observableList);
        myGrid.setHorizontalCellSpacing(0);
        myGrid.setVerticalCellSpacing(0);
        myGrid.setCellFactory(gridView -> {
            return new GridCell<String>()
            {
                Button button = new Button("ABC");

                {
                    button.setPrefWidth(60);
                    button.setPrefHeight(60);
                }

                @Override
                public void updateItem(String item, boolean empty)
                {
                    if (empty || item == null) {
                        setText(null);
                        setGraphic(null);
                    }
                    else {
                        button.setFont(new Font(item, 14));
                        setGraphic(button);
                    }

                }
            };
        });

        StackPane root = new StackPane(myGrid);
        Scene scene = new Scene(root, 500, 700);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

}

【讨论】:

  • 哇,我从来不知道我们可以做这样的事情,如图所示。非常感谢您花时间无限期地尝试一下。但我的问题是关于 JavaFX UI 更新线程。我想在其他线程中添加一个按钮到流面板。不冻结一切
  • @Ash 我稍微改变了答案。使用Button 而不是Label。我发现有趣的是,大多数 cmets 都建议您放弃正在做的事情并使用一些虚拟化控制。然而,你坚持做你正在做的事情。你的问题可能不是你想的那样。可能只是您采取了错误的方法。
  • 感谢您的帮助好友
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
  • 2014-08-29
  • 1970-01-01
  • 2013-05-06
相关资源
最近更新 更多