2013-06-24 6 views
7

मैं सक्रिय रूप से क्रमबद्ध और एक नई पंक्ति हर मिलीसेकंड की प्रविष्टि के साथ JavaFX tableview उपयोग कर रहा हूँ ...JavaFX tableview वर्तमान दृश्य में चयनित पंक्ति रखें

मैं इस कार्यक्षमता हैं:

मैं एक पंक्ति तो का चयन किया है जब नई पंक्तियां डाली जाती हैं तो यह दिखना चाहिए (जो मेरी तालिका के वर्तमान दृश्य भाग से ऊपर या नीचे नहीं जाना चाहिए)।

+0

अभी तक आपने क्या प्रयास किया है? –

+0

table.scrollto (selectindex) लेकिन फिर कुछ चुनने पर यह स्क्रॉल करने की अनुमति नहीं देगा ... – learner

उत्तर

7

यह इसके चारों ओर लंबा हो सकता है और यह हैकिश की तरह है, लेकिन जब मुझे कुछ ऐसा करने की आवश्यकता होती है तो यह मेरे लिए काम करता है।

उत्तर का सारांश यह है कि आपको के VirtualFlow सदस्य तक पहुंच प्राप्त करने की आवश्यकता है। यह उतना आसान नहीं है जितना लगता है क्योंकि जब तक सीएसएस को पार्स नहीं किया जाता है तब तक त्वचा लोड नहीं होती है। मैंने TableView में जोड़ा और VirtualFlow इस तरह से प्राप्त करने में सक्षम था।

tableView.skinProperty().addListener(new ChangeListener<Skin>() 
{ 
    @Override 
    public void changed(ObservableValue<? extends Skin> ov, Skin t, Skin t1) 
    { 
     if (t1 == null) { return; } 

     TableViewSkin tvs = (TableViewSkin)t1; 
     ObservableList<Node> kids = tvs.getChildrenUnmodifiable(); 

     if (kids == null || kids.isEmpty()) { return; } 
     flow = (VirtualFlow)kids.get(1); 
    } 
}); 

के बाद आप VirtualFlow है, तो आप परिवर्तन के लिए मेज के ObservableList को सुनने और यह सुनिश्चित करें चयनित आइटम व्यूपोर्ट में अब भी है बनाने के लिए देख सकते हैं।

countries.addListener(new ListChangeListener<Country>() 
{ 
    @Override 
    public void onChanged(ListChangeListener.Change<? extends Country> change) 
    { 
     while (change.next()) 
     { 
      if (change.wasAdded()) 
      { 
      if (flow == null) { return; } 
      int first = flow.getFirstVisibleCell().getIndex(); 
      int last = flow.getLastVisibleCell().getIndex(); 
      int selected = tableView.getSelectionModel().getSelectedIndex(); 

      if (selected < first || selected > last) 
      { 
       flow.show(selected); 
      } 
      } 
     } 
    } 
}); 

अभी भी प्रबंधन के लिए कुछ बहीखाता होगी। उदाहरण के लिए, यदि आप टेबल पर फ़ोकस करना चाहते हैं। साथ ही, यह ध्यान देने योग्य है कि VirtualFlow तालिका के दृश्य आयत से कड़ाई से बाध्य नहीं है, इसलिए एक आइटम को दृश्यमान के बाहर होने पर भी दिखाई दे सकता है। अधिक जानकारी के लिए आप VirtualFlow का अध्ययन कर सकते हैं।

यहां एक एसएससीसीई है।

JavaFXApplication21.java:

package javafxapplication21; 

import javafx.application.Application; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class JavaFXApplication21 extends Application 
{ 
    @Override 
    public void start(Stage stage) throws Exception 
    { 
     Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml")); 

     Scene scene = new Scene(root); 

     stage.setScene(scene); 
     stage.show(); 
    } 

    public static void main(String[] args) 
    { 
     launch(args); 
    } 
} 

Sample.fxml:

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<AnchorPane id="AnchorPane" prefHeight="200.0" prefWidth="200.0" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication21.SampleController"> 
    <children> 
    <ToolBar AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> 
     <items> 
     <Button fx:id="insertBtn" mnemonicParsing="false" text="Insert" /> 
     </items> 
    </ToolBar> 
    <TableView fx:id="tableView" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="31.0"> 
     <columns> 
     <TableColumn prefWidth="100.0" text="Country" fx:id="countryColumn" /> 
     <TableColumn prefWidth="100.0" text="Capital" fx:id="capitalColumn" /> 
     </columns> 
    </TableView> 
    </children> 
</AnchorPane> 

SampleController.java:

package javafxapplication21; 

import com.sun.javafx.scene.control.skin.TableViewSkin; 
import com.sun.javafx.scene.control.skin.VirtualFlow; 
import java.net.URL; 
import java.util.*; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.collections.*; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.Node; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.PropertyValueFactory; 

public class SampleController implements Initializable 
{ 
    @FXML private Button insertBtn; 
    @FXML private TableView<Country> tableView; 
    @FXML private TableColumn<Country, String> countryColumn; 
    @FXML private TableColumn<Country, String> capitalColumn; 

    private VirtualFlow flow; 

    private ObservableList<Country> countries = 
      FXCollections.observableArrayList(); 
    private List<Country> insertList = new ArrayList<>(); 

    public SampleController() 
    { 
     countries.addAll(new Country("AG", "Buenos Aires"), 
       new Country("AU", "Vienna"), 
       new Country("BY", "Minsk"), 
       new Country("CO", "Bogota"), 
       new Country("EG", "Cairo")); 

     insertList.add(new Country("ZI", "Harare")); 
     insertList.add(new Country("UK", "London")); 
     insertList.add(new Country("TW", "Taipei")); 
    } 

    @Override 
    public void initialize(URL url, ResourceBundle rb) 
    { 
     countryColumn.setCellValueFactory(
       new PropertyValueFactory<Country, String>("name")); 
     capitalColumn.setCellValueFactory(
       new PropertyValueFactory<Country, String>("capital")); 

     tableView.setItems(countries); 

     tableView.skinProperty().addListener(new ChangeListener<Skin>() 
     { 
      @Override 
      public void changed(ObservableValue<? extends Skin> ov, 
       Skin t, Skin t1) 
      { 
       if (t1 == null) { return; } 

       TableViewSkin tvs = (TableViewSkin)t1; 
       ObservableList<Node> kids = tvs.getChildrenUnmodifiable(); 

       if (kids == null || kids.isEmpty()) { return; } 

       flow = (VirtualFlow)kids.get(1); 
      } 
     }); 

     insertBtn.setOnAction(new EventHandler<ActionEvent>() 
     { 
      @Override 
      public void handle(ActionEvent t) 
      { 
       if (!insertList.isEmpty()) 
       { 
        countries.add(2, insertList.get(0)); 
        insertList.remove(0); 
       } 
      } 
     }); 

     countries.addListener(new ListChangeListener<Country>() 
     { 
      @Override 
      public void onChanged(ListChangeListener.Change<? extends Country> change) 
      { 
       while (change.next()) 
       { 
        if (change.wasAdded()) 
        { 
         if (flow == null) { return; } 
         int first = flow.getFirstVisibleCell().getIndex(); 
         int last = flow.getLastVisibleCell().getIndex(); 
         int selected = tableView.getSelectionModel().getSelectedIndex(); 

         if (selected < first || selected > last) 
         { 
          flow.show(selected); 
         } 
        } 
       } 
      } 
     }); 
    } 

    public class Country 
    { 
     private SimpleStringProperty name; 
     private SimpleStringProperty capital; 

     public Country(String name, String capital) 
     { 
      this.name = new SimpleStringProperty(name); 
      this.capital = new SimpleStringProperty(capital); 
     } 

     public SimpleStringProperty nameProperty() { return name; } 
     public SimpleStringProperty capitalProperty() { return capital; } 
    } 
} 
1

मैं भी एक ही समस्या है.आप को cellEventHandler वर्ग का उपयोग कर सकते था जो इवेंट हैंडलर इंटरफ़ेस को तब तक निकाल देता है जब कक्ष में सेल को सील किया जाता है और अंतिम चयनित पंक्ति अनुक्रमणिका सेट किया जाता है एक चर के लिए। वर्ग का पालन किया जाता है।

public class CellEventHandler implements EventHandler<MouseEvent> 

{ 
    CellEventHandler() 
    { 
    } 

    @Override 
    public void handle(MouseEvent t) 
    { 
     TableCell c; 
     c = (TableCell) t.getSource(); 
     c.getIndex(); 
     PanelController.selectedItem = c.getIndex(); 
    } 
}` 

तब पैनल तालिका नियंत्रक कक्षा में तालिका का प्रस्तुत करने के लिए आपकी टेबल क्लास का पालन किया जाना चाहिए।

typeCol.setCellFactory(new Callback<TableColumn<tableModel, String>, TableCell<tableModel, String>>() 
    { 
     @Override 
     public TableCell<tableModel, String> call(TableColumn<tableModel, String> tableColumn) 
     { 
      LableCell lableCell = new LableCell(Pos.CENTER, true); 
      lableCell.addEventFilter(MouseEvent.MOUSE_CLICKED, new CellEventHandler()); 
      return lableCell; 
     } 
    }); 

"SelectedItem" क्षेत्र स्थिर क्षेत्र के रूप में panelController वर्ग में घोषित किया जाना चाहिए और फिर "SelectedItem" के रूप में तालिका में चयनित सेट किए जाने वाले है कि जब आप तालिका पंक्ति डेटा को ताज़ा करें।

myTable.getSelectionModel().select(selectedItem);  
संबंधित मुद्दे