2016-04-14 27 views
0

Bir javaFX tablosundaki bir metin alanının sütun adını nasıl alabilirim? Sadece "text2" sütununda hücrelerin değerini kontrol etmek için buna ihtiyacım var. textfield.parent() ile denedim, ancak yararlı bir sonuç almadım. Bu organize etmek (yön) daha iyi yolları muhtemelen vardırjavafx: sütun adını al

import java.util.ArrayList; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.scene.control.ContentDisplay; 
import javafx.scene.control.TableCell; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TextArea; 
import javafx.util.Callback; 

import javafx.application.Application; 
import static javafx.application.Application.launch; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.HBox; 
import javafx.stage.Stage; 


/*interface inside_table 
{ 
    public String get_column_name 
}*/ 

public class Supermain extends Application { 

    @Override 
    public void start(Stage primaryStage) { 

     ArrayList myindizes=new ArrayList(); 



     final TableView<myTextRow> table = new TableView<>(); 
     table.setEditable(true); 
     table.setStyle("-fx-text-wrap: true;"); 

     //Table columns 
     TableColumn<myTextRow, String> clmID = new TableColumn<>("ID"); 
     clmID.setMinWidth(160); 
     clmID.setCellValueFactory(new PropertyValueFactory<>("ID")); 

     TableColumn<myTextRow, String> clmtext = new TableColumn<>("Text"); 
     clmtext.setMinWidth(160); 
     clmtext.setCellValueFactory(new PropertyValueFactory<>("text")); 
     clmtext.setCellFactory(new TextFieldCellFactory()); 

     TableColumn<myTextRow, String> clmtext2 = new TableColumn<>("Text2"); 
     clmtext2.setMinWidth(160); 
     clmtext2.setCellValueFactory(new PropertyValueFactory<>("text2")); 
     clmtext2.setCellFactory(new TextFieldCellFactory()); 

     //Add data 
     final ObservableList<myTextRow> data = FXCollections.observableArrayList(
       new myTextRow(5, "Lorem","bla"), 
       new myTextRow(2, "Ipsum","bla") 
     ); 

     table.getColumns().addAll(clmID, clmtext,clmtext2); 
     table.setItems(data); 

     HBox hBox = new HBox(); 
     hBox.setSpacing(5.0); 
     hBox.setPadding(new Insets(5, 5, 5, 5)); 

     Button btn = new Button(); 
     btn.setText("Get Data"); 
     btn.setOnAction(new EventHandler<ActionEvent>() { 

      @Override 
      public void handle(ActionEvent event) { 
       for (myTextRow data1 : data) { 
        System.out.println("data:" + data1.getText2()); 
       } 
      } 
     }); 

     hBox.getChildren().add(btn); 

     BorderPane pane = new BorderPane(); 
     pane.setTop(hBox); 
     pane.setCenter(table); 
     primaryStage.setScene(new Scene(pane, 640, 480)); 
     primaryStage.show(); 


    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     launch(args); 
    } 


    public static class TextFieldCellFactory 
      implements Callback<TableColumn<myTextRow, String>, TableCell<myTextRow, String>> { 

     @Override 
     public TableCell<myTextRow, String> call(TableColumn<myTextRow, String> param) { 
      TextFieldCell textFieldCell = new TextFieldCell(); 
      return textFieldCell; 

     } 

     public static class TextFieldCell extends TableCell<myTextRow, String> { 

      private TextArea textField; 
      private StringProperty boundToCurrently = null; 
      private String last_text; 


      public TextFieldCell() { 

       textField = new TextArea(); 
       textField.setWrapText(true); 
       textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); 
       last_text=""; 



       this.setGraphic(textField); 

       textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> { 
//only if textfield is in the text2 column 
        if(isNowFocused){last_text=textField.getText(); System.out.println("NOW focus "+last_text);} 
        if (! isNowFocused && ! isValid(textField.getText())) { 
         textField.setText(last_text); 
         textField.selectAll(); 
         System.out.println("blur"); 

        } 

       }); 

      } 

      @Override 
      protected void updateItem(String item, boolean empty) { 
       super.updateItem(item, empty); 
       if (!empty) { 
        // Show the Text Field 
        this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY); 


        // myindizes.add(getIndex()); 

        // Retrieve the actual String Property that should be bound to the TextField 
        // If the TextField is currently bound to a different StringProperty 
        // Unbind the old property and rebind to the new one 
        ObservableValue<String> ov = getTableColumn().getCellObservableValue(getIndex()); 
        SimpleStringProperty sp = (SimpleStringProperty) ov; 

        if (this.boundToCurrently == null) { 
         this.boundToCurrently = sp; 
         this.textField.textProperty().bindBidirectional(sp); 
        } else if (this.boundToCurrently != sp) { 
         this.textField.textProperty().unbindBidirectional(this.boundToCurrently); 
         this.boundToCurrently = sp; 
         this.textField.textProperty().bindBidirectional(this.boundToCurrently); 
        } 

        double height = real_lines_height(textField.getText(), this.getWidth(), 30, 22); 
        textField.setPrefHeight(height); 
        textField.setMaxHeight(height); 

        textField.setMaxHeight(Double.MAX_VALUE); 
        // if height bigger than the biggest height in the row 
        //-> change all heights of the row(textfields()typeof textarea) to this height 
        // else leave the height as it is 


        //System.out.println("item=" + item + " ObservableValue<String>=" + ov.getValue()); 
        //this.textField.setText(item); // No longer need this!!! 
       } else { 
        this.setContentDisplay(ContentDisplay.TEXT_ONLY); 
       } 
      }//update 

      private boolean isValid(String s){ 

       if(s.length()<7){return true;} 
       return false; 


      } 

     } 

    } 

    public class myTextRow { 

     private final SimpleIntegerProperty ID; 

     private final SimpleStringProperty text; 
     private final SimpleStringProperty text2; 

     public myTextRow(int ID, String text,String text2) { 

      this.ID = new SimpleIntegerProperty(ID); 
      this.text = new SimpleStringProperty(text); 
      this.text2 = new SimpleStringProperty(text2); 


     } 


     //setter 
     public void setID(int id) { 
      this.ID.set(id); 
     } 

     public void setText(String text) { 
      this.text.set(text); 
     } 

     public void setText2(String text) {   
      this.text2.set(text);   
     } 

     //getter 
     public int getID() { 
      return ID.get(); 
     } 

     public String getText() { 
      return text.get(); 
     } 

     public String getText2() { 
      return text2.get(); 
     } 

     //properties 
     public StringProperty textProperty() { 
     return text; 

     } 

     public StringProperty text2Property() { 
     return text2; 

     } 

    public IntegerProperty IDProperty() { 
     return ID; 
    } 

    } 

    private static double real_lines_height(String s, double width, double heightCorrector, double widthCorrector) { 
     HBox h = new HBox(); 
     Label l = new Label("Text"); 
     h.getChildren().add(l); 
     Scene sc = new Scene(h); 
     l.applyCss(); 
     double line_height = l.prefHeight(-1); 

     int new_lines = s.replaceAll("[^\r\n|\r|\n]", "").length(); 
     // System.out.println("new lines= "+new_lines); 
     String[] lines = s.split("\r\n|\r|\n"); 
     // System.out.println("line count func= "+ lines.length); 
     int count = 0; 
     //double rest=0; 
     for (int i = 0; i < lines.length; i++) { 
      double text_width = get_text_width(lines[i]); 
      double plus_lines = Math.ceil(text_width/(width - widthCorrector)); 
      if (plus_lines > 1) { 
       count += plus_lines; 
       //rest+= (text_width/(width-widthCorrector)) - plus_lines; 
      } else { 
       count += 1; 
      } 

     } 
     //count+=(int) Math.ceil(rest); 
     count += new_lines - lines.length; 

     return count * line_height + heightCorrector; 
    } 

    private static double get_text_width(String s) { 
     HBox h = new HBox(); 
     Label l = new Label(s); 
     l.setWrapText(false); 
     h.getChildren().add(l); 
     Scene sc = new Scene(h); 
     l.applyCss(); 
     // System.out.println("dubbyloop.FXMLDocumentController.get_text_width(): "+l.prefWidth(-1)); 
     return l.prefWidth(-1); 

    } 

} 

cevap

1

, ama muhtemelen en temiz düzeltme cep uygulamasının kurucusuna bir boolean validate parametreyi tanımlamak için sadece geçerli: İşte benim Kod olduğunu. (Eğer gerçekten mantığın "sütunun başlığı belirli bir metne eşitse, o zaman doğrula" olmasını istemiyorsunuz. "Patronunuz ofise gelip uygulamayı uluslararasılaştırmanızı istediğinde tamamen batırdınız, hatta sadece örneğin sütunun başlığını değiştirmek)

içinden parametre geçmesine sadece görünüyor tamamen gereksiz geri arama uygulamak için bütün bir iç sınıf kullanarak, ancak olurdu tutmak.

public static class TextFieldCellFactory 
     implements Callback<TableColumn<myTextRow, String>, TableCell<myTextRow, String>> { 

    private final boolean validate ; 

    public TextFieldCellFactory(boolean validate) { 
     this.validate = validate ; 
    } 

    @Override 
    public TableCell<myTextRow, String> call(TableColumn<myTextRow, String> param) { 
     TextFieldCell textFieldCell = new TextFieldCell(validate); 
     return textFieldCell; 

    } 

    public static class TextFieldCell extends TableCell<myTextRow, String> { 

     private TextArea textField; 
     private StringProperty boundToCurrently = null; 
     private String last_text; 

     public TextFieldCell(boolean validate) { 

      textField = new TextArea(); 
      textField.setWrapText(true); 
      textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); 
      last_text=""; 



      this.setGraphic(textField); 

      if (validate) { 
       textField.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> { 
//only if textfield is in the text2 column 
        if(isNowFocused){last_text=textField.getText(); System.out.println("NOW focus "+last_text);} 
        if (! isNowFocused && ! isValid(textField.getText())) { 
         textField.setText(last_text); 
         textField.selectAll(); 
         System.out.println("blur"); 

        } 

       }); 
      } 

     } 

     // ... 

} 

Sonra tabii ki sadece

TableColumn<myTextRow, String> clmtext = new TableColumn<>("Text"); 
clmtext.setMinWidth(160); 
clmtext.setCellValueFactory(new PropertyValueFactory<>("text")); 
clmtext.setCellFactory(new TextFieldCellFactory(false)); 

TableColumn<myTextRow, String> clmtext2 = new TableColumn<>("Text2"); 
clmtext2.setMinWidth(160); 
clmtext2.setCellValueFactory(new PropertyValueFactory<>("text2")); 
clmtext2.setCellFactory(new TextFieldCellFactory(true)); 
01 do(Sorunuzu düzgün bir şekilde yanıtlamak için , getTableColumn().getText() ile eklendiği hücrenin içinden sütunun metnini alabilirsiniz, ancak işaret ettiğim gibi, aslında bir sütun üstbilgisinde görüntülenen değere mantığı dayanarak kodunuzu yapacak Tamamen ulaşılamaz.)

Ve ben tamlık için sanırım, TextFieldCellFactory sınıfının gerçekten herhangi bir amaca hizmet etmediğini düşündüğünden de bahsetmeliyiz. Ben tamamen kaldırmak ve sadece TextFieldCell sınıf var ve

TableColumn<myTextRow, String> clmtext = new TableColumn<>("Text"); 
clmtext.setMinWidth(160); 
clmtext.setCellValueFactory(new PropertyValueFactory<>("text")); 
clmtext.setCellFactory(c -> new TextFieldCell(false)); 

TableColumn<myTextRow, String> clmtext2 = new TableColumn<>("Text2"); 
clmtext2.setMinWidth(160); 
clmtext2.setCellValueFactory(new PropertyValueFactory<>("text2")); 
clmtext2.setCellFactory(c -> new TextFieldCell(true));