Trace:
Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
jvx:reference [2020/06/24 14:14] cduncan [Wrapping Custom Components With UICustomComponent] |
jvx:reference [2020/06/24 15:47] cduncan [Fire away!] |
||
---|---|---|---|
Line 1061: | Line 1061: | ||
} | } | ||
</code> | </code> | ||
- | With this little example, we have a completely working [[https://sourceforge.net/projects/jvx/|JVx]] application. We provide ways to create most of this out of the box and read most of it from configuration files, so there really is little code to be written. See [[https://sourceforge.net/projects/jvxfirstapp/|the JVx FirstApp]] as a perfect example for that.As you can see, there is rarely any need to write code like this, all you have to do is create a new application and start it. | + | With this little example, we have a wholly working [[https://sourceforge.net/projects/jvx/|JVx]] application. We provide ways to create most of this out of the box and read most of it from configuration files, so there really is little code to be written. See [[https://sourceforge.net/projects/jvxfirstapp/|the JVx FirstApp]] as a perfect example of this.As you can see, there is rarely any need to write such code; all you have to do is create a new application and start it. |
Additionally, we could combine this long example with the simple one from before to initialize and create a GUI that could use our ''%%RemoteDataBook%%'', like this: | Additionally, we could combine this long example with the simple one from before to initialize and create a GUI that could use our ''%%RemoteDataBook%%'', like this: | ||
Line 1081: | Line 1081: | ||
frame.eventWindowClosed().addListener(() -> System.exit(0)); | frame.eventWindowClosed().addListener(() -> System.exit(0)); | ||
</code> | </code> | ||
- | ===== Abstractions on Every Step ===== | + | ===== Abstractions at Every Step ===== |
- | As you can see, you always have full control over the framework and can always tailor it to your needs. There is always the possibility to provide a custom implementation to fulfill your needs: | + | As you can see, you always have full control over the framework and can always tailor it to your needs. There is always the possibility to provide a custom implementation: |
* Accessing an unsupported database can be achieved by extending ''%%DBAccess%%''. | * Accessing an unsupported database can be achieved by extending ''%%DBAccess%%''. | ||
Line 1178: | Line 1178: | ||
* The editor gets the CellEditor from the model and adds it to itself. | * The editor gets the CellEditor from the model and adds it to itself. | ||
- | ===== One Moment Instance Sharing? ===== | + | ===== Instance Sharing ===== |
If we revisit the example code from above, we will notice that the CellEditor instance is set on the model and must then be used by the editor. That means that a single CellEditor instance is used for all bound editors. We all know that sharing instances in such a way can be fun, but, in this case, it is not a problem because CellEditors are only “factories” for the actual editing components. | If we revisit the example code from above, we will notice that the CellEditor instance is set on the model and must then be used by the editor. That means that a single CellEditor instance is used for all bound editors. We all know that sharing instances in such a way can be fun, but, in this case, it is not a problem because CellEditors are only “factories” for the actual editing components. | ||
Line 1525: | Line 1525: | ||
====== FormLayout ====== | ====== FormLayout ====== | ||
- | Let’s talk about the [[http://forum.sibvisions.com/viewtopic.php?f=11&t=167&p=219|FormLayout]] and why the anchor system makes it much more flexible than just a simple grid. | + | Let’s talk about the [[http://forum.sibvisions.com/viewtopic.php?f=11&t=167&p=219|FormLayout]] and why the anchor system makes it much more flexible than a simple grid. |
===== Basics ===== | ===== Basics ===== | ||
Line 1537: | Line 1537: | ||
* FormLayout | * FormLayout | ||
- | From these five, the first four are easily explained. Only the FormLayout needs some more information because it might not be as easy to grasp off the bat as the others. | + | Of these five, the first four are easily explained. Only the FormLayout needs some more information because it might not be as easy to grasp off the bat as the others. |
The FormLayout uses a dependent anchor system. An anchor in this context is a position inside the layout that is calculated from parent anchors and either the size of the component or a fixed value. So we can say there are two different types of anchors inside the FormLayout that we are concerned about: | The FormLayout uses a dependent anchor system. An anchor in this context is a position inside the layout that is calculated from parent anchors and either the size of the component or a fixed value. So we can say there are two different types of anchors inside the FormLayout that we are concerned about: | ||
- | * AutoSize-anchors, its position is calculated from the component assigned to it. | + | * Autosize anchors, its position is calculated from the component assigned to it. |
- | * Fixed-anchors, its position is fixed. | + | * Fixed anchors, its position is fixed. |
- | Additionally, there are three special cases of fixed-anchors: | + | Additionally, there are three special cases of fixed anchors: |
- | * Border-anchors, which surround the FormLayout at its border. | + | * Border anchors, which surround the FormLayout at its border. |
- | * Margin-anchors, which are inset from the border by the defined value. | + | * Margin anchors, which are inset from the border by the defined value. |
- | * Gap-anchors, which are added to create a gap between components. | + | * Gap anchors, which are added to create a gap between components. |
When it comes to calculating the position of an anchor, the position of the parent anchor is determined, and then the value of the current anchor is added (which is either the size of a component or a fixed value). Simplified and in pseudo-code it can expressed like this: | When it comes to calculating the position of an anchor, the position of the parent anchor is determined, and then the value of the current anchor is added (which is either the size of a component or a fixed value). Simplified and in pseudo-code it can expressed like this: | ||
Line 1583: | Line 1583: | ||
{{:jvx:reference:formlayout-1.png?nolink|FormLayout with one added component.}} | {{:jvx:reference:formlayout-1.png?nolink|FormLayout with one added component.}} | ||
- | With the coordinates of ''%%0,0%%'', no new anchors are created, but, instead, the component is attached to the top and left margin anchor. Two new autosize-anchors (horizontally and vertically) are created and attached to the component. | + | With the coordinates of ''%%0,0%%'', no new anchors are created. Instead, the component is attached to the top and left margin anchor. Two new autosize anchors (horizontal and vertical) are created and attached to the component. |
- | If we now add a second component in the same row: | + | We now add a second component in the same row: |
<code java> | <code java> | ||
Line 1593: | Line 1593: | ||
{{:jvx:reference:formlayout-2.png?nolink|FormLayout with two added components.}} | {{:jvx:reference:formlayout-2.png?nolink|FormLayout with two added components.}} | ||
- | Because we are still on row ''%%0%%'', the component is attached to the top margin anchor and the previous autosize-anchor for this row. Then, a new gap-anchor will be created, which is attached to the trailing autosize-anchor of the previous component. | + | Because we are still on row ''%%0%%'', the component is attached to the top margin anchor and the previous autosize anchor for this row. Then, a new gap anchor will be created, which is attached to the trailing autosize anchor of the previous component. |
We can, of course, also add items to the right and bottom: | We can, of course, also add items to the right and bottom: | ||
Line 1604: | Line 1604: | ||
{{:jvx:reference:formlayout-3.png?nolink|FormLayout with three added components, one in the bottom right corner.}} | {{:jvx:reference:formlayout-3.png?nolink|FormLayout with three added components, one in the bottom right corner.}} | ||
- | What happens is the same as when adding a component at the coordinates ''%%0,0%%'', except that the reference is the lower right corner. The component is attached to the bottom and right margin anchors with trialing autosize-anchors. | + | What happens is the same as when adding a component at the coordinates ''%%0,0%%'', except that the reference is the lower right corner. The component is attached to the bottom and right margin anchors with trialing autosize anchors. |
- | Last but not least, we can add components which span between anchors: | + | Last but not least, we can add components that span anchors: |
<code java> | <code java> | ||
Line 1616: | Line 1616: | ||
{{:jvx:reference:formlayout-4.png?nolink|FormLayout with four added components, one stretched.}} | {{:jvx:reference:formlayout-4.png?nolink|FormLayout with four added components, one stretched.}} | ||
- | Again, the same logic applies as previously, with the notable exception that new gap-anchors are created for all four sides. That includes variants which span over anchors: | + | Again, the same logic as previously applies, with the notable exception that new gap anchors are created for all four sides. This includes variants that span anchors: |
<code java> | <code java> | ||
Line 1625: | Line 1625: | ||
{{:jvx:reference:formlayout-5.png?nolink|FormLayout with three added components, one of them spans multiple anchors.}} | {{:jvx:reference:formlayout-5.png?nolink|FormLayout with three added components, one of them spans multiple anchors.}} | ||
- | The component is horizontally attached to the left margin-anchor and additionally to the autosize-anchor of the second column. The autosize- and gap-anchor of the first column are not ignored, they are not relevant to this case. | + | The component is horizontally attached to the left margin anchor and additionally to the autosize anchor of the second column. The autosize- and gap anchors of the first column are not ignored, but they are not relevant to this case. |
- | At this point it is important to note that spanning and stretched components are disregarded for the preferred size calculation of the layout. So, whenever you span or stretch a component, it is not taken into account when the preferred size of the layout is calculated, which can lead to unexpected results. | + | At this point it is important to note that spanning and stretched components are disregarded for the preferred size calculation of the layout. Therefore, whenever you span or stretch a component, it is not taken into account when the preferred size of the layout is calculated, which can lead to unexpected results. |
===== Interactive Demo ===== | ===== Interactive Demo ===== | ||
- | Sometimes, however, it might not be obvious what anchors are created and how they are used. For this, we have created a simple interactive demonstration application that allows you to inspect the created anchors of a layout, the [[https://github.com/sibvisions/jvx.formlayout-visualization|JVx FormLayout Visualization]]. | + | Sometimes, however, it might not be obvious what anchors are created and how they are used. For this, we have created a simple interactive demonstration application that allows you to inspect the created anchors of a layout: the [[https://github.com/sibvisions/jvx.formlayout-visualization|JVx FormLayout Visualization]]. |
{{:jvx:reference:formlayout-visualization.png?nolink|FormLayout Visualization Demo}} | {{:jvx:reference:formlayout-visualization.png?nolink|FormLayout Visualization Demo}} | ||
- | On the left is the possibility to show and hide anchors together with the information about the currently highlighted anchor. On the right is an Lua scripting area which allows you to quickly and easily rebuild and test layouts. It utilizes the [[https://blog.sibvisions.com/2017/09/25/jvx-lua-proof-of-concept/|JVx-Lua bridge from a previous blog post]] and so any changes to the code are directly applied. | + | On the left is the possibility to show and hide anchors together with the information about the currently highlighted anchor. On the right is an Lua scripting area, which allows you to quickly and easily rebuild and test layouts. It utilizes the [[https://blog.sibvisions.com/2017/09/25/jvx-lua-proof-of-concept/|JVx-Lua bridge from a previous blog post]] and so any changes to the code are directly applied. |
- | ===== The most simple usage: Flow-like ===== | + | ===== The Simplest Usage: Flow-Like ===== |
- | Enough of the internals, let’s talk use-cases. The most simple use-case for the FormLayout can be a container which flows its contents in a line until a certain number of items is reach, at which it breaks into a new line. | + | Enough of the internals, let’s talk use-cases. The most simple use-case for the FormLayout can be a container which flows its contents in a line until a certain number of items is reach, at which point it breaks into a new line. |
{{:jvx:reference:formlayout-flow.png?nolink|FormLayout with a flow layout}} | {{:jvx:reference:formlayout-flow.png?nolink|FormLayout with a flow layout}} | ||
Line 1671: | Line 1671: | ||
panel:add(stub()); | panel:add(stub()); | ||
</code> | </code> | ||
- | ===== The obvious usage: Grid-like ===== | + | ===== The Most Obvious Usage: Grid-Like ===== |
- | The FormLayout can also be used to align components in a grid, and actually layout them in a grid-like fashion. | + | The FormLayout can also be used to align components in a grid and actually layout them in a grid-like fashion. |
{{:jvx:reference:formlayout-grid.png?nolink|FormLayout with a grid layout}} | {{:jvx:reference:formlayout-grid.png?nolink|FormLayout with a grid layout}} | ||
- | With the main difference being that the columns and rows are sized according to the components in it and not given a fixed slice of the width of the panel. | + | The main difference is that columns and rows are sized according to the components and not given a fixed-width portion of the panel. |
==== Java ==== | ==== Java ==== | ||
Line 1707: | Line 1707: | ||
panel:add(stub(), layout:getConstraints(-1, 2, -1, -1)); | panel:add(stub(), layout:getConstraints(-1, 2, -1, -1)); | ||
</code> | </code> | ||
- | ===== The advanced usage: Anchor Configuration ===== | + | ===== The More Advanced Usage: Anchor Configuration ===== |
- | Additionally, the FormLayout offers the possibility to manually set the anchor positions, for example when it is necessary to give the first elements a certain size. Together with the ability to span components, this allows to create complex and rich layouts. | + | Additionally, the FormLayout offers the possibility to manually set the anchor position (e.g., when it is necessary to give the first elements a certain size). Together with the ability to span components, this allows us to create complex and rich layouts. |
{{:jvx:reference:formlayout-anchorconfiguration.png?nolink|FormLayout with a set anchor configuration}} | {{:jvx:reference:formlayout-anchorconfiguration.png?nolink|FormLayout with a set anchor configuration}} | ||
Line 1749: | Line 1749: | ||
===== Conclusion ===== | ===== Conclusion ===== | ||
- | The [[https://sourceforge.net/projects/jvx/|JVx]] FormLayout allows to quickly and easily create complex, good looking and working layouts which are still flexible enough for the cases when a component is swapped, removed or added. It can be used in many different circumstances and is still easy enough to use to make sure that even beginners are able to create a basic layout within seconds. | + | The [[https://sourceforge.net/projects/jvx/|JVx]] FormLayout allows us to quickly and easily create complex, good looking, and functioning layouts that are still flexible enough for the cases when a component is swapped, removed, or added. It can be used in many different circumstances and is still easy enough to use to make sure that even beginners are able to create a basic layout within seconds. |
====== Events ====== | ====== Events ====== | ||
Line 1755: | Line 1755: | ||
Let’s talk about events and event handling in [[https://sourceforge.net/projects/jvx/|JVx]]. | Let’s talk about events and event handling in [[https://sourceforge.net/projects/jvx/|JVx]]. | ||
- | ===== What are events… ===== | + | ===== What Are Events… ===== |
- | Events are an [[https://en.wikipedia.org/wiki/Event-driven_programming|important mechanism no matter to what programming language or framework you turn to]]. It allows us to react on certain actions and “defer” actions until something triggered them. Such triggers can be anything, like a certain condition is hit in another thread, the user clicked a button or another action has finally finished. Long story short, you get notified that something happened, and that you can now do something. | + | Events are an [[https://en.wikipedia.org/wiki/Event-driven_programming|important mechanism no matter to what programming language or framework you turn to]]. They allow us to react on certain actions and “defer” actions until something triggers them. Such triggers can be anything: a certain condition is hit in another thread, the user clicked a button, or another action has finally finished. Long story short, you are notified that something happened and you can now do something further. |
- | ===== …and why do I need to handle them? ===== | + | ===== …And Why Do I Need to Handle Them? ===== |
- | Well, you can’t skip events, they are a cornerstone of [[https://sourceforge.net/projects/jvx/|JVx]]. Theoretically, you could use [[https://sourceforge.net/projects/jvx/|JVx]] without using any of its events, but you would not only miss out on a lot of functionality but also be unable to do anything useful. But don’t worry, understanding the event system is easy, using it even easier. | + | Well, you can’t skip events, they are a cornerstone of [[https://sourceforge.net/projects/jvx/|JVx]]. Theoretically, you could use [[https://sourceforge.net/projects/jvx/|JVx]] without any of its events, but you would not only miss out on a lot of functionality, but also be unable to do anything useful. But don’t worry, understanding the event system is easy and using it even easier. |
===== Terminology ===== | ===== Terminology ===== | ||
- | For [[https://sourceforge.net/projects/jvx/|JVx]] the following terminology applies: An event is a property of an object, you can register listeners on that event which will get invoked if the event is dispatched (fired). Every event consists of the ''%%EventHandler%%'' which allows to register, remove and manage the listeners and also dispatches the events, meaning invoking the listeners and notifying them that the event occurred. There is no single underlying listener interface. | + | For [[https://sourceforge.net/projects/jvx/|JVx]] the following terminology applies: an event is a property of an object. You can register listeners on that event that will get invoked if the event is dispatched (fired). Every event consists of the ''%%EventHandler%%'', which allows ypi to register, remove, and manage the listeners and also dispatches the events, meaning it invokes the listeners and notifies them that the event occurred. There is no single underlying listener interface. |
- | Within the [[https://sourceforge.net/projects/jvx/|JVx]] framework, every event-property of an object does start with the prefix “event” to make it easily searchable and identifiable. But enough dry talk, let’s get started. | + | Within the [[https://sourceforge.net/projects/jvx/|JVx]] framework, every event property of an object starts with the prefix “event” to make it easily searchable and identifiable. But enough dry talk, let’s get started. |
- | ===== Attaching listeners ===== | + | ===== Attaching Listeners ===== |
We will now look at all the ways on how to attach a listener to an event. | We will now look at all the ways on how to attach a listener to an event. | ||
Line 1775: | Line 1775: | ||
==== Class ==== | ==== Class ==== | ||
- | The easiest way to get notified of events is to attach a class (which is implementing the listener interface) to an event as listener, like this: | + | The easiest way to get notified of events is to attach a class (that is implementing the listener interface) to an event as listener, like this: |
<code java> | <code java> | ||
Line 1800: | Line 1800: | ||
} | } | ||
</code> | </code> | ||
- | ==== Inlined class ==== | + | ==== Inlined Class ==== |
- | Of course we can inline this listener class: | + | Of course, we can inline this listener class: |
<code java> | <code java> | ||
Line 1825: | Line 1825: | ||
} | } | ||
</code> | </code> | ||
- | ==== JVx style ==== | + | ==== JVx Style ==== |
- | So far, so normal. But in [[https://sourceforge.net/projects/jvx/|JVx]] we have support to attach listeners based on reflection, like this: | + | So far, so good. However, in [[https://sourceforge.net/projects/jvx/|JVx]] we have support to attach listeners based on reflection, like this: |
<code java> | <code java> | ||
Line 1849: | Line 1849: | ||
} | } | ||
</code> | </code> | ||
- | What is happening here is that, internally, a listener is created which references the given object and the named method. This allows to easily add and remove listeners from events and keeping the classes clean by allowing to have all related event listeners in one place and without additional class definitions. | + | What is happening here is that, internally, a listener is created that references the given object and the named method. This allows us to easily add and remove listeners from events and keeps the classes clean by allowing us to have all related event listeners in one place without additional class definitions. |
==== Lambdas ==== | ==== Lambdas ==== | ||
- | Yet there is more, we can of course attach [[https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html|lambdas]] to the events as listeners, too: | + | Yet there is more. We can, of course, attach [[https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html|lambdas]] to the events as listeners too: |
<code java> | <code java> | ||
Line 1870: | Line 1870: | ||
} | } | ||
</code> | </code> | ||
- | ==== Method references ==== | + | ==== Method References ==== |
- | And last but not least, thanks to the new capabilities of Java 1.8, we can also use [[https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html|method references]]: | + | Lastly, thanks to the new capabilities of Java 1.8, we can also use [[https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html|method references]]: |
<code java> | <code java> | ||
Line 1894: | Line 1894: | ||
} | } | ||
</code> | </code> | ||
- | ===== Parameters or no parameters? To throw or not to throw? ===== | + | ===== Parameters or No Parameters? To Throw or Not to Throw? ===== |
- | By default we actually support two different classes of listeners, the specified event/listener interface itself, and ''%%javax.rad.util.IRunnable%%''. Which means that you can also attach methods which do not have any parameters, like this: | + | By default we actually support two different classes of listeners, the specified event/listener interface itself and ''%%javax.rad.util.IRunnable%%''. This means you can also attach methods that do not have any parameters, like this: |
<code java> | <code java> | ||
Line 1924: | Line 1924: | ||
} | } | ||
</code> | </code> | ||
- | Additionally, all listeners and ''%%IRunnable%%'' itself do support to throw ''%%Throwable%%'', which is then handled inside the ''%%EventHandler%%''. So you are very flexible when it comes to what methods you can attach and use as listeners. | + | Additionally, all listeners and ''%%IRunnable%%'' itself support throwing ''%%Throwable%%'', which is then handled inside the ''%%EventHandler%%''. As you can see, you are very flexible when it comes to what methods you can attach and use as listeners. |
- | ===== Creating your own events ===== | + | ===== Creating Your Own Events ===== |
You can, of course, create your own ''%%EventHandler%%''s and listeners to create your own events. All you need are two classes, an extension of EventHandler and a listener interface. | You can, of course, create your own ''%%EventHandler%%''s and listeners to create your own events. All you need are two classes, an extension of EventHandler and a listener interface. | ||
Line 1954: | Line 1954: | ||
event.dispatchEvent("Adam"); | event.dispatchEvent("Adam"); | ||
</code> | </code> | ||
- | ===== More methods! ===== | + | ===== Additional Methods ===== |
- | You can also use an interface for listeners which has multiple methods, specifying in the constructor which method to invoke: | + | You can also use an interface for listeners that has multiple methods, specifying in the constructor which method to invoke: |
<code java> | <code java> | ||
Line 1974: | Line 1974: | ||
} | } | ||
</code> | </code> | ||
- | Now every time the event is dispatched, the ''%%somethingOtherHappened%%'' method will be invoked. Anyway, don’t use this. The upside of having a “simple” listener interface with just one method is that it allows to use lambdas with it. A listener interface with multiple methods won’t allow this. | + | Now every time the event is dispatched, the ''%%somethingOtherHappened%%'' method will be invoked. However, don’t use this. The upside of having a “simple” listener interface with just one method is that it allows us to use lambdas with it. A listener interface with multiple methods won’t allow this. |
In [[https://sourceforge.net/projects/jvx/|JVx]] [[http://blog.sibvisions.com/2015/01/28/jvx-and-java-8-events-and-lambdas/|we reduced our listener interfaces to just one method (in a backward compatible way)]] to make sure all events can be used with lambdas. | In [[https://sourceforge.net/projects/jvx/|JVx]] [[http://blog.sibvisions.com/2015/01/28/jvx-and-java-8-events-and-lambdas/|we reduced our listener interfaces to just one method (in a backward compatible way)]] to make sure all events can be used with lambdas. | ||
- | ===== Fire away! ===== | + | ===== Fire Away! ===== |
- | That’s it for this short reference sheet, that is how our event system can and should be used. Of course, there is much more to it under the hood, for example listeners being wrapped in proxy classes, reflection used for invoking methods and some more stuff. If you feel adventurous, be my guest and have a good look at the internals of ''%%EventHandler%%'', it is quite an interesting read. | + | That’s it for this short reference sheet. This is how our event system can and should be used. Of course, there is much more to it under the hood (for example, listeners being wrapped in proxy classes, reflection used for invoking methods, etc.). If you feel adventurous, be my guest and have a good look at the internals of ''%%EventHandler%%''. It is quite an interesting read! |