Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using custom Controls in fxml

Let's say I have subclassed the default TableView<T> class provided by javafx and created a class PersonTableView extends TableView<Person>. That subclass exists in java code and does not use fxml at all. It defines and encapsulates behaviour that I need specifically for my Person object.

Now I want to use an instance of my custom class inside of an fxml file, just like I would use all the default controls. And that exactly is my problem, I don't know how I can do that, or if this is even a good / common design decision.

I want to encapsulate the behaviour for my specific TableView inside its own class, but the layout should be defined in fxml as it has nothing to do with logic, it is only cosmetics.

I imagine a kind of syntax and functionality like it can be found in WPF from .NET, where you can use your custom classes in markup like any other control, because xaml and c# are more tightly coupled than java and fxml.

From my current Point of View, what I described cannot be done and I would instead end up using only a very small amount of fxml and a lot more code, even for the parts that are just layout. For Example I do not want to use code like this:

 AnchorPane.setRightAnchor(customControl, 65.0);

because I believe that it is a good Idea to have this defined inside my fxml.

So my question is either, how do I implement what was just described above; or, if that is uncommon, what is the common, "best-practice" way to get similar functionality to what I just described?

like image 344
quantumbyte Avatar asked Mar 19 '23 23:03

quantumbyte


1 Answers

Is this what you were looking for? This works fine for me.

package numerictextfield;

import java.util.regex.Pattern;

import javafx.scene.control.IndexRange;
import javafx.scene.control.TextField;

public class NumericTextField extends TextField {

    private final Pattern intPattern = Pattern.compile("[0-9]*");

    public NumericTextField(String text) {
        super(text);
    }
    public NumericTextField() {
        super();
        this.insertText(0, "");
        this.replaceSelection("");
        this.replaceText(new IndexRange(0, 0), "");
        this.replaceText(0, 0, "");
    }

    @Override
    public void insertText(int index, String text) {
        if (intPattern.matcher(text).matches()) {
            super.insertText(0, text);
        }
    }

    @Override
    public void replaceSelection(String text) {
        if (intPattern.matcher(text).matches()) {
            super.replaceSelection(text);
        }
    }

    @Override
    public void replaceText(IndexRange range, String text) {
        if (intPattern.matcher(text).matches()) {
            super.replaceText(range, text);
        }
    }

    @Override
    public void replaceText(int start, int end, String text) {
        if (intPattern.matcher(text).matches()) {
            super.replaceText(start, end, text);
        }
    }

}

and then

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

<?import javafx.scene.layout.AnchorPane?>
<?import numerictextfield.NumericTextField?>

<AnchorPane xmlns:fx="http://javafx.com/fxml" >
    <NumericTextField text="12345" >
        <AnchorPane.rightAnchor>65.0</AnchorPane.rightAnchor>
    </NumericTextField>
</AnchorPane>
like image 75
James_D Avatar answered Apr 02 '23 02:04

James_D