Ich möchte einige TableView
Spalten Größe ändern, da eine Methode, um dies zu erreichen fehlt von javafx ich habe es geschafft, eine Lösung in MainApp.GUIUtil.fitColumns(TableView tableView)
ausgesetzt zu finden.
Mein Problem ist: Diese Lösung funktioniert gut, wenn sie von einer Benutzeraktion aufgerufen wird, aber ich kann keine Methode finden, diese Methode beim Start auszuführen, bevor Benutzereingriffe vorgenommen werden.
Ich möchte die Tabelle mit der Spalte als soos wie die Tabelle dargestellt dargestellt.
Wie Sie sehen können ich die Exception
abfangen, die mir Kopfweh (PersonTableController.setMainApp Zeile 32) verursacht, drucken Sie den StackTrace und lassen Sie dann das Programm weiterhin beweisen, dass die Fit-Methode funktioniert, nachdem die Kontrolle an den Benutzer gegeben wurde.
Wie kann ich die Spaltengrößen per Code anpassen, sobald die Tabellenansicht angezeigt wird?JavaFX TableView Spalten passen Inhalt
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
Hier ist mein Code:
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;
}
}
}
Und hier ist die FXML Datei:
<?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>
Mit seinem jeweiligen Controller:
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);
}
}
Meine Idee zu nennen war diese Methode am Ende des Renderings, also versuchte ich wi th diese Lösung: Post render event in JavaFX, aber nichts passiert, wenn ich es mache.
Funktioniert gut für mich. – DVarga
Die Nullzeiger-Ausnahme ist, weil die Skin zu diesem Zeitpunkt nicht installiert wurde. Um das zu erreichen, müssen Sie mindestens die Tabelle als Teil einer Szene verwenden und CSS anwenden (was Sie mit 'table.applyCSS()' erzwingen können); Ich kann es immer noch nicht zur Arbeit bringen, auch nicht mit dem. –
@DVarga Es tut mir leid, meine Frage war nicht ganz klar, der Code, den ich gepostet habe, warf die Ausnahme nicht. Ich habe es korrigiert. –