2017-07-19 111 views
0

我是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); 
    }  
} 
+1

首先,您應該使用fxml文件的佈局層次結構深度。 然後我注意到,你從render方法返回一個GridPane,但你只是在構造函數中調用它,而不使用'使用它的值...這可能嗎? 所以你的GridPane組在最後已經過時了,因爲你可以添加內容到「this」,因爲你的類已經是一個(n空的)GridPane了。 – deHaar

回答

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以某種方式過時...