In the thread "text properties of treetable cells", we've been discussing use cases for a limited rendering hints API. Here are the use cases I know of so far:
General use cases: - Nodes in explorer views - Properties in the property sheet - Tabs in tabbed windows in the IDE
Use cases where multiple styles in a single line of text would be desirable: - VCS status
Open questions: - How should a renderable object indicate the hints have changed, and that it may need to be re-rendered? - Should a renderable object provide one set of hints for all views, or are per-view sets desirable? - Should rendering hints include actual alternate display text (for example, no VCS status text for tabs but provide it for explorer nodes) - Note that for Nodes & Properties, this is easily implementable using, e.g., RenderingHints rh = (RenderingHints) someNode.getValue ("hints.tab");
Things a rendering hints interface should support: - Font weight - Font style - Background color - Foreground color
Tim Boudreau wrote:> In the thread "text properties of treetable cells",> we've been discussing use cases for a limited> rendering hints API. Here are the use cases I> know of so far:>
General use cases:> - Nodes in explorer views> - Properties in the property sheet> - Tabs in tabbed windows in the IDE
I forgot one use case, coming from the earlier discussion: - Menu presenters for actions (e.g. make the default action appear in boldface)
do we need a hinting API to cover mentioned use cases? We could use some attributes of object being rendered and let view implementation choose best visualization:
- Node has isPreferred(), isExpert() attributes - the same applies to described property - Mode tab is tricky but it could try TopComponent.getActivatedNodes() - menu presenter could take selected nodes and invoke Node.getPreferredAction()
Cc.
PS: I have not followed the thread "text properties of treetable cells" so I may miss some other reasons.
Tim Boudreau wrote:>> In the thread "text properties of treetable cells",>> we've been discussing use cases for a limited>> rendering hints API. Here are the use cases I>> know of so far:>>
General use cases:>> - Nodes in explorer views>> - Properties in the property sheet>> - Tabs in tabbed windows in the IDE>
I forgot one use case, coming from the earlier> discussion:> - Menu presenters for actions (e.g. make the> default action appear in boldface)
do we need a hinting API to cover mentioned use cases?> We could use some attributes of object being rendered> and let view implementation choose best visualization:>
- Node has isPreferred(), isExpert() attributes> - the same applies to described property> - Mode tab is tricky but it could try> TopComponent.getActivatedNodes()> - menu presenter could take selected nodes and> invoke Node.getPreferredAction()
This is really about specific properties/nodes that want to provide some extra clues to a view about how to render them (for example, a default action should be bold, an editor tab might show a different color text to indicate a file is modified, one of Tor's task nodes may want to indicate some specific status info, etc).
The thing being, we have generic objects (Nodes, Properties), and generic views (Explorer, Property sheet, tabbed pane, menu) - yet often the usability of these views could be enhanced if the object being rendered could contribute some information about the optimal way to render itself. And it simplifies things for a module developer, who might otherwise have to write a view subclass to do something as simple as show one node name in bold text.
-Tim
Cc.>
PS: I have not followed the thread "text properties of> treetable cells" so I may miss some other reasons.>
Tim Boudreau wrote:>>
In the thread "text properties of treetable cells",>>>we've been discussing use cases for a limited>>>rendering hints API. Here are the use cases I>>>know of so far:>>>
General use cases:>>> - Nodes in explorer views>>> - Properties in the property sheet>>> - Tabs in tabbed windows in the IDE>>
I forgot one use case, coming from the earlier>>discussion:>> - Menu presenters for actions (e.g. make the>> default action appear in boldface)>
Petr Kuzel wrote:>> - menu presenter could take selected nodes and>> invoke Node.getPreferredAction()
Tim Boudreau wrote:> This is really about specific properties/nodes that> want to provide some extra clues to a view about how> to render them (for example, a default action should> be bold, [snip]
For the case of the default action, Petr is right I think - the menu item does *not* know whether it is the default action or not. Only the view does (because it has access to the entire menu and the node it refers to). Cf. my post in "Usability issues vs. NB architecture": our decision to have a Presenter.Popup actually prevents the view from reliably boldfacing the default action, because the view does not control the creation of the menu item. (*) For menu items, there is no need for rendering hints because the presenter can already display whatever it feels like. In contrast, for node display names, the view is responsible for the display, with the node supplying only a display name string, so some additional hints can be useful.
-Jesse
(*) We could introduce a Presenter.PopupMenuWhichUnderstandDefault or whatever:
public interface WhateverItIsCalled { JMenuItem getPopupPresenter(boolean defaultAction); }
Tim Boudreau wrote:> This is really about specific properties/nodes that> want to provide some extra clues to a view about how> to render them (for example, a default action should
Would not be then a right solution to give possibility to provide a renderer? Renderers could be located using the classification framework. It's more powerfull and does not clutter model layer with rendering hints.
This is really about specific properties/nodes that>>want to provide some extra clues to a view about how>>to render them (for example, a default action should>
Would not be then a right solution to give possibility> to provide a renderer? Renderers could be located using> the classification framework. It's more powerfull and> does not clutter model layer with rendering hints.
In the sense of separating model from view, I suppose it makes a kind of sense, BUT: Trees, tables, etc. are (or at least can be) highly optimized by, for instance, using a single component to render many items. Providing a renderer means that, at best, something will instantiate an additional component to do the rendering, and at worst (with a naive implementation), it will instantiate a renderer for every paint call.
In short, "more powerful" is exactly what we *don't* want here.
This is really about specific properties/nodes that>>> want to provide some extra clues to a view about how>>> to render them (for example, a default action should>>
Would not be then a right solution to give possibility>> to provide a renderer? Renderers could be located using>> the classification framework. It's more powerfull and>> does not clutter model layer with rendering hints.
What an interesting idea!
In the sense of separating model from view, I suppose it> makes a kind of sense, BUT: Trees, tables, etc. are> (or at least can be) highly optimized by, for instance,> using a single component to render many items.
This need not be problem as there can be one instance of renderer shared among all objects of the same type.
Providing> a renderer means that, at best, something will instantiate> an additional component to do the rendering, and at worst> (with a naive implementation), it will instantiate a> renderer for every paint call.
The NodeRenderer might be modified to find the right renderer inside of the Node.getLookup (). This would return the shared instance that would render any additional attributes.
If not slow (and I do not think it is as slow), this could be an excelent enhancement as it creates a pluggable architecture for rendering extensions. From the Explorer View UI, it just uses provided renderer, from the Node point of view, it just needs to provided it. And there can be many additional libraries offering factory methods based on simplified html, Tim's rendering interface, etc.
This is really about specific properties/nodes that>>>want to provide some extra clues to a view about how>>>to render them (for example, a default action should>>
Would not be then a right solution to give possibility>> to provide a renderer? Renderers could be located using>> the classification framework. It's more powerfull and>> does not clutter model layer with rendering hints.>
In the sense of separating model from view, I suppose it> makes a kind of sense, BUT: Trees, tables, etc. are> (or at least can be) highly optimized by, for instance,> using a single component to render many items. Providing> a renderer means that, at best, something will instantiate> an additional component to do the rendering, and at worst> (with a naive implementation), it will instantiate a> renderer for every paint call.
Well, you can provide precooked renderer that takes the rendering hints...
This is really about specific properties/nodes that>>>> want to provide some extra clues to a view about how>>>> to render them (for example, a default action should>>>
Would not be then a right solution to give possibility>>> to provide a renderer? Renderers could be located using>>> the classification framework. It's more powerfull and>>> does not clutter model layer with rendering hints.>>
What an interesting idea!>>
In the sense of separating model from view, I suppose it>> makes a kind of sense, BUT: Trees, tables, etc. are>> (or at least can be) highly optimized by, for instance,>> using a single component to render many items.>
This need not be problem as there can be one instance of renderer shared > among all objects of the same type.
Which will be written by whom? I think it's much more likely that someone will not trust in this, and go out and instantiate their own renderer whether they need to or not.
Providing>> a renderer means that, at best, something will instantiate>> an additional component to do the rendering, and at worst>> (with a naive implementation), it will instantiate a>> renderer for every paint call.>
The NodeRenderer might be modified to find the right renderer inside of > the Node.getLookup (). This would return the shared instance that would > render any additional attributes.
NONONONONONONONONONONONONONO....
No matter how fast it may, might, could, should be, the last thing on earth I want to be doing is fishing around in maps, hashtables or anything else in the middle of a paint loop.
And the fact is, not everybody is comfortable with writing painting code. My goal is to make the common case easy, without requiring anyone to play with java.awt.Graphics.
If not slow (and I do not think it is as slow), this could be an > excelent enhancement as it creates a pluggable architecture for > rendering extensions. From the Explorer View UI, it just uses provided
The whole point here is that if someone wants to do something so exotic that it needs its own renderer, then probably they need to be writing their own view. How many *useful* things could you do with your own renderer beyond text color/style, etc.
renderer, from the Node point of view, it just needs to provided it. And > there can be many additional libraries offering factory methods based on > simplified html, Tim's rendering interface, etc.>
On Mon, 2003-05-19 at 07:17, Tim Boudreau wrote:> > This need not be problem as there can be one instance of renderer shared > > among all objects of the same type.>
Which will be written by whom? I think it's much more likely> that someone will not trust in this, and go out and instantiate> their own renderer whether they need to or not.
I hope this will not be the extent of the rendering hints API; as a potential client of it, I just want to say "make this string bold", "make that string red", or "add a strikethrough style on that string".
I'd prefer not to have to write a bunch of Java2D code to get the alignment just right, etc.
Tim, it is hard to reply with open mind, when receiving mail like this.
Tim Boudreau wrote:> Jaroslav Tulach wrote:>
Tim Boudreau wrote:>>
Petr Kuzel wrote:>>>
Tim Boudreau wrote:>>>>
This is really about specific properties/nodes that>>>>> want to provide some extra clues to a view about how>>>>> to render them (for example, a default action should>>>>
Would not be then a right solution to give possibility>>>> to provide a renderer? Renderers could be located using>>>> the classification framework. It's more powerfull and>>>> does not clutter model layer with rendering hints.>>>
What an interesting idea!>>
In the sense of separating model from view, I suppose it>>> makes a kind of sense, BUT: Trees, tables, etc. are>>> (or at least can be) highly optimized by, for instance,>>> using a single component to render many items.>>
This need not be problem as there can be one instance of renderer >> shared among all objects of the same type.>
Which will be written by whom? I think it's much more likely> that someone will not trust in this, and go out and instantiate> their own renderer whether they need to or not.
Looks you do not trust anybody. I think that sometimes you have to.
Providing>>> a renderer means that, at best, something will instantiate>>> an additional component to do the rendering, and at worst>>> (with a naive implementation), it will instantiate a>>> renderer for every paint call.>>
The NodeRenderer might be modified to find the right renderer inside >> of the Node.getLookup (). This would return the shared instance that >> would render any additional attributes.>
NONONONONONONONONONONONONONO....>
No matter how fast it may, might, could, should be, the last> thing on earth I want to be doing is fishing around in maps,> hashtables or anything else in the middle of a paint loop.
As far as I remember you are fishing in node.getValue == fishing in maps.
And the fact is, not everybody is comfortable with writing> painting code. My goal is to make the common case easy, without> requiring anyone to play with java.awt.Graphics.
Read the rest of my suggestion, please.
If not slow (and I do not think it is as slow), this could be an >> excelent enhancement as it creates a pluggable architecture for >> rendering extensions. From the Explorer View UI, it just uses provided >
The whole point here is that if someone wants to do something so> exotic that it needs its own renderer, then probably they need to> be writing their own view. How many *useful* things could you do> with your own renderer beyond text color/style, etc.
If somebody is writing own view, it does not need to pay attention to this discussion at all. I thought that this is about providing a rendering hints to the default views.
renderer, from the Node point of view, it just needs to provided it. >> And there can be many additional libraries offering factory methods >> based on simplified html, Tim's rendering interface, etc.>>
I like this separation.>
I sincerely hope you're kidding.
Alas, I am not. What is wrong on writing my Node like this:
class MyNode extends AbstractNode implements org.nb.api.tim.RenderingHints { public Font getFont () { ... } public Color getBackground () { ... } public Color getForeground () { ... }
public MyNode () { super (Children.LEAF, Lookups.singleton (new Object[] { org.nb.api.tim.RenderingHints.RENDERER, /* this is the instance of the rendered that renders this node, please not that there is just one instance */ this /* adds org.nb.api.tim.RenderingHints interface into the Lookup, so the render can use it */ })); } }
this is neither slow or allocates too many objects. So why you think I am kidding?
Tim Boudreau wrote:> No matter how fast it may, might, could, should be, the last> thing on earth I want to be doing is fishing around in maps,> hashtables or anything else in the middle of a paint loop.
A simple hashtable lookup is so fast as to be negligible if you're only doing a few of them. Paint loops already normally do lots of them. How do you think UI defaults etc. work?
Calling into Lookup, on the other hand, I have no idea. Might be slow at the moment. Lookup is currently oversynchronized and heavyweight IMHO.
In order to explore all the possibilities, today I wrote a lightweight HTML renderer that renders basically the same subset of HTML that rendering hints would cover.
Timing it in comparison with Swing's HTML rendering is a bit difficult - in a JLabel, a bunch of HTML rendering data is actually computed when you call setText().
Anyway, for the first render, my rendering code is about twice as fast (not including the additional time Swing rendering spends in setText() - it's a very deep call stack). If I felt really ambitious, I could probably also cache some rendering data...
For subsequent renders, Swing's HTML support is faster, since the data is already cached - but in the case of tree and table elements, where a renderer gets setText() called on it once for each cell, probably my rendering code would be quicker.
At the same time, a simple rendering hints object would be faster than either. Whaddayathink?
In order to explore all the possibilities, today I wrote a> lightweight HTML renderer that renders basically the same> subset of HTML that rendering hints would cover.>
Timing it in comparison with Swing's HTML rendering is a> bit difficult - in a JLabel, a bunch of HTML rendering> data is actually computed when you call setText().>
Anyway, for the first render, my rendering code is about> twice as fast
Good. How many times it is slower than plain drawText? In case the string contains html and in case it does not?
(not including the additional time Swing rendering> spends in setText() - it's a very deep call stack). If> I felt really ambitious, I could probably also cache> some rendering data...
That would speed up the subsequent renders, I guess. I do not know if that is necessary. When you scroll a tree, does it move the buffer or draws it again completely? If the later, then some kind of cache would be useful, otherwise I do not see use for it.
In order to explore all the possibilities, today I wrote a>> lightweight HTML renderer that renders basically the same>> subset of HTML that rendering hints would cover.>>
Timing it in comparison with Swing's HTML rendering is a>> bit difficult - in a JLabel, a bunch of HTML rendering>> data is actually computed when you call setText().>>
Anyway, for the first render, my rendering code is about>> twice as fast>
Good. How many times it is slower than plain drawText? In case the > string contains html and in case it does not?
I'll check this - I need to change my benchmarking to compare a JLabel and a JComponent w/ rendering code, and include the setText() call to both in the benchmark to get a true picture of the overhead.
I'll try that today. One problem is that both rendering methods are so fast that it's hard to get meaningful data from something like OptimizeIt - there are too many other things in the JVM that are slower that crowd it out.
(not including the additional time Swing rendering>> spends in setText() - it's a very deep call stack). If>> I felt really ambitious, I could probably also cache>> some rendering data...>
That would speed up the subsequent renders, I guess. I do not know if > that is necessary. When you scroll a tree, does it move the buffer or > draws it again completely?
Probably depends on double buffering. The painting logic for a tree or a table takes a single component and repeatedly calls setText() and then paint() for each element. So the overhead in setText() on a JLabel is relevant.
It could save one iteration of the string and a few char comparisons to cache the locations and attributes of strings that will actually be rendered.
There are two ways to implement such an optimization - 1. The render method keeps the data in a WeakSet, or such and simply reuses it when it gets a string with a matching hashcode.
2. The render method returns the data and will accept it as an argument - slightly more efficient, but more work for a client that wants to reuse it.
I completely agree with Petr. We need a renderer-based framework. It will be much more powerful and faster too. We could also provide a simple renderer implementation for color/font changing.
Tim
Petr Kuzel wrote:
Tim Boudreau wrote:>
This is really about specific properties/nodes that>>want to provide some extra clues to a view about how>>to render them (for example, a default action should>>
Would not be then a right solution to give possibility>to provide a renderer? Renderers could be located using>the classification framework. It's more powerfull and>does not clutter model layer with rendering hints.>
Tim Lebedkov wrote:> I completely agree with Petr.> We need a renderer-based framework.
Why? The only thing I've heard so far is that it's "more powerful" - but nobody has offered a use case where they would need to do something that couldn't be done with colors and font styles.
Do you have such a use case?
It will be much more powerful and faster too.
Adding code to fetch a unique renderer for some elements in a tree, table or tabbed pane, possibly instantiating the renderer for the first time, possibly loading classes to do it, and then configuring it and painting...this process can be many things, but faster is not one of them.
We could also provide a simple renderer implementation for> color/font changing.
Sure, if we choose to go that way.
Note that, as I mentioned before, creating a renderer infrastructure is in no way a blocker for going ahead with either lightweight HTML rendering or rendering hints right now.
Tim Lebedkov wrote:> One more requirement for the rendering hints is> drawing an icon (and I will need different icons> for different property values).>
How this could be achived using HTML?
The renderer used by the tree/table will handle that in its paint method, along with calling html rendering.
If you would like to report an abuse of our service, such as a spam message, please . Если Вы хотите пожаловаться на содержимое этой страницы, пожалуйста .