JavaFX随机填充ListViews

时间:2020-01-22 15:36:21

标签: javafx

我正在尝试制作一个程序,您可以在其中添加名称作为CheckBoxes。通过选中它们并按下randomize按钮,所有名称将被放置在2个不同的ListView中(每个名称只能放置一次,并且每个ListView必须具有相同数量的名称或另外1个名称)。我不知道应该如何在“ onRandom”部分中编写它。

public ChromiumWebBrowser chromeBrowser;

public Form1()
{
    InitializeComponent();

    Cef.EnableHighDPISupport();
    Cef.Initialize(settings);

    chromeBrowser = new ChromiumWebBrowser("https://www.google.com/");

    Controls.Add(chromeBrowser);
    chromeBrowser.Dock = DockStyle.Fill;
}

public Task LoadPageAsync(IWebBrowser browser, string address = null)
{
    var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
    EventHandler<LoadingStateChangedEventArgs> handler = null;
    handler = (sender, args) =>
    {
        if (!args.IsLoading)
        {
            browser.LoadingStateChanged -= handler;
            tcs.TrySetResult(true);
        }
    };

    browser.LoadingStateChanged += handler;
    if (!string.IsNullOrEmpty(address))
        browser.Load(address);
    return tcs.Task;
}

private async void button1_Click(object sender, EventArgs e)
{
   await LoadPageAsync(chromeBrowser, "https://stackoverflow.com/questions/59862329/wordpress-submit-form-into-new-tab-and-continue-processing");
   var canExecuteJs = chromeBrowser.CanExecuteJavascriptInMainFrame; //FALSE
   await LoadPageAsync(chromeBrowser, "https://stackoverflow.com/questions/59861819/getting-2-values-from-array-of-objects");
   var canExecuteJs1 = chromeBrowser.CanExecuteJavascriptInMainFrame; //TRUE
}

下面的这个仅用于测试。

package sample;


import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import java.util.Objects;


public class Controller {

    @FXML
    private Button add;
    @FXML
    private Button delete;
    @FXML
    private VBox vbox;
    @FXML
    private TextField text;
    @FXML
    private Button random;
    @FXML
    private ListView listview1;
    @FXML
    private ListView listview2;
    @FXML
    private CheckBox cb;




    @FXML
    void initialize() {

    }

    @FXML
    public void onEnter(ActionEvent e){
        CheckBox cb = new CheckBox(text.getText());
        vbox.getChildren().add(cb);
        if (text.getText().matches("")) {
            vbox.getChildren().remove(cb);
        }
    }

    @FXML
    public void onAdd(ActionEvent e) {
        CheckBox cb = new CheckBox(text.getText());
        vbox.getChildren().add(cb);
        if (text.getText().matches("")) {
            vbox.getChildren().remove(cb);
        }
    }
    @FXML
    public void onDelete(ActionEvent e) {
        vbox.getChildren().removeIf(child -> ((CheckBox) child).isSelected());
    }

    @FXML
    public void onRandom(ActionEvent e) {
        vbox.getChildren()
                .stream()
                .map(item -> (CheckBox) item)
                .filter(item -> item.isSelected())
                .filter(value -> Objects.nonNull(value))
                .forEach(value -> {
                    listview1.getItems().add(value.getText());
                    listview2.getItems().add(value.getText());
                });
        }
}

这是我的FXML文件https://pastebin.com/9v8e0c0Y

1 个答案:

答案 0 :(得分:2)

使用Collections.shuffle创建列表的随机排列,然后将前半部分添加到一个ListView中,然后将其余部分添加到另一个。

// do not use raw types
@FXML
private ListView<String> listview1;
@FXML
private ListView<String> listview2;
...

private final Random randomNumberGenerator = new Random();
List<String> items = new ArrayList<>(); // copy children to new list

// the following loop imho is easier to comprehend than the Stream implementation
for (Node child : vbox.getChildren()) {
    CheckBox cb = (CheckBox) child;
    if (cb.isSelected) {
        items.add(cb.getText());
    }
}

Collections.shuffle(items, randomNumberGenerator);
final int size = items.size();
final int half = size / 2;

// add first half to first ListView and second half to second ListView
listview1.getItems().setAll(items.sublist(0, half));
listview2.getItems().setAll(items.sublist(half, size));

请注意,在您的情况下,实际上Stream上不需要进行某些方法调用:

.filter(value -> Objects.nonNull(value))

对于null的{​​{1}}列表,永远不需要检查children。列表实现可防止将Parent插入到该列表中。如果谓词仍然产生null,则先前的过滤器应该抛出NPE。如果确实需要这样的谓词,则可以使用方法引用来缩短代码:

false
相关问题