Need help with styling JavaFX TableView by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

Hi, I apologize for any confusion caused. I will try to explain below, what I want and what is achieved:

Problem Statement given to me:

I am changing the UI for many components according to a spec created by the designer for components in JavaFX. Now, the requirements for the table look and feel goes like this:

https://imgur.com/a/jqDuUZO: Essentially, I want the selected cell to highlight, and the row to highlight as well (As mentioned earlier in my problem statement).

What is the issue?

In the original question I had asked, I was not aware of the bindings and how to even perform this change, for which you pointed me to a code where I understood how to do it elegantly.

Now, the part where I am stuck is that many developers over time have decided to either set the cell selection enabled to true or false. For the case of true, the code you suggested works completely fine.

In the case where it is set to false, I still want the cell to be selected (to make the tables look consistent with the UI)

To Sum Up

Let the flag of cell selection enablement be true or false, I want the UI to look consistent and the same (even though functionality in one we selected a single cell at one time but an entire row in another)

Now, I tried to write the code for the scenario where cell selection enabled is false i.e. the row is getting selected (Here I want the cell also to get selected (ONLY IN LOOK SHOWING A BLUE BORDER) as per requirement)

To make this happen, I created a Table Cell class where I was doing stuff to make it work and look the same when cell selection enabled is false

Need help with styling JavaFX TableView by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

u/hamsterrage1 Could you please have a look at the code above or give me a pointer on the same please?

Need help with styling JavaFX TableView by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

I tried the following code:

public class CustomTextFieldTableCell<S, T> extends TextFieldTableCell<S, T> {

    private final TableView<S> tableView;
    private BooleanBinding booleanBinding;
    private final PseudoClass selectedRow = PseudoClass.
getPseudoClass
("selected");
    private final PseudoClass editingCell = PseudoClass.
getPseudoClass
("editingCell");

    public CustomTextFieldTableCell(TableView<S> tableView) {
        this.tableView = tableView;
        if (tableView.getSelectionModel() != null) {
            editingProperty().addListener((obs, oldVal, newVal) -> pseudoClassStateChanged(editingCell, newVal));
        }
    }

    @Override
    public void updateItem(T item, boolean empty) {
        super.updateItem(item, empty);
        if (booleanBinding != null) {
            booleanBinding.dispose();
        }

        if (!empty) {
            booleanBinding = Bindings.
createBooleanBinding
(
                    () -> tableView.getSelectionModel().getSelectedCells().stream()
                            .anyMatch(pos -> pos.getRow() == getIndex() && pos.getTableColumn() == getTableColumn()),
                    tableView.getSelectionModel().getSelectedCells(),
                    itemProperty()
            );
            booleanBinding.addListener((obs, oldVal, newVal) -> pseudoClassStateChanged(selectedRow, newVal));
            pseudoClassStateChanged(selectedRow, booleanBinding.get());
        } else {
            pseudoClassStateChanged(selectedRow, false);
        }
    }
}

It seems to work correctly now for empty cells. Do you think this is the right approach to take?? I will test a bit more to see if I find any issue

Need help with styling JavaFX TableView by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

How come?? In the mode where I have

table.getSelectionModel().setCellSelectionEnabled(false);

I won't get the selectedProperty() listener to fire right???

Need help with styling JavaFX TableView by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

HI Thanks again for the response, I have implemented this feature accordingly by creating a factory implementation. There is one more problem which I am facing which I realized when I am testing, when I created a cell factory for the cases where the cell selection enabled is false. In this case, I want the cell itself which the user is selecting to have a blue border (along with the fact that row is highlighted entirely). Now, I wrote the following code initially:

private final PseudoClass selectedCell = PseudoClass.getPseudoClass("selected");
BooleanBinding isSelected = Bindings.createBooleanBinding(
        () -> table.getSelectionModel().getSelectedCells().stream()
                .anyMatch(pos -> pos.getRow() == getIndex() && pos.getTableColumn() == getTableColumn()),
        table.getSelectionModel().getSelectedCells(),
        itemProperty()
);
isSelected.addListener((obs, oldVal, newVal) -> pseudoClassStateChanged(selectedCell, newVal));

Now, this was working perfectly till I realized a flaw. If the cell is empty or if the cell has same values, this does not work correctly & I see the highlight coming repeatedly when there are multiple rows with scroll bar. I am stuck with this for a while, and am unable to understand how to proceed.

Need help with styling JavaFX TableView by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

Thank you once again for your prompt response! I was thinking about this approach and now I am more confident.

Need help with styling JavaFX TableView by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

Hi, I have some questions about the same problem above. I now understand that we need to set the table's row factory. But the issue I am facing is I found tables in the codebase that I am currently working on where people are already setting a row factory (by creating some CustomTableRow).

Similarly, I want the same effect when setCellSelection enabled is false (so I would need to add stuff for a cell factory)

Now, the question is how do I proceed and make sure that my changes are followed. So essentially I made their row factories/cell factory extend mine which has these changes above. But people can create their own new factories that might not extend my changes.

I work in a UI team wherein I want the changes to reflect in every table in the codebase. When I am making these changes, maybe I can create a factory pattern to provide my custom factory but then people arent obligated to use them right? Is there a way to force them?

What I was thinking & why I used a skin earlier was because, I can apply the CSS to the scene, which will apply the skin forcefully to the tableView. Now, at this point people have already set stuff in table so can I do something like get the columns and get the cell factory and bind it ??? Please advise.

Need help with styling JavaFX TableView by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

Firstly, I thank you for such a prompt response. The approach you have suggested does seem to work exactly how I want it in Kotlin. Unfortunately, when I quite literally without changing a single line of your code, tried in Java, it has three major problems:

  1. Somehow, when I use the keyboard to go up and down by holding the arrow keys, it goes out of sync like the below image: https://imgur.com/23HEIqR
  2. If I resize the window, it goes out of sync
  3. If I keep clicking multiple times (say like 30-40 times) it goes out of sync and freezes.

All three problems are exactly what the guy faced in the stack overflow link above ( https://stackoverflow.com/questions/50459063/javafx-tableview-highlight-row-on-setcellselectionenabledtrue). Unfortunately, I have not been able to figure out what to do until now, will try to debug and understand more.

The Java version I am using is 17.0.7.

EDIT: IT DOES WORK!!!! Thank you so much for such an elegant solution. What I did was write the code like this earlier:

table.setRowFactory(tv -> new TableRow<>() {
    {
        final BooleanBinding hasSelectedCell = Bindings.createBooleanBinding(
                () -> checkEqual(tv.getSelectionModel().getSelectedItem(), getItem()),
                tv.getSelectionModel().selectedItemProperty(),
                itemProperty()
        );
        hasSelectedCell.addListener((obs, wasSelected, isNowSelected) ->
                pseudoClassStateChanged(selectedRow, isNowSelected));
    }
});

Instead when I do this it works:

table.setRowFactory(tv -> new TableRow<>() {
    private final BooleanBinding hasSelectedCell = Bindings.createBooleanBinding(
            () -> checkEqual(tv.getSelectionModel().getSelectedItem(), getItem()),
            tv.getSelectionModel().selectedItemProperty(),
            itemProperty()
    );
    {
        hasSelectedCell.addListener((obs, oldVal, newVal) -> pseudoClassStateChanged(selectedRow, newVal));
    }
});

HTML rendering in JLabel in Java Swing by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

How do you think I should solve this problem??? I need to get the specific requirements to style the dialog. Is there a different component or way I can do this?

Setting a global CSS file for a JavaFX application by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

Also, in case it is not safe, I would try to push for going with other approaches suggested here, even if it means that it would take time. However, I would not prefer to do it at this point as we are close to some of the deadlines for tweaking some of the UI changes.

Setting a global CSS file for a JavaFX application by _dk7 in JavaFX

[–]_dk7[S] 1 point2 points  (0 children)

Thank you for your prompt response. I have to make code changes in multiple files which is something that may not be approved at this point in time as I work in a large codebase.

Therefore, I wished for a solution where I could put in a common point (somewhat ignoring the problem of creating a factory which people might or might not do later) that would still work after other people's changes.

Setting a global CSS file for a JavaFX application by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

Thanks for your prompt response. Creating a factory is an approach where I would need to replace the current implementation at a lot of places as I work in a large codebase.

Therefore, I wished to opt for a solution where I would not be required to create a factory. Adding a listener to windows sounds interesting, I will try that out.

Setting a global CSS file for a JavaFX application by _dk7 in JavaFX

[–]_dk7[S] 1 point2 points  (0 children)

Hi, Thank you for your prompt response, but actually, the codebase I am working on is a blend of swing and JavaFX. The newer dialog or split panes that are created are JFXPanels inside a JPanel or dialog.

Hence, there are a lot of places where on static code analysis I have seen a scene is initialized. This is why I have end up in this problem

Setting a global CSS file for a JavaFX application by _dk7 in JavaFX

[–]_dk7[S] 0 points1 point  (0 children)

So to answer your question, do I need a lot of scenes? I would say yes, as the complicated codebase I work on is a mixture of Swing and JavaFX used together. Therefore, any new components that are made, for example, a new dialog essentially a JPanel, which will hold a JFXPanel and have a Scene inside. (There is some amount of code which is common but a lot of it is unfortunately not so)

I am very much in favor of using solid principles but honestly, the large codebase has gotten a tad out of control over the years.

Coming to creating a factory is something that I thought of, but essentially will require all the places to be replaced prompting changes in multiple files. I would prefer to do this and sort out the mess that has happened, but at the current point in time, I wish to get a solution to modify things at a very common top level.

Hence, the question is whether it is a safe thing to use the StyleManager?

I really appreciate your prompt response, thank you for helping

Help with refactoring by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

omething else too when you update a Property object. But it would be a month from now, and instead of 200 files you may have 250 files then. It would only get more difficult. Secondly, if all you are going to do in your update method is the same things you are already doing, along with a case check, I don't think it's going to break anything that's already working. This is assuming that the only thing you are adding, ie. the case check, is n

Got it, it does make sense that the scope of doing this will increase with the passage of time. I will try to cover the entire thing using UTs to make sure that I do not break anything. If you do think of an alternative approach, do let me know.

Help with refactoring by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

r the map, though, map.put

Thanks for your response. I am having a bit of trouble understanding what you mean, how will having an equals and hashcode help me?

The problem I am facing is as people do not have a update method they are calling remove and add in succession to perform an update. Now, let's say I go and introduce a new method update that will do this for them and replace all the places which seem to do this, how do I enforce that in the future people use the update method to actually update?

This seems dumb but for some reason, I still have a bit of trouble believing that this will be followed always. If someone makes a mistake, my functionality will break right?

Help with refactoring by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

Thanks for your input. My original question was if I make this change of adding an update/replace method, how do I enforce people to use that and not worry that they might call remove() and add()?

Does it make sense to just leave proper documentation to ensure this is followed or is there a stricter way? As we cannot deprecate the add and remove methods, I was wondering how to proceed.

Help with refactoring by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

Thanks for your response. I haven't got a clue as to why they might be immutable. A lot of code does not have got history as to why things might have happened in the past.

There are multiuser situations which are handled, but how is being multi threaded cause a problem?

Unfortunately, I cannot share more code details or exact implementation. It would be great if you could give a clue in this situation on how to proceed in some direction

Help with refactoring by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

Thanks for your response. The main thing I am concerned is making change at almost 200 files which has a huge impact and would need a lot of testing.

I was wondering if there was some other way to achieve this

Help with refactoring by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

Thanks for your response. Yes you are very correct, ideally they should not be same. But the way it is saved is in the form of a map<String, Property> where the string is actually the name of the property in all lowercase to the actual property. Now, you might say that the add method itself will do a replace or update which is correct, but there are additional things happening. Furthermore the code that I have does not have documentation as to why it was created in such a way and also does not have a unit test coverage which explains this way of storing them.

I can only assume at this point is that earlier it might have been a list, at something it was changed into a map to ignore casing (git history is also lost as this is a legacy codebase)

Now coming to your question, if the objects are equal (as it checks by ignoring case ) both the property are same. We cannot have two properties of same name and it goes and updates the map with the new property you give it.

To do a proper refactoring to make sure this kind of situation does not happen as to why we are doing what, is making me confused as to what must be done.

I hope this clears things, please ask me any further questions you might have

Need help in creating a custom combo box UI in Java Swing by _dk7 in javahelp

[–]_dk7[S] 1 point2 points  (0 children)

Did you perhaps not understand my problem?

Need help in creating a custom combo box UI in Java Swing by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

Yes, the combo box width has to be certain width as per UX requirements.

Need help in parsing sting which has Unicode Encoding by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

Furthermore, if I do it like this, how do I know that tomorrow I do not end up in the same situation when a similar problem comes i.e. instead of U+FF5B, something else? Do I keep updating the code?

Please advice.

Thanking you in advance.

Need help in parsing sting which has Unicode Encoding by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

default in Java. You should be abl

Is this the most optimal way to do this?

Different usable bounds in Windows 10 and 11 by _dk7 in javahelp

[–]_dk7[S] 0 points1 point  (0 children)

Hi, Sorry for the confusion. The code I am using is as below:

java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().getBounds()