{"id":1882,"date":"2013-10-15T07:35:20","date_gmt":"2013-10-14T19:35:20","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=1882"},"modified":"2013-10-15T09:14:44","modified_gmt":"2013-10-14T21:14:44","slug":"not-your-grand-daddys-pascal-or-java","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/1882\/","title":{"rendered":"Not Your Grand-Daddy&#8217;s Pascal (or Java)"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">9<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p>I&#8217;ve mentioned some of the cool stuff in the Oxygene language in various posts and thought it would be a good idea to list them again, along with some others that I&#8217;ve not previously mentioned.<\/p>\n<p><!--more--><\/p>\n<h2>Oxygene Everywhere<\/h2>\n<p>First some of the core language features that are available on all supported platforms &#8211; Java, Cocoa and .NET<\/p>\n<ul>\n<li>Property Members<\/li>\n<li>Property Read Expressions<\/li>\n<li>Properties with Different Read\/Write Protections<\/li>\n<li>Sophisticated Class Member Scoping<\/li>\n<li>if-expressions<\/li>\n<li>Extended Constructor Calls (Create and Initialise)<\/li>\n<li>Case Statements with Strings<\/li>\n<li>In-line Variable Declarations<\/li>\n<li>Variable Type Inferencing<\/li>\n<li>Colon Operator<\/li>\n<\/ul>\n<h3>Property Members<\/h3>\n<p>If you have a simple property which directly exposes a member variable you do not need to formally declare the member variable and the accessor\/mutator properties, you can just declare the member variable as a property:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  Rectangle = class\r\n  public\r\n    property Width: Integer;\r\n    property Height: Integer;\r\n  end;\r\n<\/pre>\n<h3>Property Read Expressions<\/h3>\n<p>If you have a property whose value can be expressed using other members of the class you don&#8217;t need to wrap this up inside a formally declared accessor method, you can just write the expression directly in the property declaration:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  Rectangle = class\r\n    ..\r\n    property Area: Integer read Width * Height;\r\n  end;\r\n<\/pre>\n<p>Combining property members and read expressions allows us to write a simple rectangle class very cleanly, without any implementation code required at all:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  Rectangle = class\r\n  public\r\n    property Width: Integer;\r\n    property Height: Integer;\r\n    property Area: Integer read Width * Height;\r\n  end;\r\n<\/pre>\n<p>Which compares very favourably indeed with grand-daddy&#8217;s Pascal:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  TRectangle = class\r\n  private\r\n    fWidth: Integer;\r\n    fHeight: Integer;\r\n    function get_Area: Integer;\r\n  public\r\n    property Width: Integer read fWidth write fWidth;\r\n    property Height: Integer read fHeight write fHeight;\r\n    property Area: Integer read get_Area;\r\n  end;\r\n\r\n  \r\n  function TRectangle.get_Area: Integer;\r\n  begin\r\n    result := fWidth * fHeight;\r\n  end;\r\n<\/pre>\n<h3>Properties with Different Read\/Write Protections<\/h3>\n<p>Ever had a property which was read-only for public access but which you wanted to make writable for private or protected use ?  With Oxygene you can.  In this case however, you do need to declare the accessor\/mutator methods or fields.  The property has a default visibility &#8220;inherited&#8221; from the visibility specified applying to the declaration, but this can be &#8220;overridden&#8221; on the read\/write accessors.<\/p>\n<p>So to create a <strong>public read<\/strong>able property with <strong>protected write<\/strong> access:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  Rectangle = class\r\n  private\r\n    fWidth: Integer;\r\n    fHeight: Integer;\r\n  public\r\n    property Width: Integer read fWidth protected write fWidth;\r\n    property Height: Integer read fHeight protected write fHeight;\r\n    property Area: Integer read Width * Height;\r\n  end;\r\n<\/pre>\n<h3>Sophisticated Class Member Scoping<\/h3>\n<p>Oxygene has some very expressive capabilities in the area of member scoping.<\/p>\n<p>In addition to the usual <strong>private<\/strong>, <strong>protected<\/strong>, <strong>public<\/strong>, <strong>strict private<\/strong>, <strong>strict protected<\/strong> etc, Oxygene also allows <strong>assembly<\/strong> (corresponding to &#8220;package&#8221; in Java) and <strong>unit<\/strong> scoping.<\/p>\n<p>The possible combinations are too numerous to mention here so for a full breakdown I refer you to <a href=\"http:\/\/wiki.oxygenelanguage.com\/en\/Class_Member_Visibility_Levels\">this page of the Oxygene Language Wiki<\/a>.<\/p>\n<p>Suffice to say that the ability to directly express (and enforce) that a member be accessible to <em><strong>only<\/strong> those classes in a unit <strong>which are also<\/strong> sub-classes of the class<\/em> or, alternatively, <em>accessible to classes in a unit <strong>and<\/strong> to <strong>any<\/strong> sub-classes<\/em> (to name just two possibilites) is very useful.<\/p>\n<h3>if-expressions<\/h3>\n<p>Anywhere that an expression may be used, an <strong>if-expression<\/strong> can be employed as an inline expression selector so instead of:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  if useRed then\r\n    view.TextColor := Color.RED\r\n  else\r\n    view.TextColor := Color.WHITE;\r\n<\/pre>\n<p>We can write:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  view.TextColor := if useRed then Color.RED else Color.WHITE;\r\n<\/pre>\n<h3>Extended Constructor Calls<\/h3>\n<p>Very often in OO we write code that consists of creating some object then setting some properties on that object:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  myButton := new Button(self);\r\n  myButton.Caption := 'OK';\r\n  myButton.Width   := 100;\r\n  myButton.Height  := 25;\r\n<\/pre>\n<p>To simplify such cases in <strong>Oxygene<\/strong>, property assignments can be appended to the parameter list of any supported constructor.  The initial parameters will be used to identify and call the appropriate constructor before applying the additional assignment expressions:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  myButton := new Button(self, Caption := 'OK', \r\n                               Width   := 100,\r\n                               Height  := 25);\r\n<\/pre>\n<h3>Case Statements with Strings<\/h3>\n<p>Oxygene case statements have much broader application than in Delphi.  The most notable difference being that they support string selectors:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  case aIntent.Action of\r\n    'nz.co.deltics.SCREEN_ON' : ... ;\r\n    'nz.co.deltics.SCREEN_OFF' : ... ;\r\n  else\r\n    ...\r\n  end;\r\n<\/pre>\n<p>I seem to recall in an early version of Oxygene (what was then known as &#8220;Chrome&#8221;), the else clause of a case statement required a &#8216;begin&#8217;.  It was arguably more syntactically correct according to a strict application of core Pascal syntax, but it was a bit cumbersome and somewhere along the way this seems to have changed.  \ud83d\ude42<\/p>\n<h3>Inline Variable Declaration<\/h3>\n<p>Variables can be declared in the usual Pascal manner in <strong>Oxygene<\/strong>, within a <strong>var<\/strong> block preceding the begin statement of a method.  Or you can declare a variable in-line at first use.  In-line declarations have the scope of their containing statement block.<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  if bSomeCondition then\r\n  begin\r\n    var i: Integer;\r\n\r\n    ... do some work with an Integer, i\r\n  end\r\n  else\r\n  begin\r\n    var i: Intent;\r\n\r\n    ... do some work with an Intent, i\r\n  end;\r\n\r\n  if NOT assigned(i) then   \/\/ Compilation fails.  &quot;i&quot; does not exist\r\n    EXIT;\r\n<\/pre>\n<h3>Inline Variable Type Inference<\/h3>\n<p>Most often when declaring a variable inline, it will be immediately initialised.  In such cases Oxygene does not require that you declare the variable type.  It will infer the appropriate type from the assignment expression.  So the above in-line declaration example with some assumed initialisation, might look like this<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  if bSomeCondition then\r\n  begin\r\n    var i := 42;\r\n\r\n    ... do some work with an Integer, i\r\n  end\r\n  else\r\n  begin\r\n    var i := new Intent(Intent.ACTION_POWER_CONNECTED);\r\n\r\n    ... do some work with an Intent, i\r\n  end;\r\n<\/pre>\n<h3>Colon Operator<\/h3>\n<p>The colon operator is a variation on the dot operator.  Unlike the dot operator however, the colon operator offers some protection against potentially nil references.  This can make certain programming tasks far easier.<\/p>\n<p>Consider this hypothetical example of looking up some user object by name, obtaining the details object for that user and a company object within it and then extracting the name of that company, where there may not be any such user, the user may not have any details and the details if provided may not identify a particular company.<\/p>\n<p>In terms of runtime performance, the most efficient way to implement this would be:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  sCompanyName := '';\r\n\r\n  user := fUsers.getUserByName(aUserName);\r\n  if Assigned(user) then\r\n  begin\r\n    var details := user.Details;\r\n    if Assigned(details) then\r\n    begin\r\n      var company := details.Company;\r\n      if Assigned(company) then\r\n        sCompanyName := company.Name;\r\n    end;\r\n  end;\r\n<\/pre>\n<p>This example takes advantage of in-line, scoped variable declarations and type inferencing to improve things at least as far as possible.  The equivalent in Delphi would be even more messy.<\/p>\n<p>It is however unlikely that you would find such attention being paid to runtime efficiency given the aversion to &#8220;premature optimisation&#8221; and unnecessary typing that seems so prevalent these days.  That, and the lack of in-line variable declarations and type inferencing means that you would be far more likely to encounter something like:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  user := fUsers.getUserByName(aUserName);\r\n  if Assigned(user) and Assigned(user.Details) and Assigned(user.Details.Company) then\r\n    sCompanyName := user.Details.Company.Name\r\n  else\r\n    sCompanyName := '';\r\n<\/pre>\n<p>You will notice that in the case where there is a valid <strong>Company.Name<\/strong> to be retrieved, the above code evaluates <strong>user.Details<\/strong> no less than 3 (three!) times.  If you are lucky, neither <strong>Details<\/strong> nor <strong>Company<\/strong> will be relatively expensive property accessor functions.  Of course, they might not be when this code is first written, but that could change.<\/p>\n<p>The Oxygene colon operator allows us to write code that at runtime is exactly equivalent to that first example however, but to do it in a single line of code:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  sCompanyName := fUsers.getUserByName(aUserName):Details:Company:Name; \r\n<\/pre>\n<h2>Not Your Grand-Daddy&#8217;s Java<\/h2>\n<p>So much for these additions to Pascal.  However, there are also some things that we are well used to in Pascal &#8211; especially Delphi &#8211; that at first blush at least appear to be missing in Java.<\/p>\n<p>Fortunately, Oxygene can ease the transition by adding support for some of these itself.<\/p>\n<ul>\n<li>get\/set Methods as Properties<\/li>\n<li>Class References<\/li>\n<li>Virtual Class Methods and Constructors<\/li>\n<li>By-Reference Parameters and Records<\/li>\n<\/ul>\n<h3>get\/set Methods as Properties<\/h3>\n<p>Java has no formal concept of properties.  Instead the language has adopted a pattern based approach adopted from Java Beans, settling on the use of <strong>getPropertyName()<\/strong> and <strong>setPropertyName()<\/strong>.<\/p>\n<p>Oxygene recognises this pattern and exposes methods (which fit) as properties.<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  var i := new Intent;\r\n\r\n  i.Action := Intent.ACTION_POWER_CONNECTED:  \/\/ i.setAction( Intent.ACTION_POWER_CONNECTED );\r\n<\/pre>\n<p>Not all such methods fit this pattern.  If a <code>get..()<\/code> method has a void result (does not return a value) for example, then it is not a property accessor and cannot be treated as such.<\/p>\n<p>This is purely syntactic sugar, however.  You can still use the formal Java methods directly if you wish (or if the parameter lists do not suit a property style invocation).<\/p>\n<h3>Class References<\/h3>\n<p><strong>Java<\/strong> has a <strong>Class<\/strong> type and every <strong>Object<\/strong> has a <strong>Class<\/strong> member which exposes the underlying <strong>Class<\/strong> type.  But (from what I understand) this is not quite as capable* as Delphi&#8217;s class references concept, at least not without a great deal more work on the part of the developer.<\/p>\n<p>*: In one area, Java class types serve a purpose which Oxygene class references do not (currently?) appear to.  That is, to serve as class identities, as <a href=\"http:\/\/stackoverflow.com\/questions\/19350576\/how-do-you-compare-an-oxygene-class-reference-to-classes\">discussed in this stackoverflow question<\/a>.<\/p>\n<p>Fortunately <strong>Oxygene<\/strong> implements Delphi-like class references for us as well.<\/p>\n<p>Consider the following class with two constructors, one parameterless and one accepting an integer parameter:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  type\r\n    Foo = public class\r\n      constructor;\r\n      constructor(aID: Integer);\r\n    end;\r\n    FooClass = class of Foo;\r\n<\/pre>\n<p>Using the <strong>FooClass<\/strong> class type, the declaration of which will be familiar to any Delphi developer, we can do everything we would expect.  We can declare class reference parameters and use those references to create instances of the referenced class using any of it&#8217;s supported constructors:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  method Bar.createFoo(aFooClass: FooClass; aID: Integer): Foo;\r\n  begin\r\n    result := new aFooClass(aID);\r\n  end;\r\n<\/pre>\n<p>This <em>is<\/em> possible in Java (it must be, given that Oxygene compiles to the JVM byte code) but is <a href=\"http:\/\/docs.oracle.com\/javase\/tutorial\/reflect\/member\/ctorInstance.html\">far more complex, involving reflection<\/a> if you need to invoke anything other than parameterless constructors.<\/p>\n<p>I suspect that the Oxygene class reference implementation is founded on these underlying capabilities of Java, but surfaces them in a far more usable fashion!<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  var\r\n    fc: FooClass;\r\n    jc: &amp;Class&lt;Foo&gt;;\r\n    f: Foo;\r\n  begin\r\n    fc := FooClass;   \r\n    f := new fc(42);  \r\n\r\n    \/\/ Two ways of obtaining the Java Class type, from a class and from an object:\r\n\r\n    jc := typeOf(Foo);      \/\/ equivalent of ' = Foo.Class' in Java\r\n    jc := f.&amp;Class;\r\n\r\n    \/\/ Instantiating a new class using Java Class type:\r\n\r\n    f := jc.newInstance;\r\n    f.setID(42);\r\n  end;\r\n<\/pre>\n<p><strong>Note: <\/strong>Since the Java <strong>Class<\/strong> mechanism uses <code>Class<\/code> as an identifier, thus clashing with the <strong>class<\/strong> keyword in <strong>Oxygene<\/strong>, use of the Java <code>Class<\/code> identifier has to be qualified with the identifier prefix &#8216;<strong>&#038;<\/strong>&#8216;, just as we would in Delphi in such cases.<\/p>\n<h3>Virtual Class Methods, Including Constructors<\/h3>\n<p>The real power of class references in Delphi stems from combining them with virtual class methods and virtual constructors.  And yes, by some wizardry, these too are supported by Oxygene for Java !<\/p>\n<p>Given these hypothetical declarations of an <strong>Employee<\/strong> and a <strong>Person<\/strong> class:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  Person = public class\r\n  public\r\n    constructor; virtual;\r\n    class method getMessage: String; virtual;\r\n  end;\r\n  PersonClass = class of Person;\r\n\r\n\r\n  Employee = public class(Person)\r\n  public\r\n    constructor; override;\r\n    class method getMessage: String; override;\r\n  end;\r\n<\/pre>\n<p>The details of the <code>constructors<\/code> and the <code>getMessage<\/code> methods aren&#8217;t important, other than that the <strong>Employee<\/strong> constructor must obviously call <code>inherited<\/code> while in the case of <code>getMessage<\/code> this is not important and we simply return a different string from the version of this method on each class allowing us to easily determine which class was invoked.<\/p>\n<p>We get the expected results from this sort of code:<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\nvar\r\n  fc: FooClass;\r\n  f: Foo;\r\n  s: String;\r\nbegin\r\n  fc := Bar;\r\n  f := new fc;\r\n\r\n  s := f.Class.Name;    \/\/ yields = 'Bar'\r\n\r\n  s := f.getMessage;    \/\/ calls Bar.getMessage\r\nend;\r\n<\/pre>\n<p>One thing to note here however is that type inferencing does not work for variables that are class reference types.  I am not sure if this is by design, an unavoidable consequence of the implementation details, or whether it is simply a bug.  Either way, it&#8217;s not a huge problem.<\/p>\n<p>I have not looked to see how a class reference or virtual constructors such things appear to a Java developer consuming an Oxygene class.<\/p>\n<h2>With A Little Help From My Friends<\/h2>\n<p>There are a couple of further things that <strong>Oxygene<\/strong> adds to Java but which rely on an additional RTL support package (a <strong>jar<\/strong> file) called <strong>com.remobjects.oxygene.rtl<\/strong>.<\/p>\n<h3>By-Reference Parameters and Records<\/h3>\n<p>In Java, everything passed as a parameter to a method call is always, <em>always<\/em> passed <strong>by value<\/strong>.  There are no <strong>by reference<\/strong> parameters in Java (<strong>var<\/strong> parameters in Pascal\/Delphi speak).<\/p>\n<p>Unless you are using Oxygene.<\/p>\n<pre class=\"brush: oxygene; title: ; notranslate\" title=\"\">\r\n  BatteryUtil = public class\r\n  public\r\n    method getBatteryInfo(var aPercent: Integer; var aCharging: Boolean);\r\n  end;\r\n<\/pre>\n<p>If you use <strong>var<\/strong> parameters and your project does not reference the required RTL library you will be prompted to add it by a compiler error.<\/p>\n<p>You will get a similar prompt to add the same library (if you are not using it) if you use another language feature that you may be used to in Pascal\/Delphi:  <strong>records<\/strong>.<\/p>\n<p>Java has no specific support for <strong>record<\/strong> types or (<strong>struct<\/strong>s, if you prefer).  But Oxygene does.  Again, via the RTL support library.<\/p>\n<h2>Is There NOTHING That Oxygene Can&#8217;t Do ?<\/h2>\n<p>It might seem like that, but actually there is (at least) one thing.<\/p>\n<p>If you look at the extensions to the Java language capabilities that Oxygene provides, they all rely on encapsulating existing techniques in the JVM for achieving things that other languages support by first class means, elevating these capabilities to first class status in Oxygene itself, without breaking the fact that underneath it all sits Java itself.<\/p>\n<p>Ironically, there is (at least) one area where Java is so much more capable than the Pascal language the an existing first-class capability of Pascal appears not to be so easily portable to Java.<\/p>\n<p>Enums can be declared just as in Pascal, but <strong>set<\/strong> type declarations are <strong>not<\/strong> supported.<\/p>\n<p>The only reason I can think of for this omission is that Java already has comprehensive support for sets in it&#8217;s collections support.  As such there is perhaps not one, definitive, &#8220;set&#8221; type onto which a simple &#8220;<strong>set of<\/strong>&#8221; declaration can be usefully mapped.  Any Java class that an Oxygene developer may need to work with might have chosen some other set type.<\/p>\n<p>Perhaps RemObjects have in mind to provide a more versatile syntax to surface the Java set types in the language and are holding off on implementing this until they are sure they have a comprehensive solution.  Or perhaps they simply feel there is no need.<\/p>\n<p>Either way, in the meantime declaring a set using the Java framework classes is not much different than a first class &#8220;set type&#8221; would provide.  You will also not encounter any Pascal\/Oxygene sets in any Java classes you work with, so the omission is not likely to pose a problem, other than if you wished to use a Pascal set type in some cross-platform, portable Oxygene code.  On that score, the NSSet (and NSMutableSet) type on Cocoa is similarly quite different to the Pascal type, again making a language-level mapping less useful than simply providing first-class access to the platform framework capabilities.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">9<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> I&#8217;ve mentioned some of the cool stuff in the Oxygene language in various posts and thought it would be a good idea to list them again, along with some others that I&#8217;ve not previously mentioned.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":[]},"categories":[212,205,4,204,180],"tags":[237,239,225,13,181,238,236],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-um","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":2523,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2523\/","url_meta":{"origin":1882,"position":0},"title":"Anonymous Classes: Anonymous POCO&#8217;s","date":"14 Feb 2017","format":false,"excerpt":"There is another use case for anonymous classes, even simpler than that of providing implementations of interfaces: Anonymous POCO's. We're all familiar with the idea of declaring a class that identifies the members that all instances (objects) of that class have, and then creating instances of that class. Anonymous classes,\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/code-completion-java.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1634,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1634\/","url_meta":{"origin":1882,"position":1},"title":"An App With View","date":"17 Sep 2013","format":false,"excerpt":"Not a Merchant Ivory production, but Part 3 in the Oxygene for Java camera app for Android series. So far we have seen that we can work directly with the Android platform manifest and layout files and how the Oxygene language is a first class citizen in the Java platform\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1503,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1503\/","url_meta":{"origin":1882,"position":2},"title":"Sharing Code Across Platforms in Oxygene","date":"22 Aug 2013","format":false,"excerpt":"There seems to be a perception among some people that Delphi is in the unique position of allowing developers to share and re-use code across the various platforms that it's compiler can now (and will soon) target. But this is not the case. Oxygene has had this capability right from\u2026","rel":"","context":"In &quot;Cooper&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1624,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1624\/","url_meta":{"origin":1882,"position":3},"title":"Exploring Listeners With Oxygene","date":"16 Sep 2013","format":false,"excerpt":"Part 2 in a short series demonstrating the development of a simple camera app for Android using Oxygene. In the previous instalment we looked at the basic framework of our app. For this instalment I was going to show how to implement the camera preview or viewfinder for this instalment,\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1713,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1713\/","url_meta":{"origin":1882,"position":4},"title":"How to Call Java Code from an Oxygene Android Application","date":"20 Sep 2013","format":false,"excerpt":"Lachlan just posted a link to a post on Google+ (also available as a PDF) demonstrating how to call Java from Delphi XE5. I was shocked at both the amount and the nature of the code involved. It is long, convoluted and ugly stuff (nb. that isn't a criticism of\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1817,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1817\/","url_meta":{"origin":1882,"position":5},"title":"Getting the Battery Level on Android With Delphi","date":"01 Oct 2013","format":false,"excerpt":"Over the past few days I posted a two part series showing how to obtain the current battery level as part of the implementation of an Android AppWidget using Oxygene. As far as I can tell AppWidgets simply aren't possible using Delphi but reading the battery is quite straightforward Android\u2026","rel":"","context":"In &quot;Android&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1882"}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=1882"}],"version-history":[{"count":19,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1882\/revisions"}],"predecessor-version":[{"id":1909,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/1882\/revisions\/1909"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=1882"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=1882"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=1882"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}