<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Writing on Andy Foster</title><link>https://andyfoster.net/posts/</link><description>Recent content in Writing on Andy Foster</description><generator>Hugo</generator><language>en-GB</language><lastBuildDate>Thu, 19 Dec 2024 12:00:00 +1300</lastBuildDate><atom:link href="https://andyfoster.net/posts/index.xml" rel="self" type="application/rss+xml"/><item><title>Comparing Symfony’s Access Control Methods</title><link>https://andyfoster.net/symfony-access-control/</link><pubDate>Thu, 19 Dec 2024 12:00:00 +1300</pubDate><guid>https://andyfoster.net/symfony-access-control/</guid><description>&lt;p&gt;In Symfony, there are multiple ways to control access to actions within controllers. Two of the most commonly seen approaches are using programmatic checks (like &lt;code&gt;$this-&amp;gt;denyAccessUnlessGranted()&lt;/code&gt;) and annotation-based checks (like &lt;code&gt;@Security(...)&lt;/code&gt; or &lt;code&gt;@IsGranted(...)&lt;/code&gt;).&lt;/p&gt;&#10;&lt;h2 id="this-denyaccessunlessgrantedview-instrument"&gt;&lt;code&gt;$this-&amp;gt;denyAccessUnlessGranted('view', $instrument)&lt;/code&gt; &lt;a class="heading-anchor" href="#this-denyaccessunlessgrantedview-instrument" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;Mechanism:&lt;/strong&gt;&#10;This is an imperative style check that you place directly in your controller code. It uses the Symfony &lt;code&gt;Security&lt;/code&gt; component and voters to determine whether the current user is allowed to perform a certain action (in this case, &lt;code&gt;'view'&lt;/code&gt;) on a given object (in this case, &lt;code&gt;$instrument&lt;/code&gt;).&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;How it Works:&lt;/strong&gt;&#10;When you call &lt;code&gt;$this-&amp;gt;denyAccessUnlessGranted('view', $instrument)&lt;/code&gt;, Symfony looks for voters that can handle the &lt;code&gt;'view'&lt;/code&gt; attribute and the &lt;code&gt;Instrument&lt;/code&gt; class. These voters return either &lt;code&gt;ACCESS_GRANTED&lt;/code&gt;, &lt;code&gt;ACCESS_DENIED&lt;/code&gt;, or &lt;code&gt;ACCESS_ABSTAIN&lt;/code&gt;. If the result is not granted, an &lt;code&gt;AccessDeniedException&lt;/code&gt; is thrown.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Fine-grained, object-level permissions.&lt;/li&gt;&#10;&lt;li&gt;Good for complex scenarios where you rely on custom Voters.&lt;/li&gt;&#10;&lt;li&gt;Allows conditional logic before performing the security check since it’s inline in your code.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;You need to remember to call it each time you want to enforce security on an endpoint.&lt;/li&gt;&#10;&lt;li&gt;Logic can clutter controllers if you have multiple checks.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Run a PHP script as a daemon</title><link>https://andyfoster.net/daemon-in-php/</link><pubDate>Sun, 15 Dec 2024 15:25:50 +1200</pubDate><guid>https://andyfoster.net/daemon-in-php/</guid><description>&lt;p&gt;Below is a simple example of a PHP script and guidance on how you could run it as a daemon.&lt;/p&gt;&#10;&lt;h2 id="example-php-script"&gt;Example PHP Script &lt;a class="heading-anchor" href="#example-php-script" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Create a file called &lt;code&gt;daemon_example.php&lt;/code&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#!/usr/bin/php&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="nx"&gt;php&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// This script simply writes a timestamp to a log file every 10 seconds.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;$logFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/tmp/mydaemon.log&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Y-m-d H:i:s&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;file_put_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$logFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Current time: &lt;/span&gt;&lt;span class="si"&gt;$timestamp&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FILE_APPEND&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Key Points About the Script:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;It runs an infinite loop.&lt;/li&gt;&#10;&lt;li&gt;Every 10 seconds, it appends the current time to the file &lt;code&gt;/tmp/mydaemon.log&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;The &lt;code&gt;#!/usr/bin/php&lt;/code&gt; shebang line ensures it can be run directly (if the file is executable).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="making-the-script-executable"&gt;Making the Script Executable &lt;a class="heading-anchor" href="#making-the-script-executable" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;In a terminal, run:&lt;/p&gt;</description></item><item><title>Checkout a branch name in all directories</title><link>https://andyfoster.net/switch-all-dirs-to-develop/</link><pubDate>Sat, 14 Dec 2024 15:25:50 +1200</pubDate><guid>https://andyfoster.net/switch-all-dirs-to-develop/</guid><description>&lt;p&gt;We have a bunch of different repos that all have &lt;code&gt;develop&lt;/code&gt; as their main branch. Sometimes I am working in various feature branches and then want to check out &lt;code&gt;develop&lt;/code&gt; in all of them.&lt;/p&gt;&#10;&lt;p&gt;Here&amp;rsquo;s a concise one-liner to switch to the &lt;code&gt;develop&lt;/code&gt; branch for each folder under your current working directory:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; dir in */&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -d &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;/.git&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git checkout develop&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This one does a git pull as well:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; dir in */&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -d &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;/.git&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="nv"&gt;$dir&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git checkout develop &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git pull&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Getting your CSS Changes from DevTools</title><link>https://andyfoster.net/copying-changes-from-devtools/</link><pubDate>Thu, 22 Feb 2024 10:12:00 +1200</pubDate><guid>https://andyfoster.net/copying-changes-from-devtools/</guid><description>&lt;p&gt;I&amp;rsquo;ve been doing a lot of work on my Chrome extension, &lt;a href="https://andyfoster.net/projects/daywatch/"&gt;DayWatch&lt;/a&gt;, lately. Having my own extension open up whenever I open a new tab is great because it&amp;rsquo;s exactly the way I want it, but the other edge of the sword is that whenever I see something not right I have to dive in and fix it.&lt;/p&gt;&#10;&lt;p&gt;Being a website is great though. I can pop open the DevTools whenever I want and make little tweaks to the CSS, adding a bit of padding here and removing some margin there to make it look exactly right. The only problem is that after I have it looking how I want, I can&amp;rsquo;t remember all of the changes I made across all the different elements to put it into the stylesheet. I also mess with the :hover state so it&amp;rsquo;s all tucked away.&lt;/p&gt;</description></item><item><title>g stands for something different every gRPC release</title><link>https://andyfoster.net/grpc-g-stands-for-something-different/</link><pubDate>Mon, 19 Feb 2024 10:12:00 +0530</pubDate><guid>https://andyfoster.net/grpc-g-stands-for-something-different/</guid><description>&lt;p&gt;Here&amp;rsquo;s a funny thing I found:&lt;/p&gt;&#10;&lt;p&gt;&amp;lsquo;g&amp;rsquo; stands for something different every gRPC release&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;1.0 &amp;lsquo;g&amp;rsquo; stands for &amp;lsquo;gRPC&amp;rsquo;&lt;/li&gt;&#10;&lt;li&gt;1.1 &amp;lsquo;g&amp;rsquo; stands for &amp;lsquo;good&amp;rsquo;&lt;/li&gt;&#10;&lt;li&gt;1.2 &amp;lsquo;g&amp;rsquo; stands for &amp;lsquo;green&amp;rsquo;&lt;/li&gt;&#10;&lt;li&gt;1.3 &amp;lsquo;g&amp;rsquo; stands for &amp;lsquo;gentle&amp;rsquo;&lt;/li&gt;&#10;&lt;li&gt;1.4 &amp;lsquo;g&amp;rsquo; stands for &amp;lsquo;gregarious&amp;rsquo;&lt;/li&gt;&#10;&lt;li&gt;1.6 &amp;lsquo;g&amp;rsquo; stands for &amp;lsquo;garcia&amp;rsquo;&lt;/li&gt;&#10;&lt;li&gt;and many more&amp;hellip;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;a href="https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md"&gt;See the full list on GitHub&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Y Combinator's Ideas for Future Tech</title><link>https://andyfoster.net/ycombinator-rfs-2024/</link><pubDate>Thu, 15 Feb 2024 10:12:00 +0530</pubDate><guid>https://andyfoster.net/ycombinator-rfs-2024/</guid><description>&lt;p&gt;The startup incubator Y Combinator released an interesting &lt;a href="https://www.ycombinator.com/rfs"&gt;&amp;ldquo;Request for Startups&amp;rdquo; document&lt;/a&gt; where they have a list of some promising fields in which they&amp;rsquo;d like to invest in companies. How they seem to work is that they will hear a pitch from a founder (but they prefer co-founders) on a business to invest in and work with the founders over a few months. Often the business that was pitched &amp;ldquo;pivots&amp;rdquo; so much, it&amp;rsquo;s unrecognisable so Y Combinator has said they invest in the founders rather than the initial idea.&lt;/p&gt;</description></item><item><title>Control Access with the Proxy Pattern</title><link>https://andyfoster.net/proxy-pattern/</link><pubDate>Thu, 25 Jan 2024 09:00:50 +1200</pubDate><guid>https://andyfoster.net/proxy-pattern/</guid><description>&lt;p&gt;The Proxy Pattern is a structural design pattern commonly used in object-oriented programming. This pattern provides a surrogate or placeholder object, known as a proxy, to control access to another object, which could be remote, expensive to create, or needs to be secured. The Proxy Pattern is particularly useful for performing operations before or after the request gets to the primary object, such as access control, logging, or lazy instantiation.&lt;/p&gt;</description></item><item><title>React and JSX on a single HTML page</title><link>https://andyfoster.net/react-and-jsx-without-imports/</link><pubDate>Wed, 24 Jan 2024 17:30:50 +1200</pubDate><guid>https://andyfoster.net/react-and-jsx-without-imports/</guid><description>&lt;h2 id="introduction"&gt;Introduction &lt;a class="heading-anchor" href="#introduction" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;As much as tools like &lt;code&gt;create-react-app&lt;/code&gt;, &lt;code&gt;Next.js&lt;/code&gt;, and &lt;code&gt;Gatsby.js&lt;/code&gt; have streamlined React development, there are times when setting up an entire project feels like overkill – especially when you just want to test a small idea. While &lt;a href="https://vitejs.dev/"&gt;Vite&lt;/a&gt; offers a faster alternative, sometimes what you need is the simplest possible setup. This is where crafting a React app within a single HTML page becomes invaluable. It&amp;rsquo;s quick, straightforward, and lets you test out your ideas in real-time.&lt;/p&gt;</description></item><item><title>Voting for Ideas Not Politicians</title><link>https://andyfoster.net/vote-for-ideas-not-politicians/</link><pubDate>Mon, 22 Jan 2024 10:12:00 +1200</pubDate><guid>https://andyfoster.net/vote-for-ideas-not-politicians/</guid><description>&lt;p&gt;&lt;a href="https://www.elysian.press/p/we-need-to-get-rid-of-politicians"&gt;We need to get rid of politicians - Elle Griffin&lt;/a&gt;&lt;/p&gt;&#10;&lt;blockquote&gt;&#10; &lt;p&gt;The problem with politicians is that they are merely a figurehead. If they look like this, they will get this vote. If they say that, they will secure that vote. If they are into this thing, they will appeal to this group. If they are not into that thing, they will appeal to that group. If they stay neutral on this topic, they will be able to reach this larger group.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;</description></item><item><title>Basic Postgres Commands</title><link>https://andyfoster.net/postgres-commands-basic/</link><pubDate>Sun, 21 Jan 2024 15:25:50 +1200</pubDate><guid>https://andyfoster.net/postgres-commands-basic/</guid><description>&lt;p&gt;PostgreSQL commands can be broadly divided into command-line tools and SQL commands or functions you&amp;rsquo;d use within the &lt;code&gt;psql&lt;/code&gt; interface. I&amp;rsquo;ll provide an overview of both:&lt;/p&gt;&#10;&lt;h2 id="command-line-tools"&gt;Command-Line Tools &lt;a class="heading-anchor" href="#command-line-tools" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;psql&lt;/code&gt;&lt;/strong&gt;: The PostgreSQL command-line client.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Connect to a database: &lt;code&gt;psql -h [hostname] -U [username] -d [database_name]&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;List all databases: &lt;code&gt;psql -l&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;createdb&lt;/code&gt;&lt;/strong&gt;: Create a new PostgreSQL database.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Create a database: &lt;code&gt;createdb [database_name]&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;dropdb&lt;/code&gt;&lt;/strong&gt;: Remove a PostgreSQL database.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Drop a database: &lt;code&gt;dropdb [database_name]&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;createuser&lt;/code&gt;&lt;/strong&gt;: Create a new PostgreSQL role/user.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Create a new user: &lt;code&gt;createuser [username]&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;dropuser&lt;/code&gt;&lt;/strong&gt;: Remove a PostgreSQL role/user.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Drop a user: &lt;code&gt;dropuser [username]&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;pg_dump&lt;/code&gt;&lt;/strong&gt;: Create a backup of a PostgreSQL database.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Create a backup: &lt;code&gt;pg_dump [database_name] &amp;gt; backup.sql&lt;/code&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;&lt;code&gt;pg_restore&lt;/code&gt;&lt;/strong&gt;: Restore a PostgreSQL database from a custom-format backup.&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Create a custom-format backup: &lt;code&gt;pg_dump -Fc [database_name] &amp;gt; backup.dump&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;Restore it: &lt;code&gt;pg_restore -d [database_name] backup.dump&lt;/code&gt;&lt;/li&gt;&#10;&lt;li&gt;A plain &lt;code&gt;.sql&lt;/code&gt; dump is restored with &lt;code&gt;psql -d [database_name] -f backup.sql&lt;/code&gt; instead.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;</description></item><item><title>User Experience Mockup for Elections</title><link>https://andyfoster.net/election-user-interface/</link><pubDate>Sat, 20 Jan 2024 15:00:50 +1200</pubDate><guid>https://andyfoster.net/election-user-interface/</guid><description>&lt;figure&gt;&lt;img src="https://andyfoster.net/election-user-interface/electionsUI.gif" alt="GIF of my elections app mockup" width="233" height="480" loading="lazy"&gt;&lt;/figure&gt;&lt;h2 id="introduction"&gt;Introduction &lt;a class="heading-anchor" href="#introduction" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The brief was to design an easy-to-use interface for a voting app. The app would be used by people who are not tech-savvy, so the interface needed to be simple and intuitive.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img&#10; src="https://andyfoster.net/election-user-interface/example-party-vote_hu_b3911cdcfaa60932.webp" srcset="https://andyfoster.net/election-user-interface/example-party-vote_hu_752a623093c95293.webp 640w" sizes="(min-width: 728px) 680px, 100vw"&#10; width="712" height="1450"&#10; alt="Mockup of Party Vote page" loading="lazy" decoding="async"&gt;&lt;/figure&gt;&lt;p&gt;I used &lt;a href="https://balsamiq.com/"&gt;Balsamiq&lt;/a&gt; to create the mockup in the above images. I came up with a clear and easy-to-use interface that behaves just as the user expects and if implemented, would allow users to vote quickly and easily.&lt;/p&gt;</description></item><item><title>Making a browser in JavaFX: Lessons learned</title><link>https://andyfoster.net/custom-browser-in-javafx/</link><pubDate>Mon, 15 Jan 2024 11:25:50 +1200</pubDate><guid>https://andyfoster.net/custom-browser-in-javafx/</guid><description>&lt;p&gt;The project for this week was to build our own custom browser in JavaFX.&lt;/p&gt;&#10;&lt;h2 id="the-task"&gt;The task &lt;a class="heading-anchor" href="#the-task" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;blockquote&gt;&#10; &lt;p&gt;Create a browser using JavaFX WebView. Start 10am Monday morning and hand it in by 4pm Thursday.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;ul&gt;&#10;&lt;li&gt;Navigation&#10;&lt;ul&gt;&#10;&lt;li&gt;text for URL and button to load websites&lt;/li&gt;&#10;&lt;li&gt;Navigation buttons (e.g. back, forward, reload)&lt;/li&gt;&#10;&lt;li&gt;Allow flexible user interaction (e.g. typing both &amp;ldquo;&lt;code&gt;www.google.com&lt;/code&gt;&amp;rdquo; and &amp;ldquo;&lt;code&gt;http://www.google.com&lt;/code&gt;&amp;rdquo; works)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;Advanced website functionalities&#10;&lt;ul&gt;&#10;&lt;li&gt;Menu (e.g. history, bookmarks, print, HTML source)&lt;/li&gt;&#10;&lt;li&gt;Settings (e.g. setting home screen, colour theme, zoom)&lt;/li&gt;&#10;&lt;li&gt;Tabbed user interface&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="screenshots"&gt;Screenshots &lt;a class="heading-anchor" href="#screenshots" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;figure&gt;&lt;img&#10; src="https://andyfoster.net/custom-browser-in-javafx/browser-homepage_hu_e6363355d7427176.webp" srcset="https://andyfoster.net/custom-browser-in-javafx/browser-homepage_hu_bf6f9a57b6f34c42.webp 640w, https://andyfoster.net/custom-browser-in-javafx/browser-homepage_hu_bc4d4eeb3a04efe2.webp 960w, https://andyfoster.net/custom-browser-in-javafx/browser-homepage_hu_e6363355d7427176.webp 1280w, https://andyfoster.net/custom-browser-in-javafx/browser-homepage_hu_a52c12625e38bac7.webp 1600w" sizes="(min-width: 728px) 680px, 100vw"&#10; width="1280" height="1039"&#10; alt="Browser homepage" loading="lazy" decoding="async"&gt;&lt;/figure&gt;&lt;figure&gt;&lt;img&#10; src="https://andyfoster.net/custom-browser-in-javafx/browser-bookmarks_hu_b3b7ff664c9d4e20.webp" srcset="https://andyfoster.net/custom-browser-in-javafx/browser-bookmarks_hu_79abbdc7b141a17f.webp 640w, https://andyfoster.net/custom-browser-in-javafx/browser-bookmarks_hu_72341b363439d6e8.webp 960w, https://andyfoster.net/custom-browser-in-javafx/browser-bookmarks_hu_b3b7ff664c9d4e20.webp 1280w, https://andyfoster.net/custom-browser-in-javafx/browser-bookmarks_hu_8a89acba797923d0.webp 1600w" sizes="(min-width: 728px) 680px, 100vw"&#10; width="1280" height="1039"&#10; alt="Bookmarks page" loading="lazy" decoding="async"&gt;&lt;/figure&gt;&lt;figure&gt;&lt;img&#10; src="https://andyfoster.net/custom-browser-in-javafx/browser-settings_hu_ac0aa37d902fb5cb.webp" srcset="https://andyfoster.net/custom-browser-in-javafx/browser-settings_hu_137ca9ce30720d6e.webp 640w, https://andyfoster.net/custom-browser-in-javafx/browser-settings_hu_914a5b39c06cdf2a.webp 960w, https://andyfoster.net/custom-browser-in-javafx/browser-settings_hu_ac0aa37d902fb5cb.webp 1280w, https://andyfoster.net/custom-browser-in-javafx/browser-settings_hu_f1f54821c5234d36.webp 1600w" sizes="(min-width: 728px) 680px, 100vw"&#10; width="1280" height="1039"&#10; alt="Settings page" loading="lazy" decoding="async"&gt;&lt;/figure&gt;&lt;h2 id="new-things-i-learnt"&gt;New things I learnt &lt;a class="heading-anchor" href="#new-things-i-learnt" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;JavaFX TableView - pretty painful to build all the columns&lt;/li&gt;&#10;&lt;li&gt;A bit more about Maven and dependencies - using from inside IntelliJ IDEA&lt;/li&gt;&#10;&lt;li&gt;JavaFX TabPanes - programmatically opening and loading content into them&lt;/li&gt;&#10;&lt;li&gt;JavaFX WebView and WebEngine&lt;/li&gt;&#10;&lt;li&gt;Java Properties for storing my user settings in a text file&lt;/li&gt;&#10;&lt;li&gt;I used a Trello kanban board to keep track of things&#10;&lt;ul&gt;&#10;&lt;li&gt;I used the column headers: ToDo, In Progress, Bugs, Done but maybe using Not Started and Blocked columns might be better to have next time. There were so many features I thought I could add at the start, like Incognito and a custom app icon that just never got off the ground. Maybe a Wishlist column for things like that&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;I kept everything in Git.&lt;/li&gt;&#10;&lt;li&gt;Keep the &lt;code&gt;start()&lt;/code&gt;/&lt;code&gt;main()&lt;/code&gt; class small and try to move things into new method if not new classes - while balancing the overhead of working in different files.&lt;/li&gt;&#10;&lt;li&gt;Also got a good reminder to (should have known) not split code up too soon - moving bookmark functionality into a new class made it hard to call the parent&amp;rsquo;s openNewTab() method - I ended up passing a reference to the method into the new class.&#10;&lt;ul&gt;&#10;&lt;li&gt;I used the &lt;code&gt;Consumer&amp;lt;T&amp;gt;&lt;/code&gt; functional interface to represent the method signature.&lt;/li&gt;&#10;&lt;li&gt;When calling the &lt;code&gt;renderBookmarks&lt;/code&gt; method, pass the method reference.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;openNewBrowserTabWithURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Logic to open a new browser tab with the given URL&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// When calling the renderBookmarks method:&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;newTab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BookmarkManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;renderBookmarks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;openNewBrowserTabWithURL&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and then in the BookmarkManager class:&lt;/p&gt;</description></item><item><title>ObservableList in JavaFX</title><link>https://andyfoster.net/observable-list-javafx/</link><pubDate>Fri, 15 Dec 2023 15:00:50 +1200</pubDate><guid>https://andyfoster.net/observable-list-javafx/</guid><description>&lt;p&gt;Here is an example JavaFX application that demonstrates the use of an &lt;code&gt;ObservableList&lt;/code&gt;. This application will include a simple user interface where items can be added to or removed from the list, and the changes will be reflected in real-time on the UI.&lt;/p&gt;&#10;&lt;figure&gt;&lt;img&#10; src="https://andyfoster.net/observable-list-javafx/observable-list-example_hu_b695e5f11e14203c.webp" srcset="https://andyfoster.net/observable-list-javafx/observable-list-example_hu_a3932f4ba92b740f.webp 640w, https://andyfoster.net/observable-list-javafx/observable-list-example_hu_13563ff27e10f4db.webp 960w" sizes="(min-width: 728px) 680px, 100vw"&#10; width="1220" height="1074"&#10; alt="ObservableList Example" loading="lazy" decoding="async"&gt;&lt;/figure&gt;&lt;p&gt;Here&amp;rsquo;s a basic outline of the application:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Main Application Class&lt;/strong&gt;: This class extends &lt;code&gt;Application&lt;/code&gt; and sets up the primary stage.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;UI Elements&lt;/strong&gt;: Includes a &lt;code&gt;ListView&lt;/code&gt; to display the &lt;code&gt;ObservableList&lt;/code&gt;, and buttons to add or remove items.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;ObservableList&lt;/strong&gt;: A list that automatically updates the &lt;code&gt;ListView&lt;/code&gt; when items are added or removed.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="example-javafx-application-with-observablelist"&gt;Example JavaFX Application with ObservableList &lt;a class="heading-anchor" href="#example-javafx-application-with-observablelist" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;javafx.application.Application&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;javafx.collections.FXCollections&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;javafx.collections.ObservableList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;javafx.scene.Scene&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;javafx.scene.control.Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;javafx.scene.control.ListView&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;javafx.scene.layout.VBox&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;javafx.stage.Stage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ObservableListExample&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;extends&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ObservableList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;primaryStage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Initialize the ObservableList&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FXCollections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;observableArrayList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Create a ListView to display the items&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listView&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Buttons to add and remove items&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;addButton&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Add Item&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;removeButton&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Remove Selected Item&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Event Handler for addButton&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;addButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setOnAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;New Item &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Event Handler for removeButton&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;removeButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setOnAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;selectedIndex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSelectionModel&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getSelectedIndex&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selectedIndex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selectedIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Layout&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VBox&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;VBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;listView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;addButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;removeButton&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPadding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;javafx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;geometry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Insets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;10&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Set the scene and stage&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Scene&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;scene&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Scene&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;250&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;primaryStage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ObservableList Example&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;primaryStage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setScene&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;primaryStage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="how-to-run"&gt;How to Run &lt;a class="heading-anchor" href="#how-to-run" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&lt;strong&gt;Create a JavaFX Project&lt;/strong&gt;: Set up a JavaFX project in your IDE.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Add the Code&lt;/strong&gt;: Copy the above code into a new class file.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Run the Application&lt;/strong&gt;: Compile and run the application.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h2 id="explanation"&gt;Explanation &lt;a class="heading-anchor" href="#explanation" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;The &lt;code&gt;ObservableList&lt;/code&gt; is linked to the &lt;code&gt;ListView&lt;/code&gt;. Any changes to the list (additions or removals) will automatically update the &lt;code&gt;ListView&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;The &lt;code&gt;addButton&lt;/code&gt; adds a new item to the list.&lt;/li&gt;&#10;&lt;li&gt;The &lt;code&gt;removeButton&lt;/code&gt; removes the selected item from the list.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;This example is a simple demonstration of how an &lt;code&gt;ObservableList&lt;/code&gt; works in JavaFX. You can expand on this by adding more complex data types and additional UI elements.&lt;/p&gt;</description></item><item><title>Introduction to Design Patterns &amp; The Strategy Pattern</title><link>https://andyfoster.net/strategy-pattern/</link><pubDate>Fri, 24 Nov 2023 15:00:50 +1200</pubDate><guid>https://andyfoster.net/strategy-pattern/</guid><description>&lt;h2 id="introduction-to-design-patterns"&gt;Introduction to Design Patterns &lt;a class="heading-anchor" href="#introduction-to-design-patterns" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Definition of a design pattern.&lt;/li&gt;&#10;&lt;li&gt;Purpose and benefits of design patterns.&#10;&lt;ul&gt;&#10;&lt;li&gt;Reusability&lt;/li&gt;&#10;&lt;li&gt;Readability&lt;/li&gt;&#10;&lt;li&gt;Modularity&lt;/li&gt;&#10;&lt;li&gt;Scalability&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;Categories of design patterns:&#10;&lt;ul&gt;&#10;&lt;li&gt;Creational&lt;/li&gt;&#10;&lt;li&gt;Structural&lt;/li&gt;&#10;&lt;li&gt;Behavioral&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="dive-into-behavioral-patterns"&gt;Dive into Behavioral Patterns &lt;a class="heading-anchor" href="#dive-into-behavioral-patterns" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Brief explanation of Behavioral patterns.&lt;/li&gt;&#10;&lt;li&gt;Emphasis on how they handle object collaboration and responsibilities.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="introduction-to-the-strategy-pattern"&gt;Introduction to the Strategy Pattern &lt;a class="heading-anchor" href="#introduction-to-the-strategy-pattern" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Definition of the Strategy pattern.&lt;/li&gt;&#10;&lt;li&gt;Objective: Define a family of algorithms, encapsulate each one, and make them interchangeable.&lt;/li&gt;&#10;&lt;li&gt;Key components:&#10;&lt;ul&gt;&#10;&lt;li&gt;Context&lt;/li&gt;&#10;&lt;li&gt;Strategy&lt;/li&gt;&#10;&lt;li&gt;ConcreteStrategy&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="real-life-analogy-for-strategy-pattern"&gt;Real-life analogy for Strategy Pattern &lt;a class="heading-anchor" href="#real-life-analogy-for-strategy-pattern" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Example: Different travel modes (walking, driving, flying) to reach a destination.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="code-examples"&gt;Code Examples &lt;a class="heading-anchor" href="#code-examples" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;h3 id="class-diagram"&gt;Class diagram &lt;a class="heading-anchor" href="#class-diagram" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Context&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; |&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Strategy &amp;lt;--- ConcreteStrategy1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;lt;--- ConcreteStrategy2&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;lt;--- ConcreteStrategy3&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="basic-implementation"&gt;Basic implementation &lt;a class="heading-anchor" href="#basic-implementation" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Strategy&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;TravelStrategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;travel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// ConcreteStrategies&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WalkStrategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TravelStrategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;travel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Walking to destination&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DriveStrategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TravelStrategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;travel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Driving to destination&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FlyStrategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;implements&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TravelStrategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;travel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Flying to destination&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Context&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Traveler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TravelStrategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Traveler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TravelStrategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;setStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TravelStrategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;travel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;travel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="using-the-strategy-pattern"&gt;Using the Strategy pattern &lt;a class="heading-anchor" href="#using-the-strategy-pattern" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h3&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Client code&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Traveler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;john&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Traveler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;WalkStrategy&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;john&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;travel&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Output: Walking to destination&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;john&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DriveStrategy&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;john&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;travel&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// Output: Driving to destination&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="advantages-of-strategy-pattern"&gt;Advantages of Strategy Pattern &lt;a class="heading-anchor" href="#advantages-of-strategy-pattern" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Flexibility in swapping algorithms.&lt;/li&gt;&#10;&lt;li&gt;Decoupling of algorithm from the client that uses it.&lt;/li&gt;&#10;&lt;li&gt;Promotes Open/Closed principle.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="common-use-cases"&gt;Common Use Cases &lt;a class="heading-anchor" href="#common-use-cases" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Different payment methods in e-commerce applications.&lt;/li&gt;&#10;&lt;li&gt;Different compression techniques for files.&lt;/li&gt;&#10;&lt;li&gt;Varying rendering techniques in graphics engines.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="conclusion"&gt;Conclusion &lt;a class="heading-anchor" href="#conclusion" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;The importance of understanding design patterns in software development.&lt;/li&gt;&#10;&lt;li&gt;Encourage readers to experiment with the Strategy pattern and explore other design patterns.&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>Taking a Fence</title><link>https://andyfoster.net/taking-a-fence/</link><pubDate>Sun, 01 Oct 2023 10:12:00 +1200</pubDate><guid>https://andyfoster.net/taking-a-fence/</guid><description>&lt;p&gt;From the &lt;a href="https://www.mithral.com/~beberg/manifesto.html"&gt;Hacker&amp;rsquo;s Manifesto&lt;/a&gt;:&lt;/p&gt;&#10;&lt;blockquote&gt;&#10; &lt;p&gt;In deference to the author, I&amp;rsquo;ve not changed any of his punctuation.&#10;I have put a space between each paragraph for easier reading. I hope no one will &lt;strong&gt;take a fence&lt;/strong&gt; in my doings.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&lt;p&gt;&lt;a href="http://textfiles.com/100/hack7.txt"&gt;Read the original text file&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>UML Class Diagram</title><link>https://andyfoster.net/main-relationships-class-diagram/</link><pubDate>Sun, 01 Oct 2023 10:12:00 +1200</pubDate><guid>https://andyfoster.net/main-relationships-class-diagram/</guid><description>&lt;p&gt;Class diagrams are part of UML (Unified Modeling Language), which is a standardized graphical representation for specifying, visualizing, constructing, and documenting the artifacts of software systems. In class diagrams, various types of arrows are used to depict relationships between classes.&lt;/p&gt;&#10;&lt;p&gt;It&amp;rsquo;s kind of boring, business-like stuff, but it&amp;rsquo;s important to know the basics of UML class diagrams. They are used in many places, including design documents, code reviews, and technical interviews.&#10;Any complex system should probably be documented with UML diagrams, but for small projects, it&amp;rsquo;s usually enough to have a basic understanding of class diagrams.&lt;/p&gt;</description></item><item><title>Set up JavaFX</title><link>https://andyfoster.net/set-up-javafx/</link><pubDate>Mon, 18 Sep 2023 10:12:00 +1200</pubDate><guid>https://andyfoster.net/set-up-javafx/</guid><description>&lt;h2 id="update-your-java"&gt;Update your Java &lt;a class="heading-anchor" href="#update-your-java" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Update your Java, please. Visit &lt;a href="https://www.oracle.com/nz/java/technologies/downloads/"&gt;Oracle&amp;rsquo;s Java downloads page&lt;/a&gt; and choose your appropriate version. Ensure you note where you install it on your disk, as we will need to configure Eclipse later.&lt;/p&gt;&#10;&lt;h2 id="install-and-configure-javafx"&gt;Install and configure JavaFX &lt;a class="heading-anchor" href="#install-and-configure-javafx" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Install &lt;a href="https://openjfx.io/"&gt;JavaFX from openjfx.io&lt;/a&gt;. Remember the path where you unpacked the files to (i.e. on my machine: /Users/admin/eclipse-workspace/javafx-sdk-18.0.2/lib)&lt;/li&gt;&#10;&lt;li&gt;Install e(fx)clipse (&lt;a href="https://www.youtube.com/watch?v=bk28ytggz7E"&gt;video walkthrough&lt;/a&gt;)&#10;&lt;ol&gt;&#10;&lt;li&gt;Open Eclipse Marketplace.&lt;/li&gt;&#10;&lt;li&gt;Search for ‘JavaFX’&lt;/li&gt;&#10;&lt;li&gt;Install e(fx)clipse plugin&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;Create a new user library where you add all jar files from /Users/admin/eclipse-workspace/javafx-sdk-18.0.2/lib. Call this library ‘JavaFX-Lib’ or something else you remember.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 id="create-a-new-javafx-project"&gt;Create a new JavaFX project &lt;a class="heading-anchor" href="#create-a-new-javafx-project" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h3&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;File → New Project → JavaFX Project&lt;/li&gt;&#10;&lt;li&gt;Make sure you remove e(fx)clipse plugin JavaFX SDK as it is an old version of JavaFX from your build path&lt;/li&gt;&#10;&lt;li&gt;Add the user library you created in step 3 above (i.e. ‘JavaFX-Lib’) to your build path.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;Remember when you run your new JavaFX Project to change its configuration to allow running JavaFX as follows:&lt;/p&gt;</description></item><item><title>Aggregation vs Composition in UML</title><link>https://andyfoster.net/aggregations-vs-composition/</link><pubDate>Tue, 12 Sep 2023 10:12:00 +0530</pubDate><guid>https://andyfoster.net/aggregations-vs-composition/</guid><description>&lt;p&gt;In object-oriented design and programming, the concepts of aggregation and composition are used to establish relationships between classes. These relationships are often depicted in UML (Unified Modeling Language) diagrams and implemented in programming languages like Java. Let&amp;rsquo;s delve into both concepts and see how they differ.&lt;/p&gt;&#10;&lt;h2 id="uml-representation"&gt;UML Representation &lt;a class="heading-anchor" href="#uml-representation" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;Aggregation&lt;/strong&gt;: In UML, an aggregation relationship is depicted by a hollow diamond at the parent class end, pointing towards the child class.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Composition&lt;/strong&gt;: In UML, a composition relationship is depicted by a filled diamond at the parent class end, pointing towards the child class.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="java-representation"&gt;Java Representation &lt;a class="heading-anchor" href="#java-representation" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;In Java, both aggregation and composition can be implemented by using instance variables that refer to other objects.&lt;/p&gt;</description></item><item><title>Backup Chrome Tabs on Another Device</title><link>https://andyfoster.net/backup-chrome-tabs-on-another-device/</link><pubDate>Tue, 05 Sep 2023 02:12:29 +1200</pubDate><guid>https://andyfoster.net/backup-chrome-tabs-on-another-device/</guid><description>&lt;p&gt;Every time I hear something new, I open up a new Chrome tab on my iPhone and save it for later. I have a lot of tabs open on my phone and I want to back them up to my computer. Occasionally my Chrome will crash, losing all the tabs and there don&amp;rsquo;t seem to be any ways to get this back, besides going through your synced history and opening each tab again. Not ideal. If that&amp;rsquo;s happened to you, it could be too late, so back up your tabs now and avoid heartache later. And maybe find a new way to save things for later. I&amp;rsquo;m trying to move things over to Instapaper, but I&amp;rsquo;m really looking for a way to save each &amp;ldquo;journey&amp;rdquo; into some sort of notebook.&lt;/p&gt;</description></item><item><title>Have a dedicated window in Chrome without new tabs</title><link>https://andyfoster.net/dedicated-window-chrome/</link><pubDate>Wed, 30 Aug 2023 13:39:10 +1200</pubDate><guid>https://andyfoster.net/dedicated-window-chrome/</guid><description>&lt;p&gt;I am addicted to opening new tabs. I even created a &lt;a href="https://andyfoster.net/projects/daywatch/"&gt;browser extension&lt;/a&gt; to show me all my countdowns because I see that window so often. Often, however, I want to have a window open and not even let myself open new tabs inside it. Maybe it&amp;rsquo;s some instructions for an assignment that I don&amp;rsquo;t want to bury under dozens/hundreds of new tabs.&lt;/p&gt;&#10;&lt;p&gt;I found this method on &lt;a href="https://superuser.com/questions/1139544/disallow-new-tabs-in-chrome-window-open-new-tabs-in-other-window-instead"&gt;Super User&lt;/a&gt; that seems to do what I want. It even creates an icon from the site&amp;rsquo;s favicon so I can see it in my task switcher window.&lt;/p&gt;</description></item><item><title>How English is Changing In Front Of Our Eyes</title><link>https://andyfoster.net/english-changing-spanish/</link><pubDate>Tue, 29 Aug 2023 23:39:32 +1200</pubDate><guid>https://andyfoster.net/english-changing-spanish/</guid><description>&lt;p&gt;The structure of English in Miami is being changed by Spanish speakers. Very interesting.&lt;/p&gt;&#10;&lt;p&gt;From the New York Times: &lt;a href="https://www.nytimes.com/2023/08/29/opinion/miami-english-yiddish.html"&gt;Two Languages Walk Into a Bar&lt;/a&gt;&lt;/p&gt;&#10;&lt;blockquote&gt;&#10; &lt;p&gt;Miami is highly bilingual; in some neighborhoods, 90 percent of households use Spanish daily. But more interesting, perhaps, are the ways in which many Spanish-English bilinguals use expressions in English that are modeled on Spanish. It’s as if they are sometimes speaking English “in Spanish.” This is true not only of those whose first language was Spanish, but of second- and third-generation bilinguals, too.&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;</description></item><item><title>Traversing Hash Maps</title><link>https://andyfoster.net/traversing-hash-map-java/</link><pubDate>Tue, 29 Aug 2023 23:01:28 +1200</pubDate><guid>https://andyfoster.net/traversing-hash-map-java/</guid><description>&lt;p&gt;In Java, you can traverse a &lt;code&gt;HashMap&lt;/code&gt; in several ways. Here are some of them:&lt;/p&gt;&#10;&lt;h2 id="1-using-for-each-loop-with-entryset"&gt;1. Using For-Each Loop with &lt;code&gt;entrySet()&lt;/code&gt; &lt;a class="heading-anchor" href="#1-using-for-each-loop-with-entryset" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;You can use the &lt;code&gt;entrySet()&lt;/code&gt; method to get a set view of the mappings contained in the map. This set contains instances of the &lt;code&gt;Map.Entry&lt;/code&gt; class, each representing a key-value pair in the map.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.util.HashMap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;one&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;two&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;three&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Entry&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entrySet&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Key: &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getKey&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;#34;, Value: &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="2-using-for-each-loop-with-keyset"&gt;2. Using For-Each Loop with &lt;code&gt;keySet()&lt;/code&gt; &lt;a class="heading-anchor" href="#2-using-for-each-loop-with-keyset" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;You can use the &lt;code&gt;keySet()&lt;/code&gt; method to get a set view of the keys contained in the map, and then use these keys to look up the values.&lt;/p&gt;</description></item><item><title>Enums in Java</title><link>https://andyfoster.net/enums-in-java/</link><pubDate>Fri, 11 Aug 2023 10:12:00 +0530</pubDate><guid>https://andyfoster.net/enums-in-java/</guid><description>&lt;p&gt;Enumerations (enums) in Java are a special type of class that can have a set of constant values. This means that once an enum has been defined, the values in it cannot be modified. Enums are useful for representing fixed sets of related constants, such as days of the week, months of the year, or directions (NORTH, SOUTH, EAST, WEST).&lt;/p&gt;&#10;&lt;h2 id="basics-of-enum"&gt;Basics of Enum &lt;a class="heading-anchor" href="#basics-of-enum" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Here&amp;rsquo;s a basic example to define an enum for days of the week:&lt;/p&gt;</description></item><item><title>Altering the button appearance in the ECS100 library</title><link>https://andyfoster.net/altering-btn-in-ecs100/</link><pubDate>Fri, 11 Aug 2023 13:09:03 +1200</pubDate><guid>https://andyfoster.net/altering-btn-in-ecs100/</guid><description>&lt;p&gt;In the ECS100 library, there is not too much you can do to change the appearance of things but they&amp;rsquo;ve kindly allowed you to alter the button appearance as &lt;code&gt;UI.addButton()&lt;/code&gt; actually returns the button as well as putting it on the screen.&lt;/p&gt;&#10;&lt;p&gt;You just need to capture it in a variable and then make changes to it after that.&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;JButton&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;myButton&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;My Button&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;handleNewBtn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can customize the appearance of the button by setting properties such as the background color, foreground color, and font. For example:&lt;/p&gt;</description></item><item><title>My favourite and most used terminal commands</title><link>https://andyfoster.net/best-terminal-shortcuts/</link><pubDate>Fri, 11 Aug 2023 02:12:29 +1200</pubDate><guid>https://andyfoster.net/best-terminal-shortcuts/</guid><description>&lt;p&gt;If you&amp;rsquo;re a developer, or like messing with your computer, there&amp;rsquo;s no way to avoid the terminal. It&amp;rsquo;s almost all keyboard-based and can be intimidating when you first start. As you get used to it though, it becomes second-nature. Here are some shortcuts and tricks that will make your time in there far more pleasant.&lt;/p&gt;&#10;&lt;p&gt;This is my current list of useful things and I will keep coming back to update this.&lt;/p&gt;</description></item><item><title>Lightning Fast Code Search</title><link>https://andyfoster.net/silver-surfer-search/</link><pubDate>Thu, 10 Aug 2023 15:00:50 +1200</pubDate><guid>https://andyfoster.net/silver-surfer-search/</guid><description>&lt;p&gt;If you&amp;rsquo;re like me, you can never remember how to use grep properly to search for text inside files.&lt;/p&gt;&#10;&lt;p&gt;I can get by with a:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ grep -rnw . -e &lt;span class="s1"&gt;&amp;#39;todo&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&amp;hellip; but it&amp;rsquo;s not enough and I always have to look it up to use it properly. I&amp;rsquo;m about to make some alias shortcuts.&lt;/p&gt;&#10;&lt;p&gt;On my searches I found a tool called &lt;code&gt;ack&lt;/code&gt; which is dedicated to source code searching but before I had the chance to install it, I came across &lt;em&gt;The Silver Searcher&lt;/em&gt; (&lt;code&gt;$ ag&lt;/code&gt;) which claims to be a faster version of ack.&lt;/p&gt;</description></item><item><title>Parsing a text file delimited with dashes</title><link>https://andyfoster.net/parsing-text-files/</link><pubDate>Wed, 02 Aug 2023 15:00:50 +1200</pubDate><guid>https://andyfoster.net/parsing-text-files/</guid><description>&lt;p&gt;Let&amp;rsquo;s say you want to parse a text document with variable numbers of lines in each section and which is delimited with dashes:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Gabriel García Márquez&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1927 2014&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Cien años de soledad&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1967&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Crónica de una muerte anunciada&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1981&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;J. M. Coetzee&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1940&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Dusklands&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1974&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Life &amp;amp; Times of Michael K&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1983&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Disgrace&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1999&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Claude Simon&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1913 2005&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;L&amp;#39;Herbe&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1958&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Histoire&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1967&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Triptyque&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;1973&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ol&gt;&#10;&lt;li&gt;Open a Scanner over the entire books file&lt;/li&gt;&#10;&lt;li&gt;While there is still another String in the file&lt;/li&gt;&#10;&lt;li&gt;Save the following two lines as authorName and yearsActive (nasty that some are still alive)&lt;/li&gt;&#10;&lt;li&gt;Save that Author object&lt;/li&gt;&#10;&lt;li&gt;While there is another line in the file:&lt;/li&gt;&#10;&lt;li&gt;Put the next line into the &lt;code&gt;bookTitle&lt;/code&gt; variable&lt;/li&gt;&#10;&lt;li&gt;Check if that line is a &lt;code&gt;---&lt;/code&gt; delimiter and if so, break out of the loop and start at the top (step 2), getting a new author&lt;/li&gt;&#10;&lt;li&gt;If not, get the next line as the year (unfortunately saving the year as a string) and create a new Book object with these details and save it to the Author&amp;rsquo;s catalog.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Scanner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Scanner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;books.txt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasNext&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authorName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;yearsAlive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Author&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;authorName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;yearsAlive&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasNextLine&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bookName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bookName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;---&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bookYear&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;nextLine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bookName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bookYear&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addBook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOException&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;File error: &amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Sliding Window Problems</title><link>https://andyfoster.net/sliding-window-problems/</link><pubDate>Fri, 28 Jul 2023 13:00:50 +1200</pubDate><guid>https://andyfoster.net/sliding-window-problems/</guid><description>&lt;h2 id="introduction"&gt;Introduction &lt;a class="heading-anchor" href="#introduction" aria-label="Link to this section"&gt;#&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Sliding window problems are a common type of algorithmic challenge that involve iterating over a data structure, typically an array or a list, using a &amp;ldquo;window&amp;rdquo; of fixed size. As the name implies, this window &amp;ldquo;slides&amp;rdquo; over the data structure, helping to solve problems more efficiently.&lt;/p&gt;&#10;&lt;p&gt;The concept is surprisingly simple, yet mastering it can dramatically increase your problem-solving speed and efficiency, especially in fields like competitive programming or technical interviews.&lt;/p&gt;</description></item><item><title>Creating new aliases from the terminal</title><link>https://andyfoster.net/alias-to-make-persistent-aliases/</link><pubDate>Wed, 26 Jul 2023 15:25:50 +1200</pubDate><guid>https://andyfoster.net/alias-to-make-persistent-aliases/</guid><description>&lt;p&gt;If you are in the terminal enough, creating aliases from the command line is a great way to save time and be more productive.&lt;/p&gt;&#10;&lt;p&gt;You can type:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ &lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;ll&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;ls -la&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;but if you want these to stick around beyond the current session, you need to add it to your aliases file.&lt;/p&gt;&#10;&lt;p&gt;You can do this by creating a bash function that writes to your aliases file, and then making an alias for that function. Here&amp;rsquo;s how you can do it:&lt;/p&gt;</description></item><item><title>Make an alias to create and change into a new folder on the command line</title><link>https://andyfoster.net/alias-mkdir-and-cd/</link><pubDate>Wed, 26 Jul 2023 15:25:50 +1200</pubDate><guid>https://andyfoster.net/alias-mkdir-and-cd/</guid><description>&lt;p&gt;Sick of typing &lt;code&gt;$ cd someFolder&lt;/code&gt; and &lt;code&gt;$ mkdir someFolder&lt;/code&gt;? If you live in the terminal enough, it gets annoying. Here&amp;rsquo;s a shortcut.&lt;/p&gt;&#10;&lt;p&gt;Add the following alias to your bash profile (usually found at &lt;code&gt;~/.bashrc&lt;/code&gt; or &lt;code&gt;~/.bash_profile&lt;/code&gt;):&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;cdd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;function _cdd() { mkdir -p &amp;#34;$1&amp;#34; &amp;amp;&amp;amp; cd &amp;#34;$1&amp;#34;; unset -f _cdd; }; _cdd&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is how it works:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;alias cdd=...&lt;/code&gt; sets up the alias &lt;code&gt;cdd&lt;/code&gt; to the following command.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;function _cdd() {...}; _cdd&lt;/code&gt; is a temporary function that is immediately called. This structure is necessary because aliases can&amp;rsquo;t accept arguments directly. The function definition and call are both included in the alias command.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;mkdir -p &amp;quot;$1&amp;quot;&lt;/code&gt; creates a new directory with the name given by the first argument. The &lt;code&gt;-p&lt;/code&gt; flag tells &lt;code&gt;mkdir&lt;/code&gt; to create parent directories as needed.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; only runs the following command if the previous command succeeded, ensuring that we don&amp;rsquo;t &lt;code&gt;cd&lt;/code&gt; into a directory that wasn&amp;rsquo;t created successfully.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;cd &amp;quot;$1&amp;quot;&lt;/code&gt; changes the current working directory to the new directory.&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;unset -f _cdd&lt;/code&gt; removes the function definition after it&amp;rsquo;s used to avoid conflicts with any other functions or commands.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;Remember to source your bash profile after adding the alias for the changes to take effect. You can do this with the command &lt;code&gt;source ~/.bashrc&lt;/code&gt; or &lt;code&gt;source ~/.bash_profile&lt;/code&gt;, depending on which file you added the alias to.&lt;/p&gt;</description></item><item><title>Introduction to Recursion</title><link>https://andyfoster.net/recursion-intro/</link><pubDate>Tue, 24 Jan 2023 15:00:50 +1200</pubDate><guid>https://andyfoster.net/recursion-intro/</guid><description>&lt;p&gt;Recursion is a mind-bending topic.&lt;/p&gt;&#10;&lt;p&gt;Once you make a few methods, you may start to wonder, &amp;lsquo;can I call this method from &lt;em&gt;inside&lt;/em&gt; the method, Inception-style?&amp;rsquo;.&lt;/p&gt;&#10;&lt;p&gt;Well, yes, you can. It&amp;rsquo;s a bit mind-boggling but this is the fun part of programming, where you can feel your brain being stretched.&lt;/p&gt;&#10;&lt;p&gt;Recursion can make some problems far easier to solve and even in cases where the iterative method (loops), just won&amp;rsquo;t work.&#10;The problem is that it is very hard to visualise and understand how this works.&lt;/p&gt;</description></item><item><title>Hash Maps in Java</title><link>https://andyfoster.net/hash-maps-java/</link><pubDate>Mon, 23 Jan 2023 15:00:50 +1200</pubDate><guid>https://andyfoster.net/hash-maps-java/</guid><description>&lt;p&gt;Another very useful data structure is called a HashMap. This is simply a collection of data that is stored in the format &lt;code&gt;key: value&lt;/code&gt;, just like a dictionary. Some languages even call this structure a &amp;lsquo;dictionary&amp;rsquo;. The Hash part is because the key is passed into a method that &amp;ldquo;hashes&amp;rdquo; the letters in the key somehow and returns an integer. That integer tells Java where to store the value, so when you look up the key again, Java runs the same hashing function and can find it very quickly — O(1) on average.&lt;/p&gt;</description></item><item><title>Netrw Vim Nav Basics</title><link>https://andyfoster.net/netrw-basics/</link><pubDate>Mon, 23 Jan 2023 15:00:50 +1200</pubDate><guid>https://andyfoster.net/netrw-basics/</guid><description>&lt;p&gt;Netrw is a built-in plugin in Vim that lets you explore filesystems and network protocols such as ssh, ftp, http, etc. It&amp;rsquo;s a highly useful tool for browsing your local files or remote servers right from your Vim editor. Here&amp;rsquo;s how you can use it:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;To open Netrw:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;You can open netrw by typing &lt;code&gt;:Explore&lt;/code&gt;, &lt;code&gt;:E&lt;/code&gt; or &lt;code&gt;:Ex&lt;/code&gt; from within Vim. This will open a file explorer in the current directory.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;To navigate in Netrw:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;You can move up and down the file list using the arrow keys or &lt;code&gt;j&lt;/code&gt; and &lt;code&gt;k&lt;/code&gt;.&lt;/li&gt;&#10;&lt;li&gt;Press &lt;code&gt;Enter&lt;/code&gt; or &lt;code&gt;o&lt;/code&gt; to open a file or directory.&lt;/li&gt;&#10;&lt;li&gt;Press &lt;code&gt;-&lt;/code&gt; to move up to the parent directory.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;Creating, renaming, and deleting files:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;To create a directory, press &lt;code&gt;d&lt;/code&gt; and enter the directory name.&lt;/li&gt;&#10;&lt;li&gt;To create a file, press &lt;code&gt;%&lt;/code&gt; and enter the file name.&lt;/li&gt;&#10;&lt;li&gt;To rename a file or directory, place the cursor over it, press &lt;code&gt;R&lt;/code&gt;, and enter the new name.&lt;/li&gt;&#10;&lt;li&gt;To delete a file or directory, place the cursor over it and press &lt;code&gt;D&lt;/code&gt;.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;To navigate between multiple directories:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;You can split the screen into multiple windows, each viewing a different directory:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;:Vex&lt;/code&gt; or &lt;code&gt;:Vexplore&lt;/code&gt; to open a vertical split&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;:Sex&lt;/code&gt; or &lt;code&gt;:Sexplore&lt;/code&gt; to open a horizontal split&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;:Te&lt;/code&gt; or &lt;code&gt;:Texplore&lt;/code&gt; to open in a new tab&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;Accessing remote directories:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;You can open remote directories by typing the following command:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;code&gt;:e scp://user@host//path/to/directory&lt;/code&gt; for SSH&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;:e ftp://user@host/path/to/directory&lt;/code&gt; for FTP&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;You&amp;rsquo;ll need to replace &lt;code&gt;user&lt;/code&gt;, &lt;code&gt;host&lt;/code&gt;, and &lt;code&gt;/path/to/directory&lt;/code&gt; with the username, host address, and path of the directory you want to open, respectively.&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;Sorting files:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Press &lt;code&gt;s&lt;/code&gt; to sort files by name, date, size, or extension.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;&lt;strong&gt;File marking:&lt;/strong&gt;&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Press &lt;code&gt;mf&lt;/code&gt; to mark a file.&lt;/li&gt;&#10;&lt;li&gt;Press &lt;code&gt;mu&lt;/code&gt; to unmark a file.&lt;/li&gt;&#10;&lt;li&gt;Press &lt;code&gt;ma&lt;/code&gt; to mark all files.&lt;/li&gt;&#10;&lt;li&gt;Press &lt;code&gt;mr&lt;/code&gt; to remove all marks.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;</description></item><item><title>Queues in Java</title><link>https://andyfoster.net/queues-in-java/</link><pubDate>Mon, 23 Jan 2023 15:00:50 +1200</pubDate><guid>https://andyfoster.net/queues-in-java/</guid><description>&lt;p&gt;A queue data structure works in a similar way to a real-life queue at a supermarket or bank. Items/people get added to the back of the queue and removed from the front.&#10;They call this system &amp;ldquo;First In, First Out&amp;rdquo; (FIFO) to compare it to a stack (think stack of papers) where the last thing that gets put on is the first thing to get taken off and the thing at the bottom of the stack stays on until the very end.&lt;/p&gt;</description></item></channel></rss>