1. ControlsFX
  2. ControlsFX
  3. ControlsFX
  4. Issues

Issues

Issue #766 open

SpreadsheetView internal stylesheet is hard to override

Robert Ross
created an issue

SpreadSheetView does not abide by the parent application/scene stylesheet. Instead, it is overridden by SpreadSheetGridView and CellView's use of hard-coded internal resource stylesheet. There is also no way to override this by changing the user agent style sheet directly. Instead, I must intentionally and specifically override every style selector used in the hard-coded stylesheet.

Comments (16)

  1. Robert Ross reporter

    That's exactly the problem. You force an internal style sheet that cannot be replaced. It is hard coded, completely overrides modena.css and is private with no ability to replace it. You can provide a default style sheet but need to provide a means of setting a different one. As it stands, I had to use "!important" on some of my own CSS to force an override.

    I've forked your code and will take a look to see if I can provide a quick fix as a pull request.

  2. Robert Ross reporter

    Another thing that should change is hard coded colors should be replaced with direct references to parent style colors (-fx-control-inner-border, -fx-accent, etc.) or derivation methods (derive() and ladder()) so that your style sheet adapts dynamically to the rest of the application's style.

  3. Samir Hadzic

    The SpreadsheetView is using a TableView (SpreadsheetGridView), thus the getUserAgentStylesheet() of that TableView is not overridable. Maybe we could add a getUserAgentStylesheet() in the SpreadsheetView itself, and make the SpreadsheetGridView use it? Therefore, overriding this will remove the internal stylesheet and yours will be fully used.

  4. Robert Ross reporter

    The problem is that you're using hard coded colors ("white", "black", etc.) in your own style sheet. TableView's stylesheet already uses the properly derived colors. You're overriding that and replacing it with hard coded actual colors so it no longer responds when the parent CSS changes something like "-fx-background" or "-fx-accent".

  5. Robert Ross reporter

    I don't even really know how to reply to this. As far as I knew, ControlsFX is a library for use by others and not a set of widgets specifically designed for you. If you don't want the accent color to be yellow, then change your style sheet in your application when you use it. Don't force your color preferences on the whole world. Your use of white and blue specifically and completely contradicts our own usage requirements.

  6. Jonathan Giles

    Robert - please keep this civil. You're entitled to your opinion but please express it in a more positive way. Samir is the sole developer on the SpreadsheetView and deserves considerable respect and commendation for his efforts on this, as well as his willingness to both provide this to the community free-of-charge, and to continue to support it going forward.

    If you work together in a positive manner, good things can come out of it. If you're negative, we risk losing not only your involvement, but also Samir's. My hope is that the two of you can discuss this in a more productive manner and come to an approach that enables what you both want, and furthers the ControlsFX project.

  7. Robert Ross reporter

    I am trying to collaborate. If you look at the conversation history, I've offered several possible solutions as well as offered to fork and do a pull request. The response has been pretty much "that's the way I want it". I'm not sure what else I'm supposed to do here. That willingness to work together has to go both ways.

  8. Jonathan Giles

    I agree. I think a PR that allows for clarity of your goals is the best approach here. Then the technical merits can be discussed and the right way forward decided. Personally, I would like to see whatever can be tweaked via CSS to be possible. I believe overriding getUserAgentStylesheet() is the right way forward. TableView (and all UI controls in JavaFX) do not override this method, as they are styled by the default Modena user agent style sheet.

  9. Samir Hadzic

    Thanks Jonathan Giles , much appreciated.

    Robert, please be sure that I'm taking your issue seriously and I'm willing to find a solution.

    I've been using the SpreadsheetView for 3 years now in a professional application, and I've been able to completely customize the SpreadsheetView without any problem.

    Now, from what I understood, you want us to customize the look of the SpreadsheetView only with fx-accent and other modena selectors. By doing that, we will provide a SpreadsheetView that will use derived color, and simply modifying that derived color in your application stylesheet will impact the whole application. I think that's what you want.

    If we do that, it also means that the SpreadsheetView will look exactly the same as the TableView. But that's not what I want. The SpreadsheetView is not a JavaFX component. It's another component and I want the SpreadsheetView to be shipped with modern colors. Thus I just can't use only derived colors. If I'm using only derived color, I basically only have grey and light blue to use! If you look around in ControlsFX, you will see that people have been using hard-coded colors in their internal css. (maskerpane.css, statusbar.css, taskprogressview.css, segmentedbar.css etc). I've seen the same in JFXtras and others components.

    So I believe I have synthesized your point of view and mine. Correct me if I'm wrong. Now we must find a solution that could be good for both of us. I do believe that tweaking around getUserAgentStylesheet() will offer the possibility for me to provide a default css. And for you to override it, get rid of my css completely and provide yours without any hassle.

    EDIT: I've tried to do that and it seems to work. In SpreadsheetGridView :

     @Override
        public String getUserAgentStylesheet() {
           return handle.getView().getUserAgentStylesheet();
        }
    

    and in SpreadsheetView :

     /*
         * cache the stylesheet as lookup takes time and the getUserAgentStylesheet is called repeatedly
         */
        private String stylesheet;
    
         @Override
        public String getUserAgentStylesheet() {
            /*
             * For more information please see RT-40658
             */
            if (stylesheet == null) {
                stylesheet = SpreadsheetView.class.getResource("spreadsheet.css") //$NON-NLS-1$
                        .toExternalForm();
            }
    
            return stylesheet;
        }
    

    By doing that, you can override it when creating a SpreadsheetView and the default css will not be loaded giving you full power to tweak the way you want. Of course, if you have a better solution, it will be much appreciated. I am absolutely not claiming that what we are doing in ControlsFX is the perfect way. I've just been copying what has been done before and apparently what have worked for others during the past 4 years.

  10. Robert Ross reporter

    I think your stylesheet could still be done in a way that would adapt better to other situations. For example, simply change "-fx-base" on a parent application and see how SpreadsheetView works in that situation. You'll see the problem immediately. At the very least, your solution above would allow replacing the stylesheet which would work. But, ultimately, your stylesheet can still be adjusted to be more dynamic and useful without a full override.

  11. Samir Hadzic

    I totally agree with you that it would be great to find a way for the stylesheet to adapt better to other situation.

    If you change -fx-base on the parent application, clearly the SpreadsheetView won't follow. What I don't understand is that you seem to imply that I've been doing something completely strange. But if you look around and see some custom components made by people, everyone has been doing like me.

    In ControlsFX, we've been styling our controls like that.

    In JFXtras, they have styled there controls like that : https://github.com/JFXtras/jfxtras-styles/blob/master/src/jmetro/JMetroDarkTheme.css

    In JFoenix , too : https://github.com/jfoenixadmin/JFoenix/blob/master/jfoenix/src/main/resources/css/jfoenix-design.css

    In all controls done by Gerrit Grunwald, he always add custom style and color everywhere:

    https://github.com/HanSolo/Medusa/blob/master/src/main/resources/eu/hansolo/medusa/framed-gauge.css

    https://github.com/HanSolo/Enzo/blob/master/src/main/resources/eu/hansolo/enzo/clock/clock.css

    https://github.com/HanSolo/tilesfx/blob/master/src/main/resources/eu/hansolo/tilesfx/tilesfx.css

    So basically, if you use any controls made by someone else that JavaFX, and if you change -fx-base on the parent application, the SpreadsheetView and all other custom components will not follow. I'm not saying that this is a good way of doing it. I'm saying that everyone has been doing that, so that's the reason I've been doing that.

    You mention in the comment you deleted that Oracle is recommending against it. Could you paste the link here so that I could see these recommendations. This is the point of open source development, everyone can contribute in order to always improve things. I am no expert. I'm just following what has been done and is currently done by others.

    My answers are not always "this is what I want and it is not negotiable". If someone wants the SpreadsheetView to look like the TableView, he can provide a custom stylesheet and do it. But your point is valid. Maybe we can try to go further and provide by default two stylesheets. One using -fx-base and other modena selectors, so that the SpreadsheetView will be fully responsive. And another one with custom colors and fancy stuff. Then at initialisation, we could choose which one we want.

    Would that not be the perfect way to conciliate your needs for a responsive SpreadsheetView and my needs for a colorful and fancy SpreadsheetView ?

    Nevertheless, as Jonathan advises, the best is to provide a pull request so that everyone will be able to review it and discuss about it.

  12. Robert Ross reporter

    As long as I can provide a stylesheet to override it, I don't mind updating styles. For better or worse, our application is using a custom stylesheet already anyway. What I'm saying is that the default widget stylesheet is VERY specific in ways that become difficult to override because they don't allow cascading to happen without explicitly redefining most of the styles in the default widget's stylesheet. Change it requires some knowledge about how CSS styles cascade which is admittedly a huge PITA. Coming from a web development background, I can see why others are not abiding by those types of design best practices. I'll try to find that document I mentioned and post. When I have some free cycles, I will work up a potential solution and do a pull request for you to review.

  13. Log in to comment