我是java和javafx的新手。我试图创建一个自定义类来显示timepicker,但它不会直观地呈现节点。
以下课程出了什么问题?
package customcombobox;
import javafx.event.EventHandler;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.Spinner;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
public class TLTimePicker extends GridPane{
private int hr = 1;
private int min;
private int sec;
private String meas = "AM";
private String value = hr+":"+ min +":"+ sec +" "+meas;
private final VBox timePicker = new VBox(5);
public TLTimePicker(){
this.render();
}
public TLTimePicker(int hour, int minute, int second, String measure){
this.hr = hour;
this.min = minute;
this.sec = second;
this.meas = measure;
this.value = hr+":"+ min +":"+ sec +" "+meas;
this.render();
}
public GridPane render(){
HBox contnr = new HBox();
TextField txtfld = new TextField();
txtfld.setEditable(false);
Button open = new Button();
contnr.getChildren().addAll(txtfld, open);
ImageView arrow = new ImageView(new Image(getClass().getResourceAsStream("down.png")));
open.setGraphic(arrow);
arrow.setFitWidth(12);
arrow.setFitHeight(12);
Label hrLbl = new Label("Hour");
Spinner hour = new Spinner(1, 13, 1);
Label mntLbl = new Label("minute");
Spinner minute = new Spinner(0, 61, 0);
Label scnLbl = new Label("second");
Spinner second = new Spinner(0, 61, 0);
ComboBox<String> ampm = new ComboBox<String>();
ampm.getItems().addAll("AM", "PM");
ampm.getSelectionModel().selectFirst();
hour.setPrefWidth(52);
minute.setPrefWidth(52);
second.setPrefWidth(52);
ampm.setPrefWidth(64);
hour.setEditable(true);
minute.setEditable(true);
second.setEditable(true);
txtfld.setText(value);
hour.valueProperty().addListener((ob, ov, nv) -> {
hr = (int)nv;
if(ov.equals(12)) {
hour.getValueFactory().setValue(1);
hr = 1;
}
String value = hr+":"+ min +":"+ sec +" "+meas;
txtfld.setText(value);
});
minute.valueProperty().addListener((ob, ov, nv) -> {
min = (int)nv;
if(ov.equals(60)) {
minute.getValueFactory().setValue(0);
min = 0;
}
String value = hr+":"+ min +":"+ sec +" "+meas;
txtfld.setText(value);
});
second.valueProperty().addListener((ob, ov, nv) -> {
sec = (int)nv;
if(ov.equals(60)) {
second.getValueFactory().setValue(0);
sec = 0;
}
String value = hr+":"+ min +":"+ sec +" "+meas;
txtfld.setText(value);
});
ampm.setOnAction((event) -> {
meas = ampm.getValue();
String value = hr+":"+ min +":"+ sec +" "+meas;
txtfld.setText(value);
});
GridPane grid = new GridPane();
grid.add(hrLbl, 0, 0);
grid.add(hour, 1, 0);
grid.add(mntLbl, 0, 1);
grid.add(minute, 1, 1);
grid.add(scnLbl, 0, 2);
grid.add(second, 1, 2);
grid.setHgap(5);
grid.setVgap(5);
timePicker.getChildren().addAll(grid, ampm);
timePicker.setStyle("-fx-background-color:"
+ "#ededed; -fx-border-color: "
+ "#dddddd; -fx-border-size:1;"
+ "-fx-padding:5 25;");
hidetimePicker();
arrow.setRotate(0);
EventHandler showHide = (event) -> {
Object[] obj = {hour, minute, second};
String[] arr = txtfld.getText().split("[\\s:]+");
for(int i=0; i<arr.length;i++ ){
if(arr[i].matches("^(\\d+)$")) {
((Spinner)obj[i]).getValueFactory().setValue(Integer.parseInt(arr[i]));
} else {
ampm.setValue(arr[i].toUpperCase());
}
}
if(timePicker.visibleProperty().getValue()) {
hidetimePicker();
arrow.setRotate(0);
} else {
timePicker.setVisible(true);
timePicker.setManaged(true);
arrow.setRotate(180);
}
};
open.setOnAction(showHide);
txtfld.setOnMousePressed(showHide);
GridPane group = new GridPane();
group.add(contnr, 0, 0);
group.add(timePicker, 0, 1);
timePicker.toFront();
Scene scene = group.getScene();
// scene.setOnMousePressed((event) -> {
// hidetimePicker();
// arrow.setRotate(0);
// });
return group;
}
private void hidetimePicker(){
timePicker.setVisible(false);
timePicker.setManaged(false);
}
}
将其称为 用它调用后会显示一个空白窗口。
package customcombobox;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class demo extends Application {
@Override
public void start(final Stage primaryStage) {
TLTimePicker timer = new TLTimePicker(5,27,0,"PM");
HBox box = new HBox();
box.getChildren().add(timer);
Scene scene = new Scene(box, 350, 250);
primaryStage.setScene(scene);
primaryStage.setTitle("TimePicker");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
答案 0 :(得分:0)
稍稍更改render()
。
首先,制作方法void
:
public void render() {
// most part of your code just stays as it is
...
然后第二,更改最后一行(注释掉你的行,其余行使其工作):
...
// GridPane group = new GridPane(); ---> you don't need a new one
// group.add(contnr, 0, 0);
// group.add(timePicker, 0, 1);
this.add(contnr, 0, 0);
this.add(timePicker, 0, 1);
timePicker.toFront();
// Scene scene = group.getScene();
// scene.setOnMousePressed((event) -> {
// hidetimePicker();
// arrow.setRotate(0);
// });
// return group;
}
您也可以在GridPane timer = new TLTimePicker(5,27,0,"PM").render()
而不是demo
中调用TLTimePicker timer = new TLTimePicker(5,27,0,"PM")
,而不是更改任何其他内容以使其正常工作,这会使GridPane在某种程度上过时...