我正在尝试制作一个程序,您可以在其中添加名称作为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
答案 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