我想調整一些TableView
列的大小,因爲實現此目的的一種方法從javafx中丟失,我設法找到在MainApp.GUIUtil.fitColumns(TableView tableView)
中公開的解決方案。
我的問題是:此解決方案在用戶操作調用時工作正常,但我無法找到在啓動任何用戶干預之前在啓動時運行此方法的方法。
我想要顯示錶格,其中顯示的表格適合作爲soos使用。
正如你所看到的,我攔截了導致我頭痛的Exception
(PersonTableController.setMainApp第32行),打印堆棧跟蹤,然後讓程序繼續證明適配方法在給予用戶控制權後工作。
一旦tableview被顯示,我如何通過代碼來適應列大小?JavaFX TableView列符合內容
Exception in Application start method
java.lang.reflect.InvocationTargetException
...
Caused by: java.lang.RuntimeException: Exception in Application start method
...
Caused by: java.lang.NullPointerException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at columnstofit.MainApp$GUIUtil.fitColumns(MainApp.java:120)
at columnstofit.PersonTableController.setMainApp(PersonTableController.java:35)
at columnstofit.MainApp.showPersonTable(MainApp.java:79)
at columnstofit.MainApp.start(MainApp.java:65)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
... 1 more
Exception running application columnstofit.MainApp
這裏是我的代碼:
package columnstofit;
import com.sun.javafx.scene.control.skin.TableViewSkin;
import java.awt.AWTException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
public class MainApp extends Application {
private PersonTableController controller;
public static Stage primaryStage;
AnchorPane personTable;
private ObservableList<Person> personData = FXCollections.observableArrayList();
/**
* Constructor
*/
public MainApp() {
// i am entering this name just to force the resizing of the column
personData.add(new Person("Hansgggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg", "Muster"));
personData.add(new Person("Ruth", "Mueller"));
personData.add(new Person("Heinz", "Kurz"));
personData.add(new Person("Cornelia", "Meier"));
personData.add(new Person("Werner", "Meyer"));
personData.add(new Person("Lydia", "Kunz"));
personData.add(new Person("Anna", "Best"));
personData.add(new Person("Stefan", "Meier"));
}
/**
* Returns the data as an observable list of Persons.
* @return
*/
public ObservableList<Person> getPersonData() {
return personData;
}
@Override
public void start(Stage primaryStage) throws AWTException {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Names Table");
showPersonTable();
}
public void showPersonTable() throws AWTException {
try
{
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("PersonTable.fxml"));
personTable = (AnchorPane) loader.load();
// Give the controller access to the main app.
controller = loader.getController();
controller.setMainApp(this);
Scene scene = new Scene(personTable);
primaryStage.setScene(scene);
primaryStage.show();
}
catch (IOException e) { e.printStackTrace(); }
}
/**
* Returns the main stage.
* @return
*/
public Stage getPrimaryStage() {
return primaryStage;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
public static class GUIUtil {
private static Method columnToFitMethod;
static
{
try
{
columnToFitMethod = TableViewSkin.class.getDeclaredMethod("resizeColumnToFitContent", TableColumn.class, int.class);
columnToFitMethod.setAccessible(true);
}
catch (NoSuchMethodException e) {e.printStackTrace();}
}
public static void fitColumns(TableView tableView) {
for (Object column : tableView.getColumns())
{
try { columnToFitMethod.invoke(tableView.getSkin(), column, -1); }
catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); }
}
}
}
public class Person {
private final StringProperty firstName;
private final StringProperty lastName;
public Person() {
this(null, null);
}
public Person(String firstName, String lastName) {
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public StringProperty firstNameProperty() {
return firstName;
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public StringProperty lastNameProperty() {
return lastName;
}
}
}
這裏是FXML文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="columnstofit.PersonTableController">
<TableView fx:id="tableView" layoutX="-39.0" layoutY="39.0" onKeyPressed="#fitColumns" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="firstNameColumn" editable="false" minWidth="-1.0" prefWidth="-1.0" text="First Name" />
<TableColumn fx:id="lastNameColumn" editable="false" minWidth="-1.0" prefWidth="-1.0" text="Last Name" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</AnchorPane>
與他相應的控制器:
package columnstofit;
import java.awt.AWTException;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
/**
* FXML Controller class
*/
public class PersonTableController {
// Reference to the main application.
private MainApp mainApp;
@FXML
private TableColumn<MainApp.Person, String> firstNameColumn;
@FXML
private TableColumn<MainApp.Person, String> lastNameColumn;
@FXML
private TableView tableView;
public PersonTableController() {
}
public void setMainApp(MainApp mainApp) throws AWTException {
this.mainApp = mainApp;
// Add observable list data to the table
tableView.setItems(mainApp.getPersonData());
try
{
fitColumns();
}
catch (Exception e) {
e.printStackTrace();
}
}
@FXML
private void initialize() throws AWTException {
// Initialize the person table with the two columns.
firstNameColumn.setCellValueFactory(
cellData -> cellData.getValue().firstNameProperty());
lastNameColumn.setCellValueFactory(
cellData -> cellData.getValue().lastNameProperty());
}
@FXML
private void fitColumns() {
MainApp.GUIUtil.fitColumns(tableView);
}
}
我的想法是調用該方法在渲染結束,所以我嘗試無線這個解決方案:Post render event in JavaFX,但沒有事情發生,如果是這樣。
適合我。 – DVarga
空指針異常是因爲此時尚未安裝皮膚。爲了實現這一點,至少需要將表格作爲場景的一部分,並且已經應用了CSS(可以使用'table.applyCSS()'強制執行);儘管如此,我仍然無法實現這一目標。 –
@DVarga對不起,我的問題並不完全清楚,我發佈的代碼沒有拋出excepion。我已糾正它。 –