2

I have defined a css stylesheet in my FXML file, which when opened with scenebuilder, it's displayed correctly, but when I run the program, it isn't. This confuses me...

This is what I'm working with:

├───bin
│   └───app
│           application.css
│           Fxml.fxml
│           Main.class
│
└───src
    └───app
            application.css
            Fxml.fxml
            Main.java

My Fxml.fxml file looks like this:

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

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


<VBox prefHeight="100.0" xmlns="http://javafx.com/javafx/8"
    xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <HBox prefHeight="20.0" />
        <TableView id="table" xmlns:fx="http://javafx.com/fxml">
            <columns>
                <TableColumn id="tablec_h_from" text="H_FROM" />
                <!-- other columns -->
            </columns>
        </TableView>
    </children>
    <stylesheets>
        <URL value="@application.css" />
    </stylesheets>
</VBox>

The application.css looks like this:

.table-column {
    -fx-pref-width: 55;
}

The Main.java:

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
            VBox root = null;
            try {
                root = (VBox)FXMLLoader.load(getClass().getResource("Fxml.fxml"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            Scene scene = new Scene(root);

            primaryStage.setScene(scene);
            primaryStage.show();

    }
}

So, as I said earlier, when I open my FXML file with scene builder, the table columns are of the proper width of 55px, but when I run the program, the table columns are of a default width of 80 px. The goal is of course to have the width of the columns 55px.

Do I have to import the css file in Main.java, even if I've defined it in the fxml file? And if so, how?

I'm using eclipse IDE, and JavaFX version 2.2.45-b18

Any help is appreciated.

6
  • I'm a little confused, how are you telling that the columns are 80 pix when you run the program? printlines? When I ran this code above, I got identical results in both my sceneBuilder and the output of the application. Commented Jan 23, 2014 at 15:12
  • I use a program which shows me my pointer location relative to the screen, then I do the math. I tried copying what I've written here in a new project, and I get the same result as I did before. What I'm interested in is whether the width you get is 55 or 80 px. If you would be so kind, could you please modify that css file to, let's say 200px, and then tell me if you see a difference? Commented Jan 23, 2014 at 15:49
  • Maybe I get that result because I use SceneBuilder 2.0 (Developer Preview)... Commented Jan 23, 2014 at 16:03
  • Ah, sceneBuilder 2.0 could indeed be the problem, I've been using 1.1 pretty exclusively since it's more stable (albeit still a terribly buggy program.). however, I am seeing some weird behaviour trying to make it more exact sizes, give me a sec to work it out and I'll post up an answer. Commented Jan 23, 2014 at 16:31
  • 1
    Which Java version are you using to run it? The -fx-pref-width property is only introduced in JavaFX 8, which I believe SB 2.0 uses. However if you build the FXML file with SB 2.0, then build and run the Java components under JDK 1.7/FX 2.2, the -fx-pref-width won't be recognized. Commented Jan 23, 2014 at 17:48

1 Answer 1

2

Alright, so the issue with this particular problem is the nature of TableColumn. It doesn't appear that TableColumn has any real binding with .css, and more than that, even if you access it via' it's css ID, the property -fx-pref-width doesn't seem to exist for it. Which is why you're not seeing any sort of change. Also, due to the potentially buggy nature of tableView in javafx at the moment, you MUST set a pref-width, or things can get a little strange. see This topic for an example of some of the strangeness.

Now, the solution to this is to create an fxml controller class and set the value of the width programmatically. I realize this might not be completely ideal for your solution, but it does seem to work just fine. for example:

my FXML.fxml:

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

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

<VBox prefHeight="100.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller = "filechooserexample.fxmlController" >
  <children>
    <HBox prefHeight="20.0" />
    <TableView id="table">
      <columns>
        <TableColumn id="tablec_h_from" maxWidth="5000.0" minWidth="10.0" prefWidth="50.0" text="H_FROM" fx:id="myTableColumn" />
        <!-- other columns -->
      </columns>
      <stylesheets>
        <URL value="@application.css" />
      </stylesheets>
    </TableView>
  </children>
  <stylesheets>
    <URL value="@application.css" />
  </stylesheets>
</VBox>

my main class is identical, and now for my controller:

fxmlController.java: 

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;

/**
 *
 * @author William
 */
public class fxmlController implements Initializable{

    @FXML TableColumn myTableColumn;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        myTableColumn.setPrefWidth(200);
    }

}

pardon the weird 'filechooserexample' package tag in the fxml controller setter field, I'm reusing a mostly blank project I had already setup and everything. So, the code to set the controller would be: `fx:controller = "packageName.NameOfJavaClassNoExtension"'

with that code I was able to successfully set the pref width. Now, you can use css to style your table column, you just can't use -fx-pref-width, since I'm fairly certain that property doesn't exist. If you want a good guess as to what's allowed see: caspian.cssleview-resize-after-been-moved Which is the default .css stylesheet for all of javafx. You'll likely find one or two properties outside of that, but not tons and tons that you'll see all the time.

Also worth noting, to properly access the table column, .table-column won't work, I don't think. You might have to add a style with getStyleClass().add("myCustomStyle");

which you can then access with .myCustomStyle

Good luck! I hope that helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Wouldn't using <TableColumn ... prefWidth="200" /> have exactly the same effect?
@James_D I was looking for a way to style all TableColumns, not just one. I did put only one tableColumn in the fxml I posted not to saturate the code with something I deemed irrelevant for the purpose of my problem. I was actually trying to learn how to implement css in JavaFX. Too bad I was trying to teach myself something with a wrong example. :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.