我需要的:
- 需要一个可编辑的组合框,它可以在键入时过滤弹出窗口上的数据,并且第一个匹配的项目应突出显示,并应在按 Enter 键时设置为组合中的文本。
- 弹出窗口应该是一个包含 2 或 3 列的表格视图。 (附有屏幕截图。)(在图像中,它是一个文本字段,但我更喜欢组合,这样如果用户不确定这些值,他可以单击组合按钮并查看整个列表并选择一个。)
我将把一些数据作为源绑定到表视图,该表视图应充当组合框的弹出窗口。
我知道我应该选择自定义控件,但不知道从哪里开始?
参考网址:在此输入链接描述 https://youtu.be/DvXp_7_Wx9U
提前致谢。
到目前为止我已经尝试过:
Guys,
根据你们提供的想法,到目前为止我已经尝试过并且能够实现。
(目前,我没有在文本字段下方动态显示表格视图(最终是我想要的))
1. 带有静态数据的表格视图已加载并添加到场景中。
2. 在表格视图下方有一个文本字段。 (这被命名为txt)
3. 在第一个文本字段下方有另一个文本字段(名为 txt1)(当我从上一个文本字段按 Tab 时,光标应该来到这里)
我为表设置了谓词,并且当用户在 txt 中键入时更新我的谓词。 (在职的)
能够过滤表格,第一个匹配的行将突出显示。 (在职的)
当用户按“Tab”或“Enter”时,表视图中突出显示的行应设置为txt中的值。(工作)
需要:
1. 当我按“Tab”或“Enter”时,突出显示的行将被设置为文本字段(txt)中的值,并且光标应移动到下一个可聚焦节点。就我而言,它是第二个文本字段(txt1)。我不想实时说 txt1.requestFocus() bcoz,我在场景中有很多文本字段,并且此控件将是用户控件。所以不能硬编码任何东西。
- 当用户在文本字段中键入一些文本(不是全文。例如:“do”,其中我的表包含“Dom”、“Don”)时,如果有多个匹配项,当前两条记录都会显示在表中,但是第一个将突出显示。如果用户愿意,应该能够通过按文本字段本身的向下箭头来选择第二行。
主程序.java
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
VBox root = FXMLLoader.load(this.getClass().getResource("MainView.fxml"));
Scene scene = new Scene(root,500,300);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
主控制器.java
package application;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.stage.Popup;
public class MainController implements Initializable
{
private @FXML TableView<Person> table;
private @FXML TableColumn<Person, String> firstNameCol;
private @FXML TableColumn<Person, String> lastNameCol;
private @FXML TableColumn<Person, String> emailCol;
private @FXML TableColumn<Person, Integer> ageCol;
private @FXML TextField txt;
private @FXML TextField txt1;
private @FXML Button btn;
@Override
public void initialize(URL location, ResourceBundle resources)
{
Platform.runLater(new Runnable() {
@Override
public void run() {
txt.requestFocus();
}
});
ObservableList<Person> obsList =FXCollections.observableArrayList();
obsList.add(new Person("Sam", "P1LasttName", "[email protected] /cdn-cgi/l/email-protection", 20));
obsList.add(new Person("Dom", "P2LasttName", "[email protected] /cdn-cgi/l/email-protection", 30));
obsList.add(new Person("Ken", "P3LasttName", "[email protected] /cdn-cgi/l/email-protection", 40));
obsList.add(new Person("Don", "P4LasttName", "[email protected] /cdn-cgi/l/email-protection", 50));
obsList.add(new Person("Tom", "P5LasttName", "[email protected] /cdn-cgi/l/email-protection", 60));
FilteredList<Person> filteredList = new FilteredList<>(obsList, p->true);
table.setItems(filteredList);
txt.textProperty().addListener((obs, oldValue, newValue) ->{
filteredList.setPredicate(person-> {
if(newValue == null || newValue.isEmpty())
return true;
if(person.getFirstName().trim().toLowerCase().contains(newValue.toLowerCase()))
return true;
return false;
});
Platform.runLater(new Runnable() {
@Override
public void run()
{
// we don't want repeated selections
table.getSelectionModel().clearSelection();
//get the focus
table.requestFocus();
//select first item in TableView model
table.getSelectionModel().selectFirst();
//set the focus on the first element
table.getFocusModel().focus(0);
//render the selected item in the TableView
//tableClickHandler(null);
}
});
Platform.runLater(new Runnable() {
@Override
public void run()
{
txt.requestFocus();
txt.end();
}
});
});
table.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event)
{
if(event.getCode() == KeyCode.ENTER)
{
txt.setText(table.getSelectionModel().getSelectedItem().getFirstName());
}
}
});
txt.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event)
{
if(event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB)
//if(event.getCode() == KeyCode.ENTER)
{
txt.setText(table.getSelectionModel().getSelectedItem().getFirstName());
/*Platform.runLater(new Runnable() {
public void run() {
txt1.requestFocus();
}
});*/
}
}
});
/*txt.addEventFilter(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event)
{
if(event.getCode() == KeyCode.TAB)
{
//txt.setText(table.getSelectionModel().getSelectedItem().getFirstName());
if(txt.getSkin() instanceof BehaviorSkinBase)
{
//((BehaviorSkinBase)txt.getSkin()).getBehavior().traverseNext();
BehaviorBase x = ((BehaviorSkinBase)txt.getSkin()).getBehavior();
((TextFieldBehavior)x).callAction("TraverseNext");
}
event.consume();
}
}
});*/
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event)
{
/*
Popup popup = new Popup();
popup.getContent().add(new TableView());
//popup.show(txt, txt.localToScreen(0, 0).getX() + txt.getWidth()/2, txt.localToScreen(0, 0).getY() + txt.getHeight());
popup.show(txt, txt.localToScreen(0, 0).getX(), txt.localToScreen(0, 0).getY() + txt.getHeight() + 2);
*/
Parent vbox = null;
try {
vbox = FXMLLoader.load(this.getClass().getResource("TableView.fxml"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Popup popup = new Popup();
popup.getContent().add(vbox);
//popup.show(txt, txt.localToScreen(0, 0).getX() + txt.getWidth()/2, txt.localToScreen(0, 0).getY() + txt.getHeight());
//popup.show(txt, txt.localToScreen(0, 0).getX(), txt.localToScreen(0, 0).getY() + txt.getHeight() + 2);
popup.show(txt, txt.localToScreen(0, 0).getX(), txt.localToScreen(0, 0).getY() + txt.getHeight() + 2);
}
});
}
}
人.java
package application;
public class Person
{
private String firstName;
private String lastName;
private String email;
private Integer age;
public Person(){}
public Person(String firstName, String lastName, String email, Integer age)
{
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.age = age;
}
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public Integer getAge()
{
return age;
}
public void setAge(Integer age)
{
this.age = age;
}
}
应用程序.css
.table-row-cell:selected
{
-fx-background-color: lightgreen;
/* the below style will remove the border lines of the selected row */
-fx-table-cell-border-color: transparent;
}
主视图.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.layout.VBox?>
<!-- <?import application.Person?> -->
<VBox spacing="10.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
<children>
<TableView fx:id="table" prefHeight="250.0" prefWidth="437.0">
<columns>
<TableColumn fx:id="firstNameCol" prefWidth="120.0" text="First Name">
<cellValueFactory><PropertyValueFactory property="firstName" /></cellValueFactory>
</TableColumn>
<TableColumn fx:id="lastNameCol" prefWidth="120.0" text="Last Name">
<cellValueFactory><PropertyValueFactory property="lastName" /></cellValueFactory>
</TableColumn>
<TableColumn fx:id="emailCol" prefWidth="120.0" text="Email">
<cellValueFactory><PropertyValueFactory property="email" /></cellValueFactory>
</TableColumn>
<TableColumn fx:id="ageCol" prefWidth="75.0" text="Age">
<cellValueFactory><PropertyValueFactory property="age" /></cellValueFactory>
</TableColumn>
</columns>
</TableView>
<Button text="Button" fx:id="btn"/>
<TextField fx:id="txt" promptText="Type to Filter" />
<TextField fx:id="txt1" promptText="Focus should be here when tab is pressed from pervious txt" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</VBox>
表格视图.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.layout.VBox?>
<?import application.Person?>
<?import javafx.collections.*?>
<!--
<VBox xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65">
<children>
-->
<!-- <TableView xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65" fx:id="table" prefHeight="160.0" prefWidth="440.0"> -->
<TableView xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.65" fx:id="table" prefHeight="140.0">
<columns>
<TableColumn fx:id="firstNameCol" prefWidth="120.0" text="First Name">
<cellValueFactory><PropertyValueFactory property="firstName" /></cellValueFactory>
</TableColumn>
<TableColumn fx:id="lastNameCol" prefWidth="120.0" text="Last Name">
<cellValueFactory><PropertyValueFactory property="lastName" /></cellValueFactory>
</TableColumn>
<TableColumn fx:id="emailCol" prefWidth="120.0" text="Email">
<cellValueFactory><PropertyValueFactory property="email" /></cellValueFactory>
</TableColumn>
<TableColumn fx:id="ageCol" prefWidth="75.0" text="Age">
<cellValueFactory><PropertyValueFactory property="age" /></cellValueFactory>
</TableColumn>
</columns>
<columnResizePolicy><TableView fx:constant="CONSTRAINED_RESIZE_POLICY" /></columnResizePolicy>
<items>
<FXCollections fx:factory="observableArrayList">
<Person firstName="P1FirstName" lastName="P1LasttName" email="[email protected] /cdn-cgi/l/email-protection" age="20"/>
<Person firstName="P2FirstName" lastName="P2LasttName" email="[email protected] /cdn-cgi/l/email-protection" age="30"/>
<Person firstName="P3FirstName" lastName="P3LasttName" email="[email protected] /cdn-cgi/l/email-protection" age="40"/>
<Person firstName="P4FirstName" lastName="P4LasttName" email="[email protected] /cdn-cgi/l/email-protection" age="50"/>
<Person firstName="P5FirstName" lastName="P5LasttName" email="[email protected] /cdn-cgi/l/email-protection" age="60"/>
</FXCollections>
</items>
</TableView>
<!--
</children>
</VBox>
-->
任何帮助表示赞赏。谢谢!