Re: Binding properties to constant values

2024-02-04 Thread Scott Palmer
I think we could (easily?) introduce a new layer for style sheets that sits
at the right spot in the precedence order.  The issue that makes things
difficult is that the scene can have only one user agent stylesheet, so it
is a pain to layer on changes to the defaults with the desired precedence.
If we had a list of style sheets at that level then we could simply use it
instead of scene.getStylesheets().  It would be a backwards compatible
change so developers could add or remove style sheets at the precedence
level that makes sense for them.

I may be over-simplifying, as it has been a while since I went down the
rabbit hole of trying to get JavaFX css to do what I wanted.  But I see a
disconnect between bindings overriding the stylesheet and setProperty not.
To me setProperty should be effectively like binding the property to a
constant - they are both cases of explicitly setting the property to a
value from code. It came as a mild shock to discover that things weren't
working as I expected them to, because things were designed not to work as
I expected them to :-).  It was a "why would you do that to us?" moment.

Scott

On Thu, Feb 1, 2024 at 12:05 PM Nir Lisker  wrote:

> Hi John,
>
> If the issues with StyleOrigin are not as problematic as I presented, it
> comes out to the behavioral flexibility we have. Can we change the
> precedence order at this point? Do users rely on it or are surprised by it
> (I see the latter, but those who think it works correctly are not going to
> say that)?
> Perhaps Kevin can weigh in.
>
> The question of how to do it is simpler, and can be done with or without
> breaking changes to StyleOrigin.
>
> On Thu, Feb 1, 2024 at 2:27 AM John Hendrikx 
> wrote:
>
>> Hi Nir,
>>
>> On 31/01/2024 22:36, Nir Lisker wrote:
>> >
>> > I would wait with the ramifications of setting competing values from
>> > different origins until the question of precedence is answered.
>> > Perhaps emitting warnings is better, though I can see some scenarios
>> > in which they will be annoying.
>> >
>> > The way I see the order:
>> > 1. Setting from code should always take precedence (including the
>> > current bindings over setter order of course).
>> > 2. INLINE origin (via setStyle).
>> > 3. Stylesheets according to their StyleOrigin as specified by the
>> > non-javafx css specifications [3]: AUTHOR > USER > USER_AGENT (see
>> > below for INLINE).
>> >
>> > 2 and 3 are already (more or less) specified in JavaFX's css as far as
>> > I can see. However, 1 is not css, hence I don't think StyleOrigin
>> > should be applicable here even. Even more, 2 isn't really css either,
>> > it mimics html tags and shouldn't count as a css StyleOrigin in my
>> > opinion.
>> StyleOrigin is more of an internal thing that got exposed, so I wouldn't
>> worry too much about what is CSS and what isn't.  I agree that the above
>> order would make more sense. I suspect the reasoning why it wasn't done
>> is that setters are getting called to set up defaults, which if they by
>> default override all, would conflict with style sheets set by the user.
>> > Note also that a Stylesheet can set its origin [4], even to INLINE, so
>> > it takes precedence over java property setters and conflicts with
>> > 'setStyle' "real" INLINE. I'm not sure if this is a bug because the
>> > javafx css specs say that "Inline styles are specified via the Node
>> > setStyle AP".
>>
>> The CSS API is weird. It has many seemingly useful and public bits, but
>> they are isolated from the rest of FX.
>>
>> Take StyleSheet for example.  You can convert them (using File to File)
>> from regular to binary, then load a binary file and get a StyleSheet
>> reference with a public API.  You can then change its origin.  However,
>> it stops there.  You can't feed such a modified StyleSheet to FX via any
>> public API.
>>
>> It almost looks like a lot of the CSS public API is there for a possibly
>> previously integrated Scene Builder type application, which was later
>> split off.
>>
>> >
>> > So, if I were to able to do anything I wanted, I would have restricted
>> > Stylesheets to the options in 3, remove INLINE from a public
>> > perspective and apply it only behind the scenes to 'setStyle' calls,
>> > and stop treating java settings in the css hierarchy (which means
>> > removing the USER StyleOrigin from them). Obviously that breaks a lot
>> > of code, but this behavior would be my general goal. As for how to
>> > represent it, maybe a constant can be added to StyleOrigin to
>> > represent java code settings, but that's not a real css origin. I
>> > guess we could call INLINE and the hypothetical JAVA constants
>> > "pseudo-origins", because they don't apply to stylesheets, and are
>> > only used internally. Or just don't check StyleOrigin when the value
>> > is set from java. There are probably more ways.
>>
>> StyleOrigin really is only there for the CSS engine to distinguish if it
>> can replace a value or not with something else depending on 

Re: Binding properties to constant values

2024-01-30 Thread Scott Palmer
IMO the current CSS priorities are wrong. A value set from code should be 
adjacent to an in-line style in terms of precedence.  They are both ways of 
saying saying “this particular instance should have this value”

Scott

> On Jan 30, 2024, at 8:31 AM, John Hendrikx  wrote:
> 
> Hi Michael,
> 
> I think we first need to decide what the correct behavior is for CSS 
> properties, as the "bind" solution IMHO is a bug.
> 
> The StyleOrigin enum encodes the relative priorities of styles and user set 
> values, but it is incomplete and not fully enforced.  There is (currently) 
> actually a 5th level (next to USER_AGENT, USER, AUTHOR and INLINE) where it 
> checks the binding state (it has no choice, as it will get an exception 
> otherwise, or has to call `unbind` first).  Whether that's a bug or should 
> more formally be accepted as the correct behavior remains to be seen.  Also 
> the AUTHOR and INLINE levels are only best effort, as setting a value in code 
> (USER level) will override AUTHOR and INLINE values **temporarily** until the 
> next CSS pass...
> 
> So first questions to answer IMHO are:
> 
> 1) Does it make sense to treat values set in code (which IMHO should always 
> be the last word on anything) as less important than values from AUTHOR and 
> INLINE styles?  This is specified in the CSS document, but not fully enforced.
> 
> 2) Should bound values (which IMHO fall under "values set from code") be able 
> to override AUTHOR and INLINE styles?  Why are they being treated differently 
> at all?  Which StyleOrigin level do they fall under?  "USER"?  A 5th level 
> with higher priority than "INLINE"?
> 
> 3) Should properties which hold an AUTHOR or INLINE value reject calls to 
> `setValue` (to make it clear they are temporary and that your code is 
> probably wrong)?  This currently is not in line with the CSS document.  Note 
> that this will be slightly annoying for the CSS engine as it may not be able 
> to "reset" such values as easily as before (which is probably the reason it 
> currently works the way it does, but that's no excuse IMHO).
> 
> As for your potential solution, if you introduce a constant binding system 
> (to solve a CSS problem), does that make sense for properties as a whole?  
> What can be achieved with `bindConstant` that can't be done with `setValue`?  
> `bindConstant` will become the "setter" that always works (never throws an 
> exception...), but probably at a higher cost than using `setValue`.  Would it 
> not make more sense to only have such methods on the Styleable properties 
> (which can then also signal this by using an even higher precedence 
> StyleOrigin instead of relying on bound/unbound) once there is agreement on 
> the above questions?
> 
> In other words, I'd look more in the direction of providing users with a 
> better "setter" only for CSS properties, that also uses a different 
> StyleOrigin, and to bring both binding and setting in line with the CSS 
> document's specification (or alternatively, to change that specification).  
> This means that the normal setter provided next to the property method (ie. 
> setXXX) would have to default to some standard behavior, while a more 
> specific setter provided on the property itself can have an overriding 
> behavior, something like:
> 
> setX() -> calls cssProperty.setValue()
> cssProperty.setValue() -> sets values if not originated from an AUTHOR or 
> INLINE stylesheet, otherwise throws exception (as if bound)
> cssProperty.forceValue() -> sets value unconditionally, setting 
> StyleOrigin to some new to introduce 5th level 
> (StyleOrigin.FORCED/DEVELOPER/DEBUG/CONSTANT/FINAL)
> 
> Binding can then either be categorized as the StyleOrigin.FORCED or if it is 
> StyleOrigin.USER, the CSS engine is free to **unbind** if the need arises.
> 
> --John
> 
> 
>> On 30/01/2024 09:25, Michael Strauß wrote:
>> Hi everyone,
>> 
>> I'm interested in hearing your thoughts on the following proposal,
>> which could increase the expressiveness of the JavaFX Property API:
>> 
>> Problem
>> ---
>> The JavaFX CSS system applies the following order of precedence to
>> determine the value of a styleable property (in ascending
>> specificity):
>> 1. user-agent stylesheets
>> 2. values set from code
>> 3. Scene stylesheets
>> 4. Parent stylesheets
>> 5. inline styles
>> 
>> While this system works quite well in general, applications sometimes
>> need to override individual property values from code. However, this
>> doesn't work reliably in the presence of Scene or Parent stylesheets.
>> There are two usual workarounds to solve this problem:
>> 
>> A) Use an inline style instead of setting the property value directly.
>> 
>> This is obviously not a good solution, as you'll lose the strong
>> typing afforded by the Java language. Additionally, the value must be
>> a true constant, it can't be an expression or the result of a
>> computation.
>> 
>> B) Create an `ObservableValue` instance that holds the 

Re: Converting a Color object to its string representation

2023-12-11 Thread Scott Palmer
I agree. I was going to write pretty much this exact email, but you beat me to 
it.
I was implementing some user-configurable colour customizations in an 
application and needed to do it with style sheets, along with something that 
reads colours along the lines of what the new platform preferences API does. 
I make a base64 data URL from a dynamically generated style sheet to avoid 
writing temp CSS files to style the app. 
I also needed to do this to work around the style sheet having higher priority 
than programmatically set colours as per my misunderstanding in 
https://bugs.openjdk.org/browse/JDK-8317434
So I see value in having Color implement something like this.

Scott

> On Dec 11, 2023, at 4:19 PM, Eran Leshem  wrote:
> 
> Thank you for your responses.
> 
> Given that the framework requires colors in string format in its style APIs, 
> I think it should provide some way to convert colors to strings as expected 
> by these APIs. Otherwise, clients are forced to implement this bridging logic 
> on their own, due to a framework gap.
> 
> And given that Color already parses these string representations, I think it 
> makes sense for it to provide the inverse conversion.
> 
> Eran
> 
> -Original Message-
> From: openjfx-dev [mailto:openjfx-dev-r...@openjdk.org] On Behalf Of John 
> Hendrikx
> Sent: Saturday, December 09, 2023 11:35 PM
> To: openjfx-dev@openjdk.org
> Subject: Re: Converting a Color object to its string representation
> 
> I think this is too niche to have Color provide.
> 
> Just make a utility method for whatever format you desire, instead of
> making Color responsible for half a dozen ways of formatting colors, and
> then probably still missing some format that someone needs.
> 
> Ticket should be closed as won't fix.
> 
> --John
> 
>> On 09/12/2023 22:06, Michael Strauß wrote:
>> I obviously meant to write withPrefix("#"), not withDelimiter("#")...
>> 
>>> On Sat, Dec 9, 2023 at 9:57 PM Michael Strauß  
>>> wrote:
>>> How would HexFormat work with Color, other than using an extremely
>>> unwieldy syntax?
>>> 
>>> String formatted = HexFormat.of()
>>> .withDelimiter("#")
>>> .formatHex(new byte[] {
>>> (byte)(color.getRed() * 255.0f),
>>> (byte)(color.getGreen() * 255.0f),
>>> (byte)(color.getBlue() * 255.0f),
>>> (byte)(color.getOpacity() * 255.0f)
>>> });
>>> 
>>> 
>>> 
>>> On Sat, Dec 9, 2023 at 9:40 PM David Alayachew  
>>> wrote:
 Apologies - java.util.HexFormat
 
 That's what I get for firing from the hip, then looking afterwards.
> 


Re: eclipse warnings

2023-12-05 Thread Scott Palmer
I was about to say the same. I wish it did, and applied the rule that null 
never matches.

You could probably trick it with an ugly cast though. 

((Object)getScene()) instanceof Scene s
Maybe?

Scott

> On Dec 5, 2023, at 3:43 PM, Michael Strauß  wrote:
> 
> Unfortunately, this doesn't work. The Java language doesn't allow a
> pattern to be the same type as the expression.
> 
> 
>> On Tue, Dec 5, 2023 at 1:27 PM John Hendrikx  wrote:
>> 
>> When this runs on the FX thread it has to be safe, but it's not very nice.
>> 
>> These days you can do these kind of null chain checks like this:
>> 
>>   if (getScene() instanceof Scene s && s.getWindow() instanceof
>> Window w && w.isShowing()) {
>> 
>>   }
>> 
>> --John


Re: My JavaFX Christmas Wishlist

2023-11-16 Thread Scott Palmer

> On Nov 15, 2023, at 9:32 AM, Nir Lisker  wrote:
> 
> 
>> removal of AWT
> 
> Isn't that *a lot* of work? All the image IO is AWT, no? 

It was a mistake to tie ImageIO to GUI framework image classes. The image 
raster should be returned in a generic wrapper around a byte array or 
ByteBuffer from the various codecs. 
The UI layer should bridge it from there. A WriteableRaster or BufferImage just 
needs to wrap those bytes with the dimensions and pixel format details.
But I bet it isn’t that far off and wouldn’t be that much work. It’s a question 
of priorities though. 

I still think the AWT ties need to be cut.

I want native tray support, dock icon overlays/badges & progress feedback. 
Webcam support would be nice too, for video chat apps, security camera UIs, 
image recognition, barcode scanning, etc. 

Scott





Re: [External] : Re: Proposal: Bump the minimum version of macOS for which we target JavaFX

2023-05-11 Thread Scott Palmer
I think Option 1 makes the most sense. Specially since JDK 21 is LTS. Do we 
want to be stuck with OS 10.x through the entire LTS period?

Scott

> On May 11, 2023, at 3:23 PM, Kevin Rushforth  
> wrote:
> 
> Thanks for the additional info. I had meant to look it up and add it prior 
> to sending it out, but hit "send" too soon.
> 
> My preference would be Option 1: change the minimum to macOS 11.0 in JavaFX 
> 21.
> 
> If there are some significant concerns over doing that, we could go with 
> Option 2 as a fallback: change the minimum to 10.14 in 21 and to 11.0 in 22.
> 
> -- Kevin
> 
> 
> On 5/11/2023 12:00 PM, Martin Fox wrote:
>>> My preference is to change the minimum version for Mac / x64 to be macOS 
>>> 11.0, matching both the currently oldest version of macOS supported by 
>>> Apple, and also unifying the minimum for the two chip architectures.
>> So no one else has to look this up:
>> 
>> The last security update for macOS 10.12 was in September of 2019. It was 
>> released in 2016.
>> The last security update for macOS 10.14 was in July of 2021. It was 
>> released in 2018.
>> 
>> macOS 11.0 was released in November of 2020. Support is likely to end this 
>> year.
>> 
>> 11.0 could be installed on MacBooks from 2013 and desktops from 2014 (with 
>> some exceptions). If there’s a Mac out there that just can’t upgrade to 11.0 
>> that machine is getting a little long in the tooth. FWIW I’m using an iMac 
>> from late 2017 and running the latest OS just fine.
>> 
>> I think ditching 10.x is the right move.
>> 
>> Martin


Re: CSS styling of Shape in TextFlow causes flickering

2023-02-21 Thread Scott Palmer
Even if I always kept the TextFlow as a graphic on the cells, I would need to change its children to show the correct shape and text. So there would normally be changes to the children when updateItem is called, just one level deeper in the node hierarchy.It makes sense that in most circumstances you shouldn’t be adding or removing nodes during layout, but if updateItem is called during layout it would have to be an exception. As you note, updating the graphic is normal and clearly changes the children.I was surprised that I had to call applyCss() one level higher in the node hierarchy than where the relevant CSS actually was, but I’m okay with that as a workaround for now. I don’t expect it to be a performance issue.ScottOn Feb 22, 2023, at 1:03 AM, John Hendrikx  wrote:
  

  
  
It's a bit hard to say if this is a bug or not.
I think this happens any time when children are added during
  layout. Most controls will avoid doing this, but when Cells are
  involved, there is another layer of indirection. I think the View
  classes manage their cells during layout, and since Cells can be
  newly created or the Cells are modified in ways that would trigger
  a child to be added/removed, then this effectively is changing the
  children list during layout.
For example, Labels, when you add a graphic, immediately update
  their children list to include the graphic. Normally, calling
  `setGraphic` is not done by you during layout but in an event
  listener or during creation of the control.  However, when it is
  called in `Cell#updateItem` then layout is running, and the Label
  will change its children list when it notices the graphic
  changed.  This new child won't have CSS applied yet.
I couldn't find documentation that says you shouldn't add/remove
  children during layout, but I'm pretty sure this is standard
  practice.
The View controls may or may not be creating cells during layout,
  but they are almost certain to call `updateItem` on cells during
  layout. I'm not certain if this could be avoided in a similar
  fashion as I've done for my own ListView skin (using the pulse
  listener); if it can be, then this could be a bug fix.  If it
  can't, then I think `Cell#updateItem` should mention that the call
  should not modify the children list directly or indirectly.
As I pointed out in my other reply, you may be able to set a
  dummy graphic on all cells, and just hide it when it is not
  needed.

--John

On 22/02/2023 02:26, Scott Palmer wrote:

  
  
Well
  I managed to work around it by placing the applyCss() call on
  the Cell itself, rather than the Shape node that I was
  styling.  I'm still not sure if I'm doing something wrong, if
  this is just how it's done and the applyCss() call is the
  correct thing to do for this case, or if this should be
  considered a bug.


Scott
  
  
  
On Tue, Feb 21, 2023 at 7:37
  PM Scott Palmer <swpal...@gmail.com>
  wrote:


  
I agree, this seems
  like it could be the same issue.  Could you give me a
  little more context as to how this code works? I'm not
  implementing my own skin (maybe I should, I've never tried
  that before).  Is this something I can trigger without a
  custom skin?


Regards,


Scott.
  
  
  
On Tue, Feb 21, 2023 at
  12:01 PM John Hendrikx <john.hendr...@gmail.com>
  wrote:


  
I've run into something similar, maybe even the same
  issue.
My issue was that modifying the list of cell children
  (in a Skin for ListView) caused a 1 frame white
  flicker (my application is black, so it was annoying)
  because no CSS was applied yet to those newly added
  children.  This occured when the ListView first only
  had a few children and wasn't completely filled, and
  then switching to a list which required more cells to
  be created. I couldn't find a "correct" place to
  modify the list of children that would avoid the
  flicker (layoutChildren/computePrefWidth are places I
  tried).
In the end I did this, and added a comment to remind
  me why the hack was there:
    /*
   * A pre-layout pulse listener is added to the
  current Scene to manage the
   * cells before the CSS p

Re: CSS styling of Shape in TextFlow causes flickering

2023-02-21 Thread Scott Palmer
Well I managed to work around it by placing the applyCss() call on the Cell
itself, rather than the Shape node that I was styling.  I'm still not sure
if I'm doing something wrong, if this is just how it's done and the
applyCss() call is the correct thing to do for this case, or if this should
be considered a bug.

Scott

On Tue, Feb 21, 2023 at 7:37 PM Scott Palmer  wrote:

> I agree, this seems like it could be the same issue.  Could you give me a
> little more context as to how this code works? I'm not implementing my own
> skin (maybe I should, I've never tried that before).  Is this something I
> can trigger without a custom skin?
>
> Regards,
>
> Scott.
>
> On Tue, Feb 21, 2023 at 12:01 PM John Hendrikx 
> wrote:
>
>> I've run into something similar, maybe even the same issue.
>>
>> My issue was that modifying the list of cell children (in a Skin for
>> ListView) caused a 1 frame white flicker (my application is black, so it
>> was annoying) because no CSS was applied yet to those newly added
>> children.  This occured when the ListView first only had a few children and
>> wasn't completely filled, and then switching to a list which required more
>> cells to be created. I couldn't find a "correct" place to modify the list
>> of children that would avoid the flicker (layoutChildren/computePrefWidth
>> are places I tried).
>>
>> In the end I did this, and added a comment to remind me why the hack was
>> there:
>>
>> /*
>>  * A pre-layout pulse listener is added to the current Scene to
>> manage the
>>  * cells before the CSS pass occurs (this could also be done with an
>> AnimationTimer).
>>  *
>>  * If cells are not managed before the CSS pass, new cells will be
>> rendered for
>>  * one frame without CSS applied. This results in a visual artifact
>> (a white flash
>>  * for example if the background is supposed to be dark, while white
>> is the default
>>  * color without any CSS applied).
>>  */
>> private final Runnable pulseListener = () -> {
>>   int lines = vertical ? visibleColumns.get() : visibleRows.get();
>>   int firstIndex = (int)(scrollPosition.get()) * lines;
>>
>>   content.manageCells(firstIndex);
>> };
>>
>> Now, the reason I think this may be same issue is that you're also doing
>> a modification of the children list during layout: setting the graphic is
>> sort of equivalent to label.getChildren().add(graphic)
>>
>> --John
>> On 20/02/2023 20:58, Scott Palmer wrote:
>>
>> I'm seeing an odd issue with using CSS to colour a Shape when I have it
>> as a child of a TextFlow.
>>
>> My use case is a "rich" text Cell in a tree or list.  I want to have the
>> text portion in multiple colours and so instead of using the graphic and
>> text parts of a typical Cell, I'm using only the Graphic and setting it to
>> a TextFlow to get the text colours. This means that I lose the ability to
>> set a graphic independen to the text, and so the graphic is also added to
>> the TextFlow.
>>
>> To style the graphics, which are made of simple shapes, I'm using CSS.
>> It makes it easy to adapt the colours for when a cell is selected etc.
>> What I've noticed is that as the cell selection moves around the Shape
>> component of the TextFlow flickers, as if it is drawn first using default
>> colours and then the CSS is applied afterward.  I tried working around this
>> by explicitly calling applyCss() on the Shape from the Cell's update
>> method, but it did not help.  If I explicitly set the Stroke and Fill via
>> the Shape API the flickering does not occur.  If I use CSS, but set the
>> Shape as the Cell's graphic and resort to only having plain text, there is
>> no flickering.
>>
>> A test program that demonstrates this is below.
>>
>> Bug or known limitation?
>>
>> Scott
>> 
>> package bugs;
>>
>> import javafx.application.Application;
>> import javafx.geometry.Insets;
>> import javafx.scene.Node;
>> import javafx.scene.Scene;
>> import javafx.scene.control.CheckBox;
>> import javafx.scene.control.ContentDisplay;
>> import javafx.scene.control.Label;
>> import javafx.scene.control.ListCell;
>> import javafx.scene.control.ListView;
>> import javafx.scene.control.Tab;
>> import javafx.scene.control.TabPane;
>> import javafx.scene.layout.HBox;
>> import javafx.scene.layout.VBox;
>> import javafx.scene.paint.Color;
>> import javafx.scene.shape.Circle

CSS styling of Shape in TextFlow causes flickering

2023-02-20 Thread Scott Palmer
I'm seeing an odd issue with using CSS to colour a Shape when I have it as
a child of a TextFlow.

My use case is a "rich" text Cell in a tree or list.  I want to have the
text portion in multiple colours and so instead of using the graphic and
text parts of a typical Cell, I'm using only the Graphic and setting it to
a TextFlow to get the text colours. This means that I lose the ability to
set a graphic independen to the text, and so the graphic is also added to
the TextFlow.

To style the graphics, which are made of simple shapes, I'm using CSS.  It
makes it easy to adapt the colours for when a cell is selected etc.  What
I've noticed is that as the cell selection moves around the Shape component
of the TextFlow flickers, as if it is drawn first using default colours and
then the CSS is applied afterward.  I tried working around this by
explicitly calling applyCss() on the Shape from the Cell's update method,
but it did not help.  If I explicitly set the Stroke and Fill via the Shape
API the flickering does not occur.  If I use CSS, but set the Shape as the
Cell's graphic and resort to only having plain text, there is no flickering.

A test program that demonstrates this is below.

Bug or known limitation?

Scott

package bugs;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;


public class CSSFlickerInTextFlow extends Application {

public static void main(String[] args) {
launch(args);
}

private CheckBox onlyCssCB;

@Override
public void start(Stage stage) throws Exception {
ListView list1 = new ListView<>();
ListView list2 = new ListView<>();
var items1 = list1.getItems();
var items2 = list2.getItems();
for (int i = 1; i < 23; i++) {
var x = "Item #"+i;
items1.add(x);
items2.add(x);
}
list1.setCellFactory(t -> new MyCell1());
list2.setCellFactory(t -> new MyCell2());

onlyCssCB = new CheckBox("Use only CSS (shapes will flicker in
TextFlow)");
HBox buttons = new HBox(8, onlyCssCB);
buttons.setPadding(new Insets(4));

Tab custom = new Tab("Everything in Graphic", list1);
Tab withoutColoredText = new Tab("Graphic + Text", list2);
TabPane tabs = new TabPane(custom, withoutColoredText);

VBox root = new VBox(
new Label("""
  Focus in list, cursor up and down, pay attention
to the circle.
  Try the same with the box checked - circle
flickers.
  Doesn't happen when not using the TextFlow.
  """),
buttons, tabs);
root.setPadding(new Insets(4));
var scene = new Scene(root);
stage.setScene(scene);
stage.setTitle("Flickering with CSS in TextFlow");
stage.show();
}

private Shape makeGraphic() {
Shape graphic = new Circle(6);
if (!onlyCssCB.isSelected()) {
graphic.setFill(Color.SALMON); // CSS overrides these but
causes flickering if not the same
graphic.setStroke(Color.BLACK);
}
graphic.setStyle("-fx-fill: salmon; -fx-stroke: black;");
return graphic;
}

class MyCell1 extends ListCell {

@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
setText(null);
if (!empty && item != null) {
TextFlow flow = new TextFlow();
Shape graphic = makeGraphic();
graphic.setTranslateY(2);
var nodeList = flow.getChildren();
Text name = new Text(item + " : ");
name.setStyle("-fx-fill: -fx-text-background-color;");
Text extra = new Text("with Color");
extra.setStyle("-fx-fill:ladder(-fx-background, white 49%,
salmon 50%);");
nodeList.add(graphic);
nodeList.add(new Rectangle(4,0)); // gap
nodeList.add(name);
nodeList.add(extra);
setGraphic(flow);
} else {
setGraphic(null);
}
}
}

class MyCell2 extends ListCell {
@Override

Re: WebKit Crashes JVM when removing nodes from DOM on wrong thread.

2023-02-13 Thread Scott Palmer
Created JDK-8302336 <https://bugs.openjdk.org/browse/JDK-8302336>

On Mon, Feb 13, 2023 at 8:42 AM Kevin Rushforth 
wrote:

> Yes, please file a bug. An intermittent exception would be one thing,
> but it shouldn't actually crash when doing that.
>
> -- Kevin
>
>
> On 2/12/2023 3:49 PM, Scott Palmer wrote:
> > I'm seeing a hard crash in native code that brings down the JVM when I
> > accidentally called removeChild on an element from a WebView Document
> > while not on the Platform thread.  While I know it's my error,
> > bringing down the JVM instead of throwing an exception seems wrong.
> >
> > Should this be considered a bug or not?
> >
> > Scott
> >
> > With JavaFX 17:
> > Thread 50 Crashed:: Java: ForkJoinPool-1-worker-5
> > 0   libjfxwebkit.dylib   0x14fa2ac33
> > WTFCrashWithInfo(int, char const*, char const*, int) + 19
> > 1   libjfxwebkit.dylib   0x14ea5b60d
> > WebCore::TimerBase::setNextFireTime(WTF::MonotonicTime) + 541
> > 2   libjfxwebkit.dylib   0x14ee0a513
> >
> WebCore::RenderTreeBuilder::detachFromRenderElement(WebCore::RenderElement&,
>
> > WebCore::RenderObject&, WebCore::RenderTreeBuilder::WillBeDestroyed) +
> 179
> > 3   libjfxwebkit.dylib   0x14ee09fa2
> > WebCore::RenderTreeBuilder::Block::detach(WebCore::RenderBlock&,
> > WebCore::RenderObject&,
> > WebCore::RenderTreeBuilder::CanCollapseAnonymousBlock) + 562
> > 4   libjfxwebkit.dylib   0x14ee085ef
> > WebCore::RenderTreeBuilder::detach(WebCore::RenderElement&,
> > WebCore::RenderObject&,
> > WebCore::RenderTreeBuilder::CanCollapseAnonymousBlock) + 543
> > 5   libjfxwebkit.dylib   0x14ee082ba
> > WebCore::RenderTreeBuilder::destroy(WebCore::RenderObject&) + 58
> > 6   libjfxwebkit.dylib   0x14ee0bd57
> >
> WebCore::RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers(WebCore::RenderObject&)
>
> > + 263
> > 7   libjfxwebkit.dylib   0x14ee19aae
> > WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&,
> > WebCore::RenderTreeUpdater::TeardownType,
> > WebCore::RenderTreeBuilder&)::$_7::operator()(unsigned int) const + 734
> > 8   libjfxwebkit.dylib   0x14ee18c13
> > WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&,
> > WebCore::RenderTreeUpdater::TeardownType, WebCore::RenderTreeBuilder&)
> > + 1171
> > 9   libjfxwebkit.dylib   0x14ee196d1
> > WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&) + 65
> > 10  libjfxwebkit.dylib   0x14e46db9c
> > WebCore::ContainerNode::removeBetween(WebCore::Node*, WebCore::Node*,
> > WebCore::Node&) + 108
> > 11  libjfxwebkit.dylib   0x14e46ad44
> > WebCore::ContainerNode::removeChild(WebCore::Node&) + 324
> > 12  libjfxwebkit.dylib   0x14e50e24b
> > WebCore::Node::removeChild(WebCore::Node&) + 43
> > 13  libjfxwebkit.dylib   0x14d98deeb
> > Java_com_sun_webkit_dom_NodeImpl_removeChildImpl + 107
> > 14  ??? 0x1203e753a ???
> > 15  ??? 0x1203e335c ???
> > 16  ??? 0x1203e36a2 ???
> > 17  ??? 0x1203e342b ???
> > 18  ??? 0x1203e342b ???
> > 19  ??? 0x1203e388f ???
> > 20  ??? 0x1203e342b ???
> > 21  ??? 0x1203e3317 ???
> > 22  ??? 0x1203e3317 ???
> > 23  ??? 0x1203e342b ???
> > 24  ??? 0x1203e3317 ???
> > 25  ??? 0x1203e342b ???
> > 26  ??? 0x1203dacc9 ???
> > 27  libjvm.dylib 0x110790af6
> > JavaCalls::call_helper(JavaValue*, methodHandle const&,
> > JavaCallArguments*, JavaThread*) + 710
> > 28  libjvm.dylib 0x11078fb47
> > JavaCalls::call_virtual(JavaValue*, Klass*, Symbol*, Symbol*,
> > JavaCallArguments*, JavaThread*) + 327
> > 29  libjvm.dylib 0x11078fc13
> > JavaCalls::call_virtual(JavaValue*, Handle, Klass*, Symbol*, Symbol*,
> > JavaThread*) + 99
> > 30  libjvm.dylib 0x11083ab94
> > thread_entry(JavaThread*, JavaThread*) + 180
> > 31  libjvm.dylib 0x1

WebKit Crashes JVM when removing nodes from DOM on wrong thread.

2023-02-12 Thread Scott Palmer
I'm seeing a hard crash in native code that brings down the JVM when I
accidentally called removeChild on an element from a WebView Document while
not on the Platform thread.  While I know it's my error, bringing down the
JVM instead of throwing an exception seems wrong.

Should this be considered a bug or not?

Scott

With JavaFX 17:
Thread 50 Crashed:: Java: ForkJoinPool-1-worker-5
0   libjfxwebkit.dylib   0x14fa2ac33 WTFCrashWithInfo(int,
char const*, char const*, int) + 19
1   libjfxwebkit.dylib   0x14ea5b60d
WebCore::TimerBase::setNextFireTime(WTF::MonotonicTime) + 541
2   libjfxwebkit.dylib   0x14ee0a513
WebCore::RenderTreeBuilder::detachFromRenderElement(WebCore::RenderElement&,
WebCore::RenderObject&, WebCore::RenderTreeBuilder::WillBeDestroyed) + 179
3   libjfxwebkit.dylib   0x14ee09fa2
WebCore::RenderTreeBuilder::Block::detach(WebCore::RenderBlock&,
WebCore::RenderObject&,
WebCore::RenderTreeBuilder::CanCollapseAnonymousBlock) + 562
4   libjfxwebkit.dylib   0x14ee085ef
WebCore::RenderTreeBuilder::detach(WebCore::RenderElement&,
WebCore::RenderObject&,
WebCore::RenderTreeBuilder::CanCollapseAnonymousBlock) + 543
5   libjfxwebkit.dylib   0x14ee082ba
WebCore::RenderTreeBuilder::destroy(WebCore::RenderObject&) + 58
6   libjfxwebkit.dylib   0x14ee0bd57
WebCore::RenderTreeBuilder::destroyAndCleanUpAnonymousWrappers(WebCore::RenderObject&)
+ 263
7   libjfxwebkit.dylib   0x14ee19aae
WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&,
WebCore::RenderTreeUpdater::TeardownType,
WebCore::RenderTreeBuilder&)::$_7::operator()(unsigned int) const + 734
8   libjfxwebkit.dylib   0x14ee18c13
WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&,
WebCore::RenderTreeUpdater::TeardownType, WebCore::RenderTreeBuilder&) +
1171
9   libjfxwebkit.dylib   0x14ee196d1
WebCore::RenderTreeUpdater::tearDownRenderers(WebCore::Element&) + 65
10  libjfxwebkit.dylib   0x14e46db9c
WebCore::ContainerNode::removeBetween(WebCore::Node*, WebCore::Node*,
WebCore::Node&) + 108
11  libjfxwebkit.dylib   0x14e46ad44
WebCore::ContainerNode::removeChild(WebCore::Node&) + 324
12  libjfxwebkit.dylib   0x14e50e24b
WebCore::Node::removeChild(WebCore::Node&) + 43
13  libjfxwebkit.dylib   0x14d98deeb
Java_com_sun_webkit_dom_NodeImpl_removeChildImpl + 107
14  ??? 0x1203e753a ???
15  ??? 0x1203e335c ???
16  ??? 0x1203e36a2 ???
17  ??? 0x1203e342b ???
18  ??? 0x1203e342b ???
19  ??? 0x1203e388f ???
20  ??? 0x1203e342b ???
21  ??? 0x1203e3317 ???
22  ??? 0x1203e3317 ???
23  ??? 0x1203e342b ???
24  ??? 0x1203e3317 ???
25  ??? 0x1203e342b ???
26  ??? 0x1203dacc9 ???
27  libjvm.dylib 0x110790af6
JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*,
JavaThread*) + 710
28  libjvm.dylib 0x11078fb47
JavaCalls::call_virtual(JavaValue*, Klass*, Symbol*, Symbol*,
JavaCallArguments*, JavaThread*) + 327
29  libjvm.dylib 0x11078fc13
JavaCalls::call_virtual(JavaValue*, Handle, Klass*, Symbol*, Symbol*,
JavaThread*) + 99
30  libjvm.dylib 0x11083ab94
thread_entry(JavaThread*, JavaThread*) + 180
31  libjvm.dylib 0x110d164af
JavaThread::thread_main_inner() + 335
32  libjvm.dylib 0x110d1481f Thread::call_run() +
207
33  libjvm.dylib 0x110b1f898
thread_native_entry(Thread*) + 328
34  libsystem_pthread.dylib  0x7ff8062b4259 _pthread_start + 125
35  libsystem_pthread.dylib  0x7ff8062afc7b thread_start + 15


With JavaFX 19.0.2.1
Thread 48 Crashed:: Java: ForkJoinPool-1-worker-2
0   libjfxwebkit.dylib   0x14f2eb9f3 0x14d0d8000 + 35731955
1   libjfxwebkit.dylib   0x14e3744a6 0x14d0d8000 + 19514534
2   libjfxwebkit.dylib   0x14e747d49 0x14d0d8000 + 23526729
3   libjfxwebkit.dylib   0x14e747798 0x14d0d8000 + 23525272
4   libjfxwebkit.dylib   0x14e745b7f 0x14d0d8000 + 23518079
5   libjfxwebkit.dylib   0x14e745837 0x14d0d8000 + 23517239
6   libjfxwebkit.dylib   0x14e749766 0x14d0d8000 + 23533414
7   libjfxwebkit.dylib   0x14e757dc1 0x14d0d8000 + 23592385
8   libjfxwebkit.dylib   0x14e757033 0x14d0d8000 + 23588915
9   libjfxwebkit.dylib   0x14e757aa1 0x14d0d8000 + 

Re: RFR: 8301302: Platform preferences API [v2]

2023-01-31 Thread Scott Palmer
On Tue, Jan 31, 2023 at 6:15 PM Andy Goryachev  wrote:

> On Tue, 31 Jan 2023 23:04:50 GMT, Scott Palmer 
> wrote:
>
> > Is it necessary for any application to know about "auto"?
>
> I actually don't know how the "auto" behaves.  From the description it
> seems the colors might actually change gradually throughout the day, thus
> making an enum useless and necessitating the use of the actual colors.
>

>From https://support.apple.com/en-ca/guide/mac-help/mchl52e1c2d2/mac

Auto just changes from light to dark based on the "Night Shift" setting,
which uses either a fixed schedule, or sunset.  It doesn't have any "in
between" modes. Though it does animate the transition of the colors over
1/2 second or so.

The point being that as far as making the application aware of the current
state, auto isn't needed.  As a preference for within the application
(force light or dark, or 'auto' = track the OS setting) it might be
useful.  I would only include it if the Theme proposal is also going to
dynamically track the OS preference and switch Themes for you.  It looks
like you have that covered by having the application bind to the Platform
Preferences value, in which case "auto" would be an application setting
rather than a JavaFX platform setting.

Scott


Re: RFR: 8301302: Platform preferences API [v2]

2023-01-31 Thread Scott Palmer
On Sun, 29 Jan 2023 17:10:26 GMT, Michael Strauß  wrote:

>> Platform preferences are the preferred UI settings of the operating system. 
>> For example, on Windows this includes the color values identified by the 
>> `Windows.UI.ViewManagement.UIColorType` enumeration; on macOS this includes 
>> the system color values of the `NSColor` class.
>> 
>> Exposing these dynamic values to JavaFX applications allows developers to 
>> create themes that can integrate seamlessly with the color scheme of the 
>> operating system.
>> 
>> Platform preferences are exposed as an `ObservableMap` of platform-specific 
>> key-value pairs, which means that the preferences available on Windows are 
>> different from macOS or Linux. JavaFX provides a small, curated list of 
>> preferences that are available on most platforms, and are therefore exposed 
>> with a platform-independent API:
>> 
>> 
>> public interface Preferences extends ObservableMap {
>> // Platform-independent API
>> ReadOnlyObjectProperty appearanceProperty();
>> ReadOnlyObjectProperty backgroundColorProperty();
>> ReadOnlyObjectProperty foregroundColorProperty();
>> ReadOnlyObjectProperty accentColorProperty();
>> 
>> // Convenience methods to retrieve platform-specific values from the map
>> Optional getInteger(String key);
>> Optional getDouble(String key);
>> Optional getString(String key);
>> Optional getBoolean(String key);
>> Optional getColor(String key);
>> }
>> 
>> 
>> The platform appearance is defined by the new `javafx.stage.Appearance` 
>> enumeration:
>> 
>> 
>> public enum Appearance {
>> LIGHT,
>> DARK
>> }
>> 
>> 
>> An instance of the `Preferences` interface can be retrieved by calling 
>> `Platform.getPreferences()`.
>
> Michael Strauß has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   Use Optional for convenience methods in Preferences

On Tue, Jan 31, 2023 at 3:00 PM Andy Goryachev ***@***.***>
wrote:

> In the context of adding theme support in javafx, I think this PR is a
> step in the right direction. I also like a small set of
> platform-independent properties like fg and bg colors. I wonder if the same
> approach can be extended for other aspects of platform L, like fonts,
> spacing, and may be other aspects (like, hiding scrollbars setting on Mac?)
>
> I agree with @kevinrushforth  - we'd
> need more discussion on the actual implementation. There are a few items
> that I feel are unnecessary, or might be done differently, and I'd like to
> learn what other people think.
>
> Specifically:
>
>1. Appearance enum seems unnecessary - there might be more choices in
>a specific platform (Mac Ventura has three: dark/light/auto).
>
>
Is it necessary for any application to know about "auto"?  Presumably when
the mode automatically changes from one to the other there would be an
event that should be handled, just as if the user changed the setting while
the application was running.

Scott

> Message ID: ***@***.***>
>

-

PR: https://git.openjdk.org/jfx/pull/1014


Re: Q: missing APIs needed for implementation of a rich text control

2023-01-27 Thread Scott Palmer
When I was experimenting with a program to generate titles for videos the
ability to control the spacing between letters (not kerning, but tracking)
would have been helpful.
E.g. animating something like this:
Title
T i t l e
T  i  t  l  e
T   i   t   l   e
I don't recall everything I encountered in that project, but I believe all
the basic font metrics about baseline and ascenders/descenders would help.

A FontChooser would be useful.  Applications can always code their own, but
the same can be said for ColorPicker.  It doesn't look like there is one
available even from 3rd-party libraries like ControlsFX.
Going from a Font object to CSS -fx-font-size, -fx-font-family, -fx-
font-weight, -fx-font-style doesn't always work as I've already mentioned.
The Font object doesn't have a method to get the font weight and there is
no -fx-font-name style.  Setting -fx-font-family doesn't always result in
CSS that successfully selects the desired font if used in combination with
-fx-font-style and/or -fx-font-weight.  Sometimes adding CSS for weight or
style will cause a completely different family to be used which can look
quite drastic when a variable width font is substituted for a fixed-width
font just because you tried to make something bold.
Also FontPosture only has ITALIC and NORMAL, but CSS -fx-font-style has
'normal',  'italic' and 'oblique' - There is no way to ask for 'oblique'
from code and the FontStyleConverter will convert "oblique" to REGULAR,
even though "oblique" works in CSS to get a slanted font.

Asking about caretBlinkRate, I'm not sure. I imagine only one caret
should ever be visible, with the exception of a rich text control that
supports multiple simultaneous insertion points, like many code editors.
In that case there would still only be one rate at a time even though there
are multiple carets.  My point being there should never be a need for
multiple rates to be active at the same time, so maybe you could get away
with a global rate.  I can't think of a need for multiple rates, but maybe
someone else can.

Regards,

Scott

On Fri, Jan 27, 2023 at 12:31 PM Andy Goryachev 
wrote:

> >  More control of kerning and general spacing might be nice.
>
>
>
> What properties, besides kerning, are you referring to?
>
>
>
> Also, a question for the wider audience: is there a need to have
> caretBlinkRate property for each control, or a single global one would
> suffice?  In other words, are there use cases when two or more controls
> might need a different blink rate?
>
>
>
> Thank you.
>
>
>
> -andy
>
>
>
>
>
> *From: *openjfx-dev  on behalf of Scott
> Palmer 
> *Date: *Thursday, January 26, 2023 at 12:33
> *To: *openjfx-dev 
> *Subject: *Re: Q: missing APIs needed for implementation of a rich text
> control
>
> [dupe of private message, now including the mailing list]
>
>
>
> I've been using RichTextFX to make my own code editor/IDE.  I see that you
> have asked that project specifically on GitHub, excellent.
>
> One thing that I wanted to do was to use a font like Fira Code that
> combines characters such as != or >= into a single glyph, but there are no
> APIs to request that JavaFX render those optional ligatures. Swing APIs
> automatically do.  In fact just implementing some basic font selection has
> been tedious.  Getting the font family from a Font object and trying to use
> it in CSS to specify -fx-font-family simply doesn't work sometimes.  Trying
> to filter the list of available fonts to show only those that are
> fixed-width is tedious.  I tried to hack something by measuring a couple
> different characters from the font that would normally be different widths,
> but this is an unreliable hack. Allowing the user to choose a preferred
> font and then configuring components to use it via a CSS stylesheet is
> simply more difficult than it should be.
>
> A few years ago I contributed the changes to make the tab-width
> configurable, which helped with my project a little bit.  Other APIs are
> needed to better control line spacing and measure font baseline offsets and
> that sort of thing.  I see there is an issue for caretBlinkRate, what about
> changing the caret shape? E.g. block, underscore, vertical bar, etc.
> Should the block be solid or an outline? Why is caretShape read-only? Why
> does it return an array of PathElements instead of simply a Shape which by
> default would be a Path?  More control of kerning and general spacing might
> be nice. I've wanted that in the past, not for a rich text control, but for
> doing video titles.  I can see how the two needs overlap though.  I
> recently asked here about rendering emojis.  That's currently very
> unreliable and broken.  Getting something to work consistently
> cross-platform is not easy.  Sometimes emojis are

Re: BaselineOffset of StackPane is inconsistent

2023-01-26 Thread Scott Palmer
I determined this is caused by the StackPane's child node's layoutY value
sometimes being 0.0 and sometimes being 7.5.  Which is strange, since
layout should always be complete on the TreeCells by the time they are
painted.

Which got me thinking.. sure maybe on one pass it wasn't initialized or
something, but why would it keep changing?

Then I learned that updateItem is being called much more often than I had
thought.  I had previously thought it was only called when the TreeCell was
meant to render a new or different TreeItem.  Apparently it is called when
the TreeItem selection changes.  I'm not sure why, as no parameters to
updateItem include the selection state, so a TreeCell doesn't know that is
why it is being called, and the documentation and sample code doesn't
mention it.
In fact the documentation for Cell isItemChanged specifically states:

 * This method is called by Cell subclasses so that certain
CPU-intensive
 * actions (specifically, calling {@link #updateItem(Object, boolean)})
are
 * only performed when necessary

*(that is, they are only performed * when the currently set {@link
#itemProperty() item} is considered to be * different than the proposed
new item that could be set).*

Which implies to me (along with the method name "updateItem") that
assigning a different item to the Cell is the only reason for updateItem to
be called.
This is clearly not the case.

Another observation is that, while changing the selected item such that I
observe the misalignment, the last time getBaselineOffset is called for any
particular cell while processing that event, it always returns the same
value of 7.5, but it seems it doesn't always use this value for when it
paints.
E.g. if I toggle the selection of a cell, updateItem is called once,
creating new Nodes for the Cell's graphic, and getBaselineOffset for the
StackPane is called 4 times.  The first 3 times the first managed child of
the StackPane has layoutY = 0.0, the last time it is 7.5.

There's a bug here somewhere...

Scott


On Tue, Jan 24, 2023 at 1:43 PM Scott Palmer  wrote:

> I'm seeing something odd with the alignment of content in a TextFlow and
> I'm not sure if I'm doing something wrong, or if there is a bug there.
> The getBaselineOffset() method of the StackPane is returning inconsistent
> values.  If I sub-class it to force a constant offset, everything works.
> Since the StackPane content is always the same, I would expect
> getBaselineOffset to always return the same value, but in my sample program
> (below) sometimes it returns 6.5 and other times it returns 14.0. (Tested
> on macOS 13.2 w. OpenJDK 19/OpenJFX19)
> Parent.getBaselineOffset() is documented as: "Calculates the baseline
> offset based on the first managed child." - which should always be the same
> in my example. Sure enough, I checked and
> getChildren().get(0).getBaselineOffset() is always returning the same value
> (13.0) - so where is the discrepancy coming from?
>
> Possibly related to https://bugs.openjdk.org/browse/JDK-8091236
>
> The following program demonstrates the issue.  While selecting things in
> the TreeView the TextFlows are repainted with different alignment between
> the StackPane node and the Text nodes.
>
> package bugs;
>
> import javafx.application.Application;
> import javafx.scene.Scene;
> import javafx.scene.control.ContentDisplay;
> import javafx.scene.control.Label;
> import javafx.scene.control.TreeCell;
> import javafx.scene.control.TreeItem;
> import javafx.scene.control.TreeView;
> import javafx.scene.layout.StackPane;
> import javafx.scene.layout.VBox;
> import javafx.scene.paint.Color;
> import javafx.scene.shape.Circle;
> import javafx.scene.shape.Polygon;
> import javafx.scene.text.Text;
> import javafx.scene.text.TextFlow;
> import javafx.stage.Stage;
>
> public class TextFlowWithIcons extends Application {
> public static void main(String[] args) {
> launch(args);
> }
>
> @Override
> public void start(Stage primaryStage) {
> TreeItem node1 = new TreeItem<>("item");
> TreeItem node2 = new TreeItem<>("text");
> TreeItem node3 = new TreeItem<>("tree");
> TreeItem root = new TreeItem<>("ROOT");
> root.setExpanded(true);
> root.getChildren().addAll(node1, node2, node3);
> var treeView = new TreeView(root);
> treeView.setCellFactory(this::cellFactory);
> VBox box = new VBox(8, new Label("Fiddle with the
> TreeView...\nWatch the alignment bounce around."), treeView);
> var scene = new Scene(box);
> primaryStage.setScene(scene);
> primaryStage.setTitle("Graphic Alignment Issue");
> primaryStage.show();
> }

Re: Q: missing APIs needed for implementation of a rich text control

2023-01-26 Thread Scott Palmer
[dupe of private message, now including the mailing list]

I've been using RichTextFX to make my own code editor/IDE.  I see that you
have asked that project specifically on GitHub, excellent.
One thing that I wanted to do was to use a font like Fira Code that
combines characters such as != or >= into a single glyph, but there are no
APIs to request that JavaFX render those optional ligatures. Swing APIs
automatically do.  In fact just implementing some basic font selection has
been tedious.  Getting the font family from a Font object and trying to use
it in CSS to specify -fx-font-family simply doesn't work sometimes.  Trying
to filter the list of available fonts to show only those that are
fixed-width is tedious.  I tried to hack something by measuring a couple
different characters from the font that would normally be different widths,
but this is an unreliable hack. Allowing the user to choose a preferred
font and then configuring components to use it via a CSS stylesheet is
simply more difficult than it should be.
A few years ago I contributed the changes to make the tab-width
configurable, which helped with my project a little bit.  Other APIs are
needed to better control line spacing and measure font baseline offsets and
that sort of thing.  I see there is an issue for caretBlinkRate, what about
changing the caret shape? E.g. block, underscore, vertical bar, etc.
Should the block be solid or an outline? Why is caretShape read-only? Why
does it return an array of PathElements instead of simply a Shape which by
default would be a Path?  More control of kerning and general spacing might
be nice. I've wanted that in the past, not for a rich text control, but for
doing video titles.  I can see how the two needs overlap though.  I
recently asked here about rendering emojis.  That's currently very
unreliable and broken.  Getting something to work consistently
cross-platform is not easy.  Sometimes emojis are rendered in color, other
times not.  Mac renders color emojis in gray and at the wrong size (since
 the sub-pixel rendering was turned off to match macOS).  On Windows the
emojis are never in color.

Regards,

Scott

On Wed, Jan 25, 2023 at 10:41 PM Scott Palmer  wrote:

> I've been using RichTextFX to make my own code editor/IDE.  I see that you
> have asked that project specifically on GitHub, excellent.
> One thing that I wanted to do was to use a font like Fira Code that
> combines characters such as != or >= into a single glyph, but there are no
> APIs to request that JavaFX render those optional ligatures. Swing APIs
> automatically do.  In fact just implementing some basic font selection has
> been tedious.  Getting the font family from a Font object and trying to use
> it in CSS to specify -fx-font-family simply doesn't work sometimes.  Trying
> to filter the list of available fonts to show only those that are
> fixed-width is tedious.  I tried to hack something by measuring a couple
> different characters from the font that would normally be different widths,
> but this is an unreliable hack. Allowing the user to choose a preferred
> font and then configuring components to use it via a CSS stylesheet is
> simply more difficult than it should be.
> A few years ago I contributed the changes to make the tab-width
> configurable, which helped with my project a little bit.  Other APIs are
> needed to better control line spacing and measure font baseline offsets and
> that sort of thing.  I see there is an issue for caretBlinkRate, what about
> changing the caret shape? E.g. block, underscore, vertical bar, etc.
> Should the block be solid or an outline? Why is caretShape read-only? Why
> does it return an array of PathElements instead of simply a Shape which by
> default would be a Path?  More control of kerning and general spacing might
> be nice. I've wanted that in the past, not for a rich text control, but for
> doing video title.  I can see how the two needs overlap though.  I recently
> asked here about rendering emojis.  That's currently very unreliable and
> broken.  Getting something to work consistently cross-platform is not
> easy.  Sometimes emojis are rendered in color, other times not.  Mac
> renders color emojis in gray and at the wrong size (since  the sub-pixel
> rendering was turned off to match macOS).  On Windows the emojis are never
> in color.
>
> Regards,
>
> Scott
>
> On Wed, Jan 25, 2023 at 5:38 PM Andy Goryachev 
> wrote:
>
>> Dear colleagues:
>>
>>
>>
>> I am trying to identify missing public APIs needed to support a rich text
>> control.  There is a number of tickets created already against various
>> parts of JavaFX, collected in https://bugs.openjdk.org/browse/JDK-8300569
>> , though I suspect this list may not be complete.
>>
>>
>>
>> If anyone has any suggestions

BaselineOffset of StackPane is inconsistent

2023-01-24 Thread Scott Palmer
I'm seeing something odd with the alignment of content in a TextFlow and
I'm not sure if I'm doing something wrong, or if there is a bug there.
The getBaselineOffset() method of the StackPane is returning inconsistent
values.  If I sub-class it to force a constant offset, everything works.
Since the StackPane content is always the same, I would expect
getBaselineOffset to always return the same value, but in my sample program
(below) sometimes it returns 6.5 and other times it returns 14.0. (Tested
on macOS 13.2 w. OpenJDK 19/OpenJFX19)
Parent.getBaselineOffset() is documented as: "Calculates the baseline
offset based on the first managed child." - which should always be the same
in my example. Sure enough, I checked and
getChildren().get(0).getBaselineOffset() is always returning the same value
(13.0) - so where is the discrepancy coming from?

Possibly related to https://bugs.openjdk.org/browse/JDK-8091236

The following program demonstrates the issue.  While selecting things in
the TreeView the TextFlows are repainted with different alignment between
the StackPane node and the Text nodes.

package bugs;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Polygon;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;

public class TextFlowWithIcons extends Application {
public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage primaryStage) {
TreeItem node1 = new TreeItem<>("item");
TreeItem node2 = new TreeItem<>("text");
TreeItem node3 = new TreeItem<>("tree");
TreeItem root = new TreeItem<>("ROOT");
root.setExpanded(true);
root.getChildren().addAll(node1, node2, node3);
var treeView = new TreeView(root);
treeView.setCellFactory(this::cellFactory);
VBox box = new VBox(8, new Label("Fiddle with the
TreeView...\nWatch the alignment bounce around."), treeView);
var scene = new Scene(box);
primaryStage.setScene(scene);
primaryStage.setTitle("Graphic Alignment Issue");
primaryStage.show();
}

private TreeCell cellFactory(TreeView tv) {
return new CustomCell();
}

private static class CustomCell extends TreeCell {

public CustomCell() {
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}

@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (item != null && !empty) {
var text1 = new Text("Some ");
var text2 = new Text("colored ");
var text3 = new Text(item);
text2.setFill(Color.GREEN);
var circle = new Circle(6);
circle.setStroke(Color.BLACK);
circle.setFill(Color.RED);
var triangle = new Polygon(-6, 6, 6, 6, 0, -6);
triangle.setFill(Color.YELLOW);
triangle.setStroke(Color.BLACK);
triangle.setScaleX(0.5);
triangle.setScaleY(0.5);
triangle.setTranslateX(4);
triangle.setTranslateY(4);
var icon = new StackPane(circle, triangle)
// uncomment to fix
//{
//@Override
//public double getBaselineOffset() {
//return 12;
//}
//}
;
var textFlow = new TextFlow(icon, text1, text2, text3);
setGraphic(textFlow);
} else {
setGraphic(null);
}
setText(null);
}

}
}

Regards,

Scott


Small changes to Gradle build scripts

2023-01-20 Thread Scott Palmer
Are small simplifying changes to the gradle scripts welcome?

E.g. instead of:
def inStream = new java.io.BufferedReader(new java.io.InputStreamReader(new
java.lang.ProcessBuilder(JAVA, "-fullversion").start().getErrorStream()));
try {
String v = inStream.readLine().trim();
if (v != null) {
int ib = v.indexOf("full version \"");
if (ib != -1) {
String str = v.substring(ib);
String ver = str.substring(str.indexOf("\"") + 1, str.size() - 1);

defineProperty("jdkRuntimeVersion", ver)
def jdkVersionInfo = parseJavaVersion(ver)
defineProperty("jdkVersion", jdkVersionInfo[0])
defineProperty("jdkBuildNumber", jdkVersionInfo[1])

// Define global properties based on the version of Java
// For example, we could define a "jdk18OrLater" property as
// follows that could then be used to implement conditional build
// logic based on whether we were running on JDK 18 or later,
// should the need arise.
// def status = compareJdkVersion(jdkVersion, "18")
// ext.jdk18OrLater = (status >= 0)
}
}
} finally {
inStream.close();
}

this:
def verMatch = [JAVA, "-fullversion"].execute().err.text =~ /full version
"([^"]+)/
if (verMatch.find()) {
String ver = verMatch.group(1);
defineProperty("jdkRuntimeVersion", ver)
def jdkVersionInfo = parseJavaVersion(ver)
defineProperty("jdkVersion", jdkVersionInfo[0])
defineProperty("jdkBuildNumber", jdkVersionInfo[1])

// Define global properties based on the version of Java
// For example, we could define a "jdk18OrLater" property as
// follows that could then be used to implement conditional build
// logic based on whether we were running on JDK 18 or later,
// should the need arise.
// def status = compareJdkVersion(jdkVersion, "18")
// ext.jdk18OrLater = (status >= 0)
}

or instead of:
ext.HAS_JAVAFX_MODULES = false;
def inStream2 = new java.io.BufferedReader(new java.io.InputStreamReader(new
java.lang.ProcessBuilder(JAVA, "--list-modules").start().getInputStream()));
try {
String v;
while ((v = inStream2.readLine()) != null) {
v = v.trim();
if (v.startsWith("javafx.base")) ext.HAS_JAVAFX_MODULES = true;
}
} finally {
inStream2.close();
}

this:
ext.HAS_JAVAFX_MODULES = [JAVA, '--list-modules'].execute().text.contains(
'javafx.base')

... much simpler and seems to work just as well.

They don't do much more than improve readability and reduce the line count
though, so I'm not sure if anyone cares.

Scott


Re: Build issue: error: option --upgrade-module-path cannot be used together with --release

2023-01-19 Thread Scott Palmer
I guess --patch-module should be used instead of --update-module-path ? It
seems to be a little more complicated.

On Thu, Jan 19, 2023 at 2:17 PM Scott Palmer  wrote:

> I found the problem.  I'm using a build of OpenJDK from Azul that includes
> the javafx modules.  You probably aren't, which means the
> --upgrade-module-path option isn't being used so there is no conflict with
> javac parameters.
> I downloaded a JDK17 without the JavaFX modules and teh build worked.
> I think this will have to be fixed somehow or the documentation needs to
> change to forbid a JDK with built-in JavaFX modules.  The current attempts
> in the build script to deal with existing javafx modules are not working.
> A fix would be better.
>
> Scott
>
> On Thu, Jan 19, 2023 at 1:29 PM Scott Palmer  wrote:
>
>> Tried a gradle clean (which works fine after manually deleting the stale
>> mac_tools.properties file) and confirmed the build folder was gone from the
>> graphics module and elsewhere, no difference.  I'm running the gradle
>> wrapper, so it's using Gradle as defined by the project.  I'm also usually
>> on the bleeding edge with Gradle, so if I didn't use gradlew it would have
>> been Gradle 8.0-rc-2 :-)
>>
>> Scott
>>
>>
>> On Thu, Jan 19, 2023 at 1:20 PM Kevin Rushforth <
>> kevin.rushfo...@oracle.com> wrote:
>>
>>> I recommend removing the entire build directory (although if you managed
>>> to get "gradle clean" working, then it will do that).
>>>
>>> What version of gradle are you using? You will need gradle 7.6 to use
>>> JDK 19.
>>>
>>> -- Kevin
>>>
>>>
>>> On 1/19/2023 10:17 AM, Scott Palmer wrote:
>>>
>>> Tried again with JDK 17.0.5, just in case... still not working.
>>>
>>> On Wed, Jan 18, 2023 at 3:18 PM Scott Palmer  wrote:
>>>
>>>> I'm trying to build OpenJFX on my Mac.  I figured out an issue with the
>>>> Gradle scripts, they fail if there is a stale mac_tools.properties file. A
>>>> 'clean' also fails for the same reason so you have to manually delete the
>>>> file to get it to be re-built.  But now the build fails with the following
>>>> error:
>>>>
>>>> > Task :graphics:compileJava FAILED
>>>> You specified both --module-source-path and a sourcepath. These options
>>>> are mutually exclusive. Ignoring sourcepath.
>>>> error: option --upgrade-module-path cannot be used together with
>>>> --release
>>>> Usage: javac  
>>>> use --help for a list of possible options
>>>>
>>>> FAILURE: Build failed with an exception.
>>>>
>>>> I'm not sure why I would be seeing this error if the build is working
>>>> for everyone else.  I'm using JDK 19.
>>>>
>>>> Any hints?
>>>>
>>>> Btw, the Mac section of
>>>> https://wiki.openjdk.org/display/OpenJFX/Building+OpenJFX still
>>>> mentions needing Mercurial.  I don't think that's true anymore.
>>>>
>>>> Regards,
>>>>
>>>> Scott
>>>>
>>>
>>>


Re: Build issue: error: option --upgrade-module-path cannot be used together with --release

2023-01-19 Thread Scott Palmer
I found the problem.  I'm using a build of OpenJDK from Azul that includes
the javafx modules.  You probably aren't, which means the
--upgrade-module-path option isn't being used so there is no conflict with
javac parameters.
I downloaded a JDK17 without the JavaFX modules and teh build worked.
I think this will have to be fixed somehow or the documentation needs to
change to forbid a JDK with built-in JavaFX modules.  The current attempts
in the build script to deal with existing javafx modules are not working.
A fix would be better.

Scott

On Thu, Jan 19, 2023 at 1:29 PM Scott Palmer  wrote:

> Tried a gradle clean (which works fine after manually deleting the stale
> mac_tools.properties file) and confirmed the build folder was gone from the
> graphics module and elsewhere, no difference.  I'm running the gradle
> wrapper, so it's using Gradle as defined by the project.  I'm also usually
> on the bleeding edge with Gradle, so if I didn't use gradlew it would have
> been Gradle 8.0-rc-2 :-)
>
> Scott
>
>
> On Thu, Jan 19, 2023 at 1:20 PM Kevin Rushforth <
> kevin.rushfo...@oracle.com> wrote:
>
>> I recommend removing the entire build directory (although if you managed
>> to get "gradle clean" working, then it will do that).
>>
>> What version of gradle are you using? You will need gradle 7.6 to use JDK
>> 19.
>>
>> -- Kevin
>>
>>
>> On 1/19/2023 10:17 AM, Scott Palmer wrote:
>>
>> Tried again with JDK 17.0.5, just in case... still not working.
>>
>> On Wed, Jan 18, 2023 at 3:18 PM Scott Palmer  wrote:
>>
>>> I'm trying to build OpenJFX on my Mac.  I figured out an issue with the
>>> Gradle scripts, they fail if there is a stale mac_tools.properties file. A
>>> 'clean' also fails for the same reason so you have to manually delete the
>>> file to get it to be re-built.  But now the build fails with the following
>>> error:
>>>
>>> > Task :graphics:compileJava FAILED
>>> You specified both --module-source-path and a sourcepath. These options
>>> are mutually exclusive. Ignoring sourcepath.
>>> error: option --upgrade-module-path cannot be used together with
>>> --release
>>> Usage: javac  
>>> use --help for a list of possible options
>>>
>>> FAILURE: Build failed with an exception.
>>>
>>> I'm not sure why I would be seeing this error if the build is working
>>> for everyone else.  I'm using JDK 19.
>>>
>>> Any hints?
>>>
>>> Btw, the Mac section of
>>> https://wiki.openjdk.org/display/OpenJFX/Building+OpenJFX still
>>> mentions needing Mercurial.  I don't think that's true anymore.
>>>
>>> Regards,
>>>
>>> Scott
>>>
>>
>>


Minor: Misleading comment (and typo) in build.gradle

2023-01-19 Thread Scott Palmer
This isn't affecting anything, but while trying to figure out my build
issues I noticed this typo and mismatch between the comment and the code..
 "verion" at https://github.com/openjdk/jfx/blob/master/build.gradle#L617
But more significant, the actual command issued is "java -fullversion"
which outputs something substantially different.

// Determine the verion of Java in JDK_HOME. It looks like this:
//
// $ java -version
// java version "1.7.0_45"
// Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
// Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)
//
// We need to parse the second line
def inStream = new java.io.BufferedReader(new java.io.InputStreamReader(new
java.lang.ProcessBuilder(JAVA, "-fullversion").start().getErrorStream()));


Re: Build issue: error: option --upgrade-module-path cannot be used together with --release

2023-01-19 Thread Scott Palmer
Tried a gradle clean (which works fine after manually deleting the stale
mac_tools.properties file) and confirmed the build folder was gone from the
graphics module and elsewhere, no difference.  I'm running the gradle
wrapper, so it's using Gradle as defined by the project.  I'm also usually
on the bleeding edge with Gradle, so if I didn't use gradlew it would have
been Gradle 8.0-rc-2 :-)

Scott


On Thu, Jan 19, 2023 at 1:20 PM Kevin Rushforth 
wrote:

> I recommend removing the entire build directory (although if you managed
> to get "gradle clean" working, then it will do that).
>
> What version of gradle are you using? You will need gradle 7.6 to use JDK
> 19.
>
> -- Kevin
>
>
> On 1/19/2023 10:17 AM, Scott Palmer wrote:
>
> Tried again with JDK 17.0.5, just in case... still not working.
>
> On Wed, Jan 18, 2023 at 3:18 PM Scott Palmer  wrote:
>
>> I'm trying to build OpenJFX on my Mac.  I figured out an issue with the
>> Gradle scripts, they fail if there is a stale mac_tools.properties file. A
>> 'clean' also fails for the same reason so you have to manually delete the
>> file to get it to be re-built.  But now the build fails with the following
>> error:
>>
>> > Task :graphics:compileJava FAILED
>> You specified both --module-source-path and a sourcepath. These options
>> are mutually exclusive. Ignoring sourcepath.
>> error: option --upgrade-module-path cannot be used together with --release
>> Usage: javac  
>> use --help for a list of possible options
>>
>> FAILURE: Build failed with an exception.
>>
>> I'm not sure why I would be seeing this error if the build is working for
>> everyone else.  I'm using JDK 19.
>>
>> Any hints?
>>
>> Btw, the Mac section of
>> https://wiki.openjdk.org/display/OpenJFX/Building+OpenJFX still mentions
>> needing Mercurial.  I don't think that's true anymore.
>>
>> Regards,
>>
>> Scott
>>
>
>


Re: Build issue: error: option --upgrade-module-path cannot be used together with --release

2023-01-19 Thread Scott Palmer
Tried again with JDK 17.0.5, just in case... still not working.

On Wed, Jan 18, 2023 at 3:18 PM Scott Palmer  wrote:

> I'm trying to build OpenJFX on my Mac.  I figured out an issue with the
> Gradle scripts, they fail if there is a stale mac_tools.properties file. A
> 'clean' also fails for the same reason so you have to manually delete the
> file to get it to be re-built.  But now the build fails with the following
> error:
>
> > Task :graphics:compileJava FAILED
> You specified both --module-source-path and a sourcepath. These options
> are mutually exclusive. Ignoring sourcepath.
> error: option --upgrade-module-path cannot be used together with --release
> Usage: javac  
> use --help for a list of possible options
>
> FAILURE: Build failed with an exception.
>
> I'm not sure why I would be seeing this error if the build is working for
> everyone else.  I'm using JDK 19.
>
> Any hints?
>
> Btw, the Mac section of
> https://wiki.openjdk.org/display/OpenJFX/Building+OpenJFX still mentions
> needing Mercurial.  I don't think that's true anymore.
>
> Regards,
>
> Scott
>


Build issue: error: option --upgrade-module-path cannot be used together with --release

2023-01-18 Thread Scott Palmer
I'm trying to build OpenJFX on my Mac.  I figured out an issue with the
Gradle scripts, they fail if there is a stale mac_tools.properties file. A
'clean' also fails for the same reason so you have to manually delete the
file to get it to be re-built.  But now the build fails with the following
error:

> Task :graphics:compileJava FAILED
You specified both --module-source-path and a sourcepath. These options are
mutually exclusive. Ignoring sourcepath.
error: option --upgrade-module-path cannot be used together with --release
Usage: javac  
use --help for a list of possible options

FAILURE: Build failed with an exception.

I'm not sure why I would be seeing this error if the build is working for
everyone else.  I'm using JDK 19.

Any hints?

Btw, the Mac section of
https://wiki.openjdk.org/display/OpenJFX/Building+OpenJFX still mentions
needing Mercurial.  I don't think that's true anymore.

Regards,

Scott


Re: CSS Color functions

2023-01-17 Thread Scott Palmer
I don't disagree.  It's a minor thing that I can workaround for now.
I would like to see improved support for CSS standards though. From
the little reading I did, it seems full CSS compliance would be very
complex, so I'm not sure what level of support to expect in JavaFX.
Standard functions for deriving colors though would be welcome.

Scott

On Tue, Jan 17, 2023 at 12:34 PM Michael Strauß 
wrote:

> I don't think it makes a lot of sense to add even more non-standard
> functions to JavaFX CSS. Instead we should work towards bringing our
> implementation closer to the web standard.
> You wrote that it might not be worth to wait for the standard; does
> that mean that you'd get a lot of value from this proposed feature?
> Improving one line of code in Modena.css is probably not enough
> justification.
>
> On Sun, Jan 15, 2023 at 1:31 AM Scott Palmer  wrote:
> >
> > I was looking at Modena.css and came across this:
> >
> > /* A bright blue for the focus indicator of objects. Typically used
> as the
> >  * first color in -fx-background-color for the "focused"
> pseudo-class. Also
> >  * typically used with insets of -1.4 to provide a glowing effect.
> >  */
> > -fx-focus-color: #039ED3;
> > -fx-faint-focus-color: #039ED322;
> >
> > I noticed two things pertaining to -fx-faint-focus-color.  Although I've
> used this form to specify colors myself, the JavaFX CSS Reference Guide at
> https://openjfx.io/javadoc/19/javafx.graphics/javafx/scene/doc-files/cssref.html#typecolor
> does not mention being able to use an 8-digit form of #rrggbbaa when using
> hex digits. Only the 3- and 6-digit forms of hexadecimal RGB are mentioned.
> RGB + Alpha colors are only documented in the form of rgba(#,#,#,#) and
> rgba(#%,#%,#%,#).
> >
> > More importantly, this is a copy of -fx-focus-color with an added alpha
> channel, but it's created by repeating the literal color value and
> appending the alpha component, rather than somehow deriving it from
> -fx-focus-color.  Similar repetition is needed for the semi-transparent
> chart colors.
> >
> > Would it make sense to add support for something similar to derive(
>  , % ) to specify a color based on an existing color with a
> new value for the alpha channel (or any other) value? Maybe a
> color-transform method that would do for an RGBA color vector what other
> transforms do for spatial coordinates?*
> >
> > Regards,
> >
> > Scott
> >
> > * Note: It seems future CSS standards are looking for ways to do similar
> things.  A color-mod function was proposed in
> https://www.w3.org/TR/2016/WD-css-color-4-20160705/#funcdef-color-mod but
> removed in the next revision
> https://www.w3.org/TR/2022/CRD-css-color-4-20221101/#changes-from-20160705.
> I'm not following CSS development closely, but some googling suggests the
> next proposal is based on a new keyword 'from' to create derived colors.
> E.g rgb(from skyblue, 255 g b) to get a color based on skyblue with a red
> component of 255.  This is mentioned here
> https://github.com/w3c/csswg-drafts/issues/3187#issuecomment-499126198
> I'm skeptical that it is worth waiting for the dust to settle on the CSS
> standard, but supporting whatever they come up with is a possibility.
> >
>


CSS Color functions

2023-01-14 Thread Scott Palmer
I was looking at Modena.css and came across this:

/* A bright blue for the focus indicator of objects. Typically used as
the
 * first color in -fx-background-color for the "focused" pseudo-class.
Also
 * typically used with insets of -1.4 to provide a glowing effect.
 */
-fx-focus-color: #039ED3;
-fx-faint-focus-color: #039ED322;

I noticed two things pertaining to -fx-faint-focus-color.  Although I've
used this form to specify colors myself, the JavaFX CSS Reference Guide at
https://openjfx.io/javadoc/19/javafx.graphics/javafx/scene/doc-files/cssref.html#typecolor
does
not mention being able to use an 8-digit form of #rrggbbaa when using hex
digits. Only the 3- and 6-digit forms of hexadecimal RGB are mentioned. RGB
+ Alpha colors are only documented in the form of rgba(#,#,#,#) and
rgba(#%,#%,#%,#).

More importantly, this is a copy of -fx-focus-color with an added alpha
channel, but it's created by repeating the literal color value and
appending the alpha component, rather than somehow deriving it from
-fx-focus-color.  Similar repetition is needed for the semi-transparent
chart colors.

Would it make sense to add support for something similar to derive( 
, % ) to specify a color based on an existing color with a new
value for the alpha channel (or any other) value? Maybe a color-transform
method that would do for an RGBA color vector what other transforms do for
spatial coordinates?*

Regards,

Scott

* Note: It seems future CSS standards are looking for ways to do similar
things.  A color-mod function was proposed in
https://www.w3.org/TR/2016/WD-css-color-4-20160705/#funcdef-color-mod but
removed in the next revision
https://www.w3.org/TR/2022/CRD-css-color-4-20221101/#changes-from-20160705.
I'm not following CSS development closely, but some googling suggests the
next proposal is based on a new keyword 'from' to create derived colors.
E.g rgb(from skyblue, 255 g b) to get a color based on skyblue with a red
component of 255.  This is mentioned here
https://github.com/w3c/csswg-drafts/issues/3187#issuecomment-499126198  I'm
skeptical that it is worth waiting for the dust to settle on the CSS
standard, but supporting whatever they come up with is a possibility.


JavaFX Font support for Emojis

2023-01-01 Thread Scott Palmer
I’ve been experimenting, trying to figure out a cross-platform way of 
displaying emojis in a JavaFX application.  It has been interesting.

I tested on macOS and Windows 11. On macOS I explicitly set the font to “Apple 
Color Emoji”, on Windows 11, I used “Segoe UI Emoji”.  Those appear to be the 
standard fonts for emojis on the respective platforms.
 
On macOS with JavaFX, emojis render in monochrome with shades of grey, smaller 
than they should be and shifted down slightly, sometimes cropping off the 
bottom pixels.  With Swing (via SwingPane) they render in full colour the same 
as native applications.

On Windows with JavaFX the emoji is rendered in black and white (no shading) 
for both JavaFX and Swing.  This is the same as how WordPad renders them, but 
different than Microsoft Word, which will show the emojis in full colour. The 
emojis are the right size and not vertically shift as they are on macOS.

If I set the font to something else, I used “Fira Code” that I downloaded so it 
should be the exact same on both platforms, I get different behaviour.  
On Windows 11 with JavaFX the \uFE0F combining character that indicates the 
previous character should be rendered as an emoji causes a blocked ? to print 
after a non-emoji heart character. (To get a “Red Heart” emoji I am using the 
standard Unicode heart “\u2764” followed by "\uFE0F”.)
Swing on macOS still renders full colour emojis, but on Windows 11 it claims it 
can’t render the emoji characters at all - sure enough 
java.awt.Font.canDisplay(codePoint) returns true on macOS and false on Windows 
11, even though the font is the same.  

If I use a logical font, e.g. “Monospaced”, Swing renders the emojis the same 
as when using the explicit emoji font on both platforms, as does JavaFX on 
macOS. However, JavaFX on Windows 11 still prints the blocked ? for \uFE0F.

So a few questions:

Can JavaFX render full colour emojis? Is the greyscale rendering on macOS 
intentional?
Presumably the smaller scale and vertical shift on macOS are bugs?
Can Swing on Windows render emojis in colour like it does on macOS?
(Btw, SwingPane on Windows 11 doesn’t paint at all until it is “provoked” with 
some sort of event, like dragging the window so it is partially obscured.)

And finally, is there any hope to get cross-platform support for full colour 
emojis in a JavaFX application via Text nodes, or would it be best to abandon 
the idea altogether and use Image nodes for them instead?

Regards,

Scott

Re: Concatenated observable list

2022-12-31 Thread Scott Palmer
+1 to doing something like this. I just recently discovered FXCollections.concat(ObservableList…) doesn’t do what you propose. I figured that was the whole point.ScottOn Dec 31, 2022, at 3:44 PM, Nir Lisker  wrote:We can do better than that. Instead of introducing methods for specific operations, like concat and retain, we can offer bulk operations on collections. When John H. proposed the fluent bindings additions, we discussed doing the same for collections after that.At the very least, we can have a method that takes an observable collection and a function that specifies the operation you want to perform. This will be a lot more flexible.I have been playing around with adding ObservableCollection as a first step so that we don't need to multiply the methods for sets and lists. It's also useful for an observableValues() on ObservableMap. I hit a few backwards compatibility issues there.I can share later some mock API I created as a sort of end goal, but it's incomplete.On Sat, Dec 31, 2022 at 8:15 PM Michael Strauß  wrote:FXCollections.concat(ObservableList...) can be used to create a new
ObservableList that contains the concatenation of all elements of the
source lists. This is useful to initialize the contents of the new
ObservableList, but the returned list is not kept in sync with the
source lists.

I'm proposing to add a new method:
FXCollections.concatenatedObservableList(ObservableList...)

Like FXCollections.concat, it returns a list that contains the
concatenation of all elements of the source lists. However, in this
case the returned list is unmodifiable and is always kept in sync with
the source lists. This can be useful to create a list where only parts
of the list are under the control of the author, and other parts are
derived from other lists.

I'm interested to hear your thoughts on this. Here's the proposed
specification of the new method:

/**
 * Creates a new unmodifiable {@code ObservableList} that contains
 * the concatenation of the contents of the specified observable lists.
 * In contrast to {@link #concat(ObservableList[])}, the list returned from
 * this method is updated when any of the source lists are changed.
 *
 * @param lists the source lists
 * @param  the element type
 * @return an {@code ObservableList} that contains the concatenation
 *         of the contents of {@code lists}
 * @throws IndexOutOfBoundsException if the sum of the number of
 *         elements contained in all source lists exceeds
 *         {@link Integer#MAX_VALUE}
 */
@SafeVarargs
public static  ObservableList concatenatedObservableList(
        ObservableList... lists)



Re: Node.lookupAll behaves differently before Scene is shown

2022-12-25 Thread Scott Palmer
Items added to a control like ListView, TableView, TreeView, are of an arbitrary type and are rendered via a CellFactory, not added as Nodes.  (And in fact, as recent clarifications to the Javadoc mention, Nodes as items in the lists are strongly discouraged.). The items of a SplitPane are explicitly Nodes. So it isn’t quite the same, but I get your point.I think if anything a clarification in the Javadoc would help.  I suspect changing the behaviour of lookup/lookupAll might be more problem than it is worth.In my application, I’ve worked around the issue by deferring the call until the CSS has been applied through the usual flow, but I can confirm that explicitly calling applyCss() is also a valid workaround.ScottOn Dec 24, 2022, at 7:05 PM, John Hendrikx  wrote:
  

  
  
One thing you could try still, whether acceptable or not, is to
  call `applyCss` on the border pane before calling the count
  function.
As for the "and any children", I'm not sure how you should
  interpret that.  For a SplitPane, the nodes that are part of it
  are in the items list (you don't add them as actual children). 
  The example in split pane also does something like
  `splitPane.getItems().addAll(x, y, z)`. 

Same may apply to items in a List / Table / TreeView -- are they
  children?

--John

On 24/12/2022 19:09, Scott Palmer
  wrote:


  
  That’s interesting.  It leads me to wonder what is the expected
  result from a call to lookupAll in various scenarios.  If, after
  the window was showing, the SplitPane divider is pushed all the
  way to one size such that the skin can potentially choose to leave
  the hidden child out of the scene graph, presumable the current
  lookupAll implementation would then fail to find it again.
  
  
  I think that either that’s a bug, or it needs to be made
clearer in the documentation that non-rendered child nodes may
not be found.  I personally lean toward “bug”, as I think any
Node reachable through a parent Node’s public API to access
child nodes should be found via Node.lookupAll.  I suppose you
could argue that Scene.lookup is searching the scene graph in a
more literal sense and wouldn’t find some Nodes.
  
  
  The docs for Scene.lookup say:
  	"Looks
for any node within the scene graph based on the specified CSS
selector.”
  

  The docs for Node.lookup say:
  	"Finds
this Node, or the first sub-node, based on the given CSS
selector”
  
  
  The docs for Node.lookupAll say:
  	"Finds
all Nodes, including this one and any children, which
match the given CSS selector."
  
It doesn’t mention the scene graph or if the node is
  currently being rendered in a visible portion of the scene.
   It explicitly states “any children”.


So I’m saying it’s a bug.




Scott

  
On Dec 24, 2022, at 3:34 AM, John Hendrikx
   wrote:


  
  
Hi,

In this case, this is because SplitPane doesn't
  actually add its split items as children -- only its
  Skin does this.  Skins are AFAIK installed after a CSS
  pass.
In the split pane case, I guess a Skin could choose
  to completely leave out a child if its splitter
  completely hides it (ie, dragged all the way to the
  left or right if allowed).
This may be another case where it may make sense to
  have both a document graph (logical graph) and a scene
  graph as Michael Strauss mentioned here: https://mail.openjdk.org/pipermail/openjfx-dev/2022-June/034417.html
I doubt this is documented anywhere at all, it's one
  of those things that doesn't work quite right in
  JavaFX before a Scene is displayed.

--John

    On 23/12/2022 23:49, Scott
  Palmer wrote:


  
  I just want to make sure this is not expected
  behaviour. I don’t think so, the documentation for
  lookupAll doesn’t mention anything related, but maybe
  I missed something somewhere else.
  
I was just coding something to query the Scene
  for all SplitPanes and save/restore the divider
  positions for when my application is exiting and
  launching and came across this issue.

Re: Node.lookupAll behaves differently before Scene is shown

2022-12-24 Thread Scott Palmer
That’s interesting.  It leads me to wonder what is the expected result from a 
call to lookupAll in various scenarios.  If, after the window was showing, the 
SplitPane divider is pushed all the way to one size such that the skin can 
potentially choose to leave the hidden child out of the scene graph, presumable 
the current lookupAll implementation would then fail to find it again.

I think that either that’s a bug, or it needs to be made clearer in the 
documentation that non-rendered child nodes may not be found.  I personally 
lean toward “bug”, as I think any Node reachable through a parent Node’s public 
API to access child nodes should be found via Node.lookupAll.  I suppose you 
could argue that Scene.lookup is searching the scene graph in a more literal 
sense and wouldn’t find some Nodes.

The docs for Scene.lookup say:
"Looks for any node within the scene graph based on the specified CSS 
selector.”

The docs for Node.lookup say:
"Finds this Node, or the first sub-node, based on the given CSS 
selector”

The docs for Node.lookupAll say:
"Finds all Nodes, including this one and any children, which match the 
given CSS selector."

It doesn’t mention the scene graph or if the node is currently being rendered 
in a visible portion of the scene.  It explicitly states “any children”.

So I’m saying it’s a bug.


Scott

> On Dec 24, 2022, at 3:34 AM, John Hendrikx  wrote:
> 
> Hi,
> 
> In this case, this is because SplitPane doesn't actually add its split items 
> as children -- only its Skin does this.  Skins are AFAIK installed after a 
> CSS pass.
> 
> In the split pane case, I guess a Skin could choose to completely leave out a 
> child if its splitter completely hides it (ie, dragged all the way to the 
> left or right if allowed).
> 
> This may be another case where it may make sense to have both a document 
> graph (logical graph) and a scene graph as Michael Strauss mentioned here: 
> https://mail.openjdk.org/pipermail/openjfx-dev/2022-June/034417.html
> 
> I doubt this is documented anywhere at all, it's one of those things that 
> doesn't work quite right in JavaFX before a Scene is displayed.
> 
> --John
> 
> On 23/12/2022 23:49, Scott Palmer wrote:
>> I just want to make sure this is not expected behaviour. I don’t think so, 
>> the documentation for lookupAll doesn’t mention anything related, but maybe 
>> I missed something somewhere else.
>> 
>> I was just coding something to query the Scene for all SplitPanes and 
>> save/restore the divider positions for when my application is exiting and 
>> launching and came across this issue.
>> My UI is fully constructed (at least in terms of all the SplitPanes in the 
>> scene graph) before it is shown.
>> 
>> This  code:
>> 
>>  window.getScene().getRoot().lookupAll(".split-pane")
>> 
>> returns a different number of Nodes if I call it before showing the window 
>> versus after showing the window.  Specifically, if I call it before showing 
>> the window it appears to only return the first SplitPane found in the scene 
>> graph, but calling it in an event handler for the window shown event I get 
>> all three.
>> 
>> This can be demonstrated with the following program:
>> 
>> 
>> import javafx.application.Application;
>> import javafx.scene.Scene;
>> import javafx.scene.control.SplitPane;
>> import javafx.scene.control.TextArea;
>> import javafx.scene.layout.BorderPane;
>> import javafx.stage.Stage;
>> import javafx.stage.Window;
>> 
>> public class LookupAll extends Application {
>> Window mainWindow;
>> 
>> public static void main(String[] args) {
>> launch(args);
>> }
>> 
>> @Override
>> public void start(Stage primaryStage) throws Exception {
>> var bp = new BorderPane(new SplitPane(new TextArea(),new 
>> SplitPane(new TextArea(),new SplitPane(new TextArea();
>> var scene = new Scene(bp);
>> primaryStage.setScene(scene);
>> mainWindow = primaryStage;
>> System.out.println("Before showing:");
>> countSplitPanes();
>> primaryStage.setOnShown(we -> {
>> System.out.println("After showing:");
>> countSplitPanes();
>> });
>> primaryStage.show();
>> }
>> 
>> private void countSplitPanes() {
>> var splitPanes = 
>> mainWindow.getScene().getRoot().lookupAll(".split-pane");
>> System.out.printf("Found %d SpitPanes: %s\n",splitPanes.size(), 
>> splitPanes);
>> }
>> }
>> 
>> 
>> 
>> Before showing:
>> Found 1 SpitPanes: [SplitPane@16bca2d9[styleClass=split-pane]]
>> After showing:
>> Found 3 SpitPanes: [SplitPane@16bca2d9[styleClass=split-pane], 
>> SplitPane@7078ef3c[styleClass=split-pane], 
>> SplitPane@56a29626[styleClass=split-pane]]
>> 
>> 
>> Regards,
>> 
>> Scott
>> 



Node.lookupAll behaves differently before Scene is shown

2022-12-23 Thread Scott Palmer
I just want to make sure this is not expected behaviour. I don’t think so, the 
documentation for lookupAll doesn’t mention anything related, but maybe I 
missed something somewhere else.

I was just coding something to query the Scene for all SplitPanes and 
save/restore the divider positions for when my application is exiting and 
launching and came across this issue.
My UI is fully constructed (at least in terms of all the SplitPanes in the 
scene graph) before it is shown.

This  code:

window.getScene().getRoot().lookupAll(".split-pane")

returns a different number of Nodes if I call it before showing the window 
versus after showing the window.  Specifically, if I call it before showing the 
window it appears to only return the first SplitPane found in the scene graph, 
but calling it in an event handler for the window shown event I get all three.

This can be demonstrated with the following program:


import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.stage.Window;

public class LookupAll extends Application {
Window mainWindow;

public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage primaryStage) throws Exception {
var bp = new BorderPane(new SplitPane(new TextArea(),new SplitPane(new 
TextArea(),new SplitPane(new TextArea();
var scene = new Scene(bp);
primaryStage.setScene(scene);
mainWindow = primaryStage;
System.out.println("Before showing:");
countSplitPanes();
primaryStage.setOnShown(we -> {
System.out.println("After showing:");
countSplitPanes();
});
primaryStage.show();
}

private void countSplitPanes() {
var splitPanes = 
mainWindow.getScene().getRoot().lookupAll(".split-pane");
System.out.printf("Found %d SpitPanes: %s\n",splitPanes.size(), 
splitPanes);
}
}



Before showing:
Found 1 SpitPanes: [SplitPane@16bca2d9[styleClass=split-pane]]
After showing:
Found 3 SpitPanes: [SplitPane@16bca2d9[styleClass=split-pane], 
SplitPane@7078ef3c[styleClass=split-pane], 
SplitPane@56a29626[styleClass=split-pane]]


Regards,

Scott



Dialog Resizing

2022-11-30 Thread Scott Palmer
I just noticed that Dialogs set to be resizable don’t have any constraints on 
min/max size.  So no min/max size properties on Dialog, nor does it limit 
resizing to within the constraints of the DialogPane.

Am I missing something, or shall I file an enhancement request?

Scott

Re: Discussion: Naming API method

2022-11-21 Thread Scott Palmer
I like "when" (partly because it is short and to the point, Java is already
verbose enough.)

I also thought of "trackWhile" to indicate the value is only tracking the
value of the source ObservableValue while the condition is true.

Scott


On Mon, Nov 14, 2022 at 12:47 PM Andy Goryachev 
wrote:

> I'd pick "whenever" or "onCondition".
>
>
>
> "updateWhen" sounds like an update, which I think it is not.  "when" seems
> too vague.
>
>
>
> Disclaimer: English is not my native language.
>
>
>
> -andy
>
>
>
>
>
> *From: *openjfx-dev  on behalf of Kevin
> Rushforth 
> *Date: *Monday, 2022/11/14 at 09:40
> *To: *openjfx-dev@openjdk.org 
> *Subject: *Re: Discussion: Naming API method
>
> I also think this will be a useful feature to get into JavaFX.
>
> As for the name of the method, the only one of them I don't like is
> "conditionOn". That name doesn't suggest (to me anyway) what its purpose
> is. I think any of the ones with "when" in the name would work. I have a
> slight preference for "updateWhen", but could be talked into one of the
> others.
>
> -- Kevin
>
>
> On 11/14/2022 6:52 AM, John Hendrikx wrote:
> > Hi,
> >
> > I'm working on https://github.com/openjdk/jfx/pull/830 where I asked
> > for some opinions on the naming of a new method I'd like to introduce
> > in ObservableValue.
> >
> > I wrote a (perhaps too large) comment about the possible names and
> > rationales:
> > https://github.com/openjdk/jfx/pull/830#issuecomment-1304846220
> >
> > I'd like to ask what others think what would be a good name for this
> > new method (Observable#when in the PR) in order to move the PR
> > forward, as I think it offers a very compelling feature to JavaFX
> > (moving from weak reference to deterministic behavior when it comes to
> > listener management).  My opinion has always been that using weak
> > listeners for listener management is a crutch that relies far too much
> > on the internal workings of the JVM and Garbage Collector which offer
> > no guarantees as to the timely clean up of these references and the
> > listeners related to them.
> >
> > Leading contenders are (but not limited to these, if you have a better
> > name):
> >
> > 1) conditionOn
> >
> > 2) updateWhen
> >
> > 3) when
> >
> > 4) whenever
> >
> > Usage in code is nearly always going to be something like these
> > constructs:
> >
> >   // keeps text property in sync with longLivedProperty when label
> > is shown:
> >
> label.textProperty().bind(longLivedProperty.**when**(label::isShownProperty));
>
> >
> >
> >   // keeps text property in sync with longLivedProperty when
> > container is shown:
> >
> label.textProperty().bind(longLivedProperty.**when**(container::isShownProperty));
>
> >
> >
> > It can also be used to make a listener only actively listen when a
> > condition is met (the listener is added/removed immediately when the
> > condition changes, facilitating GC):
> >
> >   // listen to changes of longLivedProperty when container is shown:
> >   longLivedProperty.when(container::isShownProperty)
> > .addListener((obs, old, current) -> { ... change listener
> > ... });
> >
> > Or it can be used to disable updates temporarily (or permanently):
> >
> > BooleanProperty allowUpdates = new SimpleBooleanProperty(true)
> >
> > // keeps text property in sync when updates are allowed:
> > name.textProperty().bind(model.title.when(allowUpdates));
> > detail.textProperty().bind(model.subtitle.when(allowUpdates));
> >
> asyncImageProperty.imageHandleProperty().bind(model.imageHandle.when(allowUpdates));
>
> >
> >
> > This last example can be useful in Skin#dispose, but has uses outside
> > of skins as well, for example when you want to prevent updates until
> > things have settled down.
> >
> > Thanks for reading!
> >
> > --John
> >
> >
>


Re: Signing shared libraries and questions about loading

2022-11-21 Thread Scott Palmer
This is why I suggested long ago that there should be .jmod zips in Maven 
central or similar.  We need a dependency management system that works with 
JMODs for exactly this reason. Zips in the current public repos would work.

Scott

> On Nov 21, 2022, at 11:08 AM, Armin Schrenk  wrote:
> 
> Oh, thanks, didn't knew that. I tried the JMOD files provided by Gloun 
> company with a local build. Works!
> 
> But how can this be integrated into an automatic/CI build? Using a more or 
> less arbitrary url pointing to a third-party website downloading a zip file 
> of unknown structure would result in a "ducktape build" and is not very 
> resilient against any changes. Furthermore, some build systems (i.e., 
> ubuntu-ppa) do not allow external downloads.
> 
> Does automatic build examples exist which are jlinking JFX to a custom JRE?
> 
> Best wishes,
> 
> Armin
> 
> Am 16/11/2022 um 15:39 schrieb Kevin Rushforth:
>> Leaving aside the question of signed libraries, if you are using jpackage / 
>> jlink to create a custom Java runtime with the JavaFX modules, then you 
>> should use the JMODs bundles and not the artifacts from Maven central. The 
>> maven modules are a handy convenience for developers, but not recommend for 
>> creating packaged applications.
>> 
>> -- Kevin
>> 
>> 
>> 
>> 
>> On 11/16/2022 6:29 AM, Armin Schrenk wrote:
>>> Hello,
>>> 
>>> for our application, a customer reported that the shared libraries (in this 
>>> case DLLs) used by JFX are unsigned and thus were blocked from loading, 
>>> which blocks the app from starting. The culprit for blocking is a new 
>>> security feature for Windows 11, Smart App Control 
>>> (https://support.microsoft.com/en-gb/topic/what-is-smart-app-control-285ea03d-fa88-4d56-882e-6698afdb7003).
>>>  Since this feature seems to be a future part of Windows, i suggest to sign 
>>> the shared libs before the maven release. In our case, the archive 
>>> javafx-graphics-*-win.jar contains the DLLs.
>>> 
>>> Apart from this feature request, we want to fix the issue on our side. To 
>>> do that, I investigated into the sharedLib loading of JFX.
>>> 
>>> SharedLib Loading is in JFX is done with the NativeLibLoader 
>>> (https://github.com/openjdk/jfx/blob/19+11/modules/javafx.graphics/src/main/java/com/sun/glass/utils/NativeLibLoader.java).
>>>  It does the following to load the native lib:
>>> 
>>> 1. Load the DLLs from a certain path (see below)
>>> 2. On Failure, load the DLLs from a resource (aka the jar) by extracting 
>>> them to a cache directory and load them from there
>>> 3. On Failure, do other stuff not of interest
>>> 
>>> Our app is modular (or as much as possible), thus, the DLLs were always 
>>> loaded from the resource. But this extract-and-cache approach is 
>>> unsatisfying from our point of view. The app uses a custom JRE via jlink 
>>> and is packaged with jpackage, and we would like to place the sharedLibs at 
>>> build time somewhere in the app directory.
>>> 
>>> So I had to figure out the where to place the DLLs, or more specifically, 
>>> what path is checked in Step 1 of shared libLoading. Reading the inline 
>>> comment starting at line 117, it should be the same dir as the jar is 
>>> placed. Unfortunately, this is not the case and i had to dig more through 
>>> the code to find out.
>>> 
>>> Our app has the following structure:
>>> |- JarsAndMods
>>> | - Mods
>>> | - modul1.jar
>>> | - modul2.jar
>>> | - ...
>>> | - javafx-graphics-XXX-win.jar
>>> | - ...
>>> | - nonModular1.jar
>>> | - nonModular2.jar
>>> | - ...
>>> |- executable
>>> 
>>> According to the comment, the path to place all DLLs should be 
>>> /JarsAndMods/Mods.
>>> But verbose logging showed and later proofed by the code, it has to be 
>>> /JarsAndMods/bin.
>>> 
>>> My questions are:
>>> 
>>> Why does JFX require only for Windows the `../bin` directory?
>>> 
>>> Additionally, this inline comment has a FIXME that Step 1 of 
>>> SharedLibLoading should be removed in the future. Is there already an ETA?
>>> 
>>> And lastly, I would love to see some Documentation for this. I can write it 
>>> and create the PR, but where should it be placed?
>>> 
>>> 
>>> Best wishes,
>>> 
>>> Armin
>>> 
>> 



Re: Virtual Flow enhancements

2022-10-28 Thread Scott Palmer
While reading this I was thinking of a similar, but not quite the same use
case.  A visual Diff program that is showing two versions of the same
source file side-by-side.  Scrolling both views in a synchronized way such
that lines that are the same are aligned is a common feature, but since one
file may have a different number of lines the two sides won't scroll
exactly the same amount to keep the views where you want them. Regardless,
the need for exact positioning between the two views exists.  I haven't
attempted to do this yet, but it is something that may come up soon in a
project I'm working on.  Knowing any relevant tricks or gotcha cases will
be helpful.

Cheers,

Scott

On Fri, Oct 28, 2022 at 8:43 AM Dirk Lemmermann 
wrote:

> Looks like I missed this last replay from Johan. In my last email I was
> referring to a work-around where one VirtualFlow gets repositioned via
> scrollTo() method calls in response to changes in the other VirtualFlow.
> Not only are the rows alignments way off but updates are lagging behind.
>
> But let’s leave that behind for now and let’s try to find an existing
> property that would make our use-case work again.
>
> For the “FlexGanttFX” use-case where I need to syncronize  the scrolling
> of a TreeTableView and a ListView I would love to be able to simply bind
> the “position” properties of those two controls with each other. That feels
> very intuitive to me. If both controls have the same number of rows and
> each row’s height matches the row’s height in the other control then this
> should work, but currently it does not.
>
> The “position” property gets updated by the VirtualFlow. When the flow
> sets this property to a certain value then I would hope setting the same
> value from outside would place the virtual flow at the exact same position.
> Basically I am hoping that this is a bijective mapping but it is not ….
> unless … the user scrolled all the way down in both views. Then it becomes
> a bijective mapping. So I guess after having made all rows visible the
> calculations are based on hard facts (as in “actual row height”) and not on
> estimates.
>
> To summarise the requirement: there should be a way to bind a property of
> VirtualFlow so that two instances with the same content can be scrolled in
> sync (content = same rows with same heights resulting in same total virtual
> height).
>
> Dirk
>
> On 15 Sep 2022, at 21:20, Johan Vos  wrote:
>
>
>
> On Wed, Sep 14, 2022 at 12:19 PM Dirk Lemmermann 
> wrote:
>
>> Hi,
>>
>>
>> FlexGanttFX used to make this work via bidirectional bindings of the
>> properties of the vertical scrollbars of both VirtualFlows. With the latest
>> fixes to the VirtualFlow the assumption that two identically populated
>> VirtualFlows would provide identical values to the ScrollBar properties is
>> no longer true. The attempt to bind the “position” property also failed and
>> a work-around that Johan provided also has not been successful, yet (a
>> customer of mine is still evaluating it).
>>
>
> I don't know what work-around you refer to, but I often point to public
> methods in VirtualFlow that, when properly combined, allow many usecases. I
> sometimes see code where the information about the positioning of elements
> in the VirtualFlow is obtained via the position of the scrollbar thumb,
> which seems a really odd way to get this info (and especially unreliable as
> the relation with the real positioning of cells is unspecified). There are
> other methods on VirtualFlow that imho are better suited for
> getting/setting information.
> What I want to avoid is that we have 2 API's that almost achieve the same.
> Hence, before considering a new method or property, I think we should make
> sure that there is currently no existing (documented) way to achieve it. I
> am pretty sure there are cases that can not be solved with the existing set
> of API's, and those cases are exactly what I'm looking for.
>
> - Johan
>
>
>
>


Re: Support for Ligatures

2022-10-24 Thread Scott Palmer
I guess everything you’ve written below about querying and requesting features 
still falls into the hole of “stuff we could do with Swing, but can’t do with 
JavaFX”.  I don’t use Swing anymore, but every once in a while I run into one 
of these issues. There are workarounds for some, like NSMenuFX to get proper 
menu support on macOS, or using AWT Desktop support in combination with JavaFX 
to get the missing support for the system tray, dock, opening documents with 
the OS-defined default handler, etc... but it’s less than ideal.   However, 
this issue doesn’t appear to have any workaround.

I did a quick search in the JavaFX code for ligature support and it seems there 
is quite a bit of incomplete support in many parts of the font processing.  
E.g. com.sun.javafx.scene.control.skin.Utils contains the commented out block 
that appears to be from older AWT code:

private static boolean requiresComplexLayout(Font font, String string) {
/*Map attrs = font.getAttributes();
   if (contains(attrs, KERNING, KERNING_ON) ||
   contains(attrs, LIGATURES, LIGATURES_ON) ||
   (attrs.containsKey(TRACKING) && attrs.get(TRACKING) != null)) {
   return true;
   }
   return isComplexLayout(string.toCharArray(), 0, string.length());
 */
return false;
}

So complexLayout is always ‘false', which is good because where it is used the 
path for 'true' looks like:
if (complexLayout) {
// TODO needs implementation
return 0;
} else {


com.sun.javafx.font.FontResources defines a bunch of constants related to 
ligatures, but they don’t appear to be used anywhere.  Looks like they are 
intended for the value returned by getFeatures() in FontResource and PGFont.

com.sun.javafx.font.PrismFont and the interface it implements PGFont (what does 
PG stand for?) defines a getFeatures method:
/*
 * Returns the features the user has requested.
 * (kerning, ligatures, etc)
 */
@Override public int getFeatures() {
return features;
}

but features is always 0, with no means to set it.

com.sun.javafx.text.GlyphLayout where ‘features’ is used in two places compares 
the features of Font to FontResource. PrismFont defaults to 0, and the 
PrismFontFile implementation of FontResource returns -1, so for GlyphLayout  
the supported features are always “everything” and the requested features are 
always “nothing”, so boolean feature = false, always. This is used to compute 
‘complex’ (initially false)
if (!complex) {
complex = feature || 
ScriptMapper.isComplexCharCode(codePoint);
}
So ScriptMapper is the only thing really deciding what’s ‘complex’… which seems 
to bring me back to what you’ve stated, that required ligatures like those 
needed for Arabic are supported.  Now I wonder if ‘feature’ was true would my 
Fira Code experiment render correctly or is there a lot more to it than that?

It seems there is some otherwise ‘dead’ code already in place to support 
requesting these openType features.
Is exposing an API to initialize the features of FontResource enough to get 
some meaningful results?

I was going to try some experiments, but I’m unable to build OpenJFX on my Mac 
for some reason:

> > Task :graphics:compileJava FAILED
> You specified both --module-source-path and a sourcepath. These options are 
> mutually exclusive. Ignoring sourcepath.
> error: option --upgrade-module-path cannot be used together with --release
> Usage: javac  
> use --help for a list of possible options

 (using JDK 17 running a simple ./gradlew)
I didn’t have trouble when I last built it a couple years ago, so I’m not sure 
what’s changed.

Cheers,

Scott

> On Oct 24, 2022, at 3:43 PM, Philip Race  wrote:
> 
> FX does (of course) support required ligatures, meaning those without which 
> some script (eg Arabic)
> can't even be rendered.
> 
> But that is implementation, no API.
> 
> So this is about adding an API to request optional ligatures - and other 
> OpenType features.
> For example I think we'd want to support things like small caps etc.
> 
> Of course we'd need to make sure all the measuring code is up to that .. and 
> BTW
> the APIs to do measurement probably should be in the queue ahead of this ..
> 
> And I am not sure about just an API to request ligatures without an API to 
> query
> if ligatures are available for a font. However that may turn out to be tricky 
> for a
> few reasons, but we should at least study it.
> 
> And to try to answer the "when" question .. it is on a "desired" list in my 
> head and maybe
> even on a wiki somewhere .. but no concrete timetable exists.
> 
> But it is good to get feedback like this so we know it is interesting to 
> developers.
> 
> -phil.
&g

Support for Ligatures

2022-10-24 Thread Scott Palmer
Something I noticed while experimenting with RichTextFX, when I set it to use 
Fira Code for the font, like I do in NetBeans, I see that JavaFX doesn't 
support ligatures.  I found this issue that's been around for quite some time:
https://bugs.openjdk.org/browse/JDK-8091616

Is there any drive to get this implemented within the next few releases?  I 
would help, but unfortunately I suspect it will take more time than I can 
commit to it.
I’m hoping that eliminating some of the remaining gaps between what JavaFX 
supports and Swing supports would be a priority, as it removes some barriers to 
JavaFX adoption... but maybe not?

Regards,

Scott

Re: Provide Quit handler for system menu bar

2022-09-20 Thread Scott Palmer
I always understood Alt+F4 as simply being a keyboard shortcut on Windows for 
closing the window of the active application.  The same as clicking the close 
widget.  I don’t think there is anything special about it.  As far as being an 
equivalent to the macOS Quit action, I don’t think it is quite the same. Does 
an application even know the difference between a window closed with the widget 
vs. Alt+F4? CTRL+F4 closes the current document window or tab - similar to 
Command-W on macOS. 

I’m not aware of any special handlers being called on Windows for these 
shortcuts other than what is called when the equivalent close widget is 
pressed. If I’m wrong about that, then sure, a quit handler for JavaFX could be 
wired in to the same mechanism automatically.  Maybe Linux has an equivalent as 
well, I don’t know.

While we are at it, custom handling for the ‘About’ menu item in the 
application menu is also needed, is it not?  

For now I’m currently using Jan Gassen’s port of NSMenuFX to hook into this 
stuff. https://github.com/0x4a616e/NSMenuFX


Scott

> On Sep 20, 2022, at 5:55 AM, John Hendrikx  wrote:
> 
> 
> What about Alt + F4 and Ctrl + F4 on Windows?  Alt + F4 closes the 
> application (which works with JavaFX already) and Ctrl + F4 is supposed to 
> close a single window, but that doesn't work for JavaFX.
> 
> Also very much in favor of Keeping the API platform neutral, that's just how 
> Java has worked since its inception.
> 
> --John
> 
> On 20/09/2022 06:25, Scott Palmer wrote:
>> Windows applications often have an “Exit” menu item, but since it isn’t 
>> standardized like it is on macOS, calling a quit handler for it would need 
>> to be a manual step - but the exact same method for the quit handler could 
>> be called, leaving it up to the programmer to continue or not with the 
>> application exit depending on the return value. This manual coding isn’t a 
>> big deal since you would also need to have some app-specific handling to 
>> avoid making an Exit menu item on macOS, where it would look out of place.  
>> 
>> You could add a standard “requestExit()” method to Platform that you could 
>> manually bind to an Exit menu item on Windows or Linux, but it would be 
>> automatically called via an internal macOS Quit handler implementation.  The 
>> implementation of Platform.requestExit() on *all* platforms would call a 
>> boolean method if one was registered and then conditionally call 
>> Platform.exit() depending on the return value, the default being to always 
>> exit if nothing was registered. On macOS it would pass on the value to veto 
>> the native Quit handler as needed.  I haven’t checked, does 
>> Application.stop() get called on macOS if you exit via the Quit menu or 
>> Command-Q? If it doesn’t, that’s another benefit.  This idea should probably 
>> be opt-in via some API or system property, I suppose it would have to be if 
>> it changes behaviour of having Application.stop() called in some 
>> circumstances. Or you can just make the setting of the handler function the 
>> “opt-in”.
>> 
>> Btw, this reminds me of the long-standing request for system tray support, 
>> along with with various other features that have equivalents across multiple 
>> OS’, like showing progress on the dock icon, or a numbered badge (for 
>> notifications, or unread msgs, etc).  I think there are already issues in 
>> Jira for these, maybe just as a general request to support some features 
>> that AWT/Swing has that JFX is still missing. Most of these features are 
>> available on both Mac and Windows, possibly Linux.  It would be irritating 
>> to code to different APIs for each if it can be avoided, so I agree with 
>> going for a platform-neutral way.
>> 
>> Cheers, 
>> 
>> Scott
>> 
>>> On Sep 19, 2022, at 8:11 PM, Kevin Rushforth  
>>> wrote:
>>> 
>>>  I don't see us adding 100s of OS-specific API calls, but even if we did, 
>>> going down the path of exposing them as Mac APIs or Windows APIs, doesn't 
>>> really seem like the direction we want to go. Whatever we do needs to 
>>> balance the desire to integrate with, e.g., the macOS or Windows platform 
>>> with a desire to leave the door open for it to later be implemented on the 
>>> other platform(s). And the most cross-platform way to do that from an API 
>>> point of view is by defining API that delivers the desired functionality in 
>>> as platform-neutral a way as possible. It also needs to fit cleanly into 
>>> the existing API.
>>> 
>>> So in the specific case of a quit handler, we could define a platform API 
>>> that an app could call to

Re: Provide Quit handler for system menu bar

2022-09-19 Thread Scott Palmer
Windows applications often have an “Exit” menu item, but since it isn’t 
standardized like it is on macOS, calling a quit handler for it would need to 
be a manual step - but the exact same method for the quit handler could be 
called, leaving it up to the programmer to continue or not with the application 
exit depending on the return value. This manual coding isn’t a big deal since 
you would also need to have some app-specific handling to avoid making an Exit 
menu item on macOS, where it would look out of place.  

You could add a standard “requestExit()” method to Platform that you could 
manually bind to an Exit menu item on Windows or Linux, but it would be 
automatically called via an internal macOS Quit handler implementation.  The 
implementation of Platform.requestExit() on *all* platforms would call a 
boolean method if one was registered and then conditionally call 
Platform.exit() depending on the return value, the default being to always exit 
if nothing was registered. On macOS it would pass on the value to veto the 
native Quit handler as needed.  I haven’t checked, does Application.stop() get 
called on macOS if you exit via the Quit menu or Command-Q? If it doesn’t, 
that’s another benefit.  This idea should probably be opt-in via some API or 
system property, I suppose it would have to be if it changes behaviour of 
having Application.stop() called in some circumstances. Or you can just make 
the setting of the handler function the “opt-in”.

Btw, this reminds me of the long-standing request for system tray support, 
along with with various other features that have equivalents across multiple 
OS’, like showing progress on the dock icon, or a numbered badge (for 
notifications, or unread msgs, etc).  I think there are already issues in Jira 
for these, maybe just as a general request to support some features that 
AWT/Swing has that JFX is still missing. Most of these features are available 
on both Mac and Windows, possibly Linux.  It would be irritating to code to 
different APIs for each if it can be avoided, so I agree with going for a 
platform-neutral way.

Cheers, 

Scott

> On Sep 19, 2022, at 8:11 PM, Kevin Rushforth  
> wrote:
> 
>  I don't see us adding 100s of OS-specific API calls, but even if we did, 
> going down the path of exposing them as Mac APIs or Windows APIs, doesn't 
> really seem like the direction we want to go. Whatever we do needs to balance 
> the desire to integrate with, e.g., the macOS or Windows platform with a 
> desire to leave the door open for it to later be implemented on the other 
> platform(s). And the most cross-platform way to do that from an API point of 
> view is by defining API that delivers the desired functionality in as 
> platform-neutral a way as possible. It also needs to fit cleanly into the 
> existing API.
> 
> So in the specific case of a quit handler, we could define a platform API 
> that an app could call to register a handler that gets called if the platform 
> quit menu is selected and is able to cancel the Quit action(basically, that's 
> what is being proposed). We could decide to provide some way for an app to 
> query whether it is supported, but maybe we just don't need to worry about it 
> in this specific case. We could just document that it will get called when 
> the platform quit action is called, if there is such an action on that 
> platform. Other than maybe mentioning in the docs that the macOS system menu 
> "quit" action is an example of an action that would invoke this, it doesn't 
> need to be platform-specific. One question to answer is whether we should 
> just put this in the Platform class (where we have other similar "global" 
> application state), the Application class (which has the life-cycle APIs), or 
> somewhere else (which might make sense if we wanted to define an analog to 
> the AWT Desktop class, although the existing Platform class already has some 
> APIs like this).
> 
> -- Kevin
> 
> 
> On 9/19/2022 1:46 PM, Andy Goryachev wrote:
>> Thank you, Kevin.  Your insightful feedback always pulls the discussion in 
>> the right direction.
>>  
>> The initial problem we are facing is access to Mac menu in general and 
>> additional API specifically.  I can see a possibility of extending the list 
>> of APIs that app devs would want on Mac growing, so there should be a better 
>> way to add them.  Using hacks like com.apple.eawt, or system properties is 
>> probably not the best solution.  Ideally, there should be away that does not 
>> require creative linking of stub classes on non-Mac platforms, i.e. we 
>> should be able to use a single code base for all the platforms.
>>  
>> ConditionalFeature might work well internally for openjfx, but I don't think 
>> it is a good solution for actually exposing the platform APIs to the user.
>>  
>> So, in order to provide platform-specific API in such a way that still 
>> allows for a single code base for multiple platform, and one that 
>> potentially 

Link to Release Notes is broken

2022-09-13 Thread Scott Palmer
The link to the Release Notes at https://openjfx.io/ goes to 
https://github.com/openjdk/jfx/blob/jfx19/doc-files/release-notes-19.md which 
is giving me a 404 error.

It seems the release note files at 
https://github.com/openjdk/jfx/tree/jfx19/doc-files only go up to v18.  
The same folder on the master branch does have the notes for v19 
https://github.com/openjdk/jfx/tree/master/doc-files

Scott



Re: JavaFX Media Enhancements Survey

2022-07-22 Thread Scott Palmer



> On Jul 21, 2022, at 9:48 PM, Alexander Matveev  
> wrote:
> 
> Greetings!
> 
> We are running a little survey to get input on possible JavaFX Media 
> enhancements. Below you can find a list of possible JavaFX Media 
> enhancements, which we might implement in the future, although there is no 
> commitment. We will appreciate if you can rate each enhancement on how 
> useful/important it will be for JavaFX mainline. Put “1" for very important 
> and I need this feature; “2" for looks important, but I am not planning to 
> use it; “3" for not important and I do not need it.
> 
> 1) ID3 metadata support for MP4 files.
> Rating:
3
> 
> 2) Support for multichannel audio rendering (more than 2 channels).
> Rating:
2
> 
> 3) Subtitles support for MP4 files and HTTP Live Streaming.
> Rating:
2
> 
> 4) HDR support.
> Rating:
2
> 
> 5) InputStream for AudioClip with PCM support.
> Rating:
1
> 
> 6) Public APIs to access raw audio and video frames.
> Rating:
1
> 
> 7) Support for multiple audio tracks in MP4 files and alternate audio streams 
> in HTTP Live Streaming provided via #EXT-X-MEDIA tag.
> Rating:
2
> 
> 8) Media recording/capture.
> Rating:
1
> 
> 9) Opus audio codec.
> Rating:
3
> 
> 10) MKV (matroska) file format.
> Rating:
3
> 
> 11) WebM/VP9/Opus
> Rating:
2
> 
> 12) RTSP (Real Time Streaming Protocol)
> Rating:
1
> 
> 13) Pluggable codecs
> Rating:
2
> 
> Please, list any additional media formats (codecs) / protocols you would like 
> to see in upcoming JavaFX releases:
> 
> List any additional media enhancements you consider important to JavaFX Media:

I would like to be able to tap in to various points in the media pipeline. I 
would like to be able to feed the player with entirely synthetic data for 
example. E.g. a test pattern with burnt-in timecode. 
My primary application is a tool for building media processing workflows. I 
currently have to make a separate window in native code to preview the media to 
avoid extensive copying of uncompressed video frames. Most if the media 
processing I’m doing will be in my own native code, but since the UI is JavaFX 
I’m missing convenient points at the input and output stages. It would be great 
to be able to have a simple cross-platform camera and mic input for testing 
live streams (have tried OpenCV but it wasn’t that great). Being able to feed 
raw uncompressed video and audio data to the UI for preview would certainly 
clean up that aspect of the application. 

Cheers,

Scott