Open
Description
For the migration of the internal Gradle runner, I'm running into trouble with the Preferences
class.
Problem description
Currently Preferences
is tightly coupled with the PDE through the use of the Base
, Messages
, Toolkit
and Language
classes. These classes do not operate outside of the PDE, thus not allowing reuse of the Preferences
class in other modules within Processing (e.g. Gradle plugins, Processing CLI, Processing pre-processor, etc.)
Proposed solution
Migrate the Preferences
class to a standalone version.
- Completing the migration of Preferences to be standalone from
:app
by moving it to a:app:utils
module. - Move functionality dependent on
:app
into aAppPreferences
class or into other relevant areas of the PDE - Adding callback events/listeners when a preference changes
- Tests that will declare and test the functionality of
Preferences
, a few of the top of my head would be:- Test if the defaults are loaded and saved without creating changes
- Test if
\
work - Test if the preferences file is created if it does not yet exist
- Any other tests to make sure we have backwards compatibility
- A Github Action that will run the Tests on all supported platforms
- Bonus: Removing the dependency on
core
Steps taken so far
- In IntelliJ IDEA create a new module
utils
in theapp
folder with the following settings (see image below) - Add package
processing.utils
to the newly created module - Refactoring the class by right clicking the
Prefrences
class andRefactor -> Move Class...
and moving it to the newly createdprocessing.utils
package

Metadata
Metadata
Assignees
Labels
No labels
Activity
Stefterv commentedon May 16, 2025
@AhmedMagedC is this something you would be interested in working on?
AhmedMagedC commentedon May 16, 2025
@Stefterv Thanks for suggesting me to implement this, and yes i'm interested into working on it
unfortunately though im currently busy with college having practical exams this week, i can start working on it once i finish
AhmedMagedC commentedon May 21, 2025
Hi @Stefterv , I would like to show my approach to make sure I'm moving in the right direction.
I will move
Preferences
class into:app:util
module insideprocessing.utils
package, while keepingAppPreferences
class inside:app
module which will extendPreferences
main functionalities likeload()
,get()
,set()
and then provide functionalities that depend on:app
likesetFont()
,getFont()
but for the
Preferneces
class, getting thepreferences.txt
file is platform-dependent so i thought of creatingprocessing.utils.platform
package to overridegetSettingFolder()
for each platform (which is already implemented inprocessing.app.platform
package i will just copy it)and for things like getting the
default.txt
file or ,setting.txt
(for portable versions), I can use built-in JAR Resources System instead of the deprecatedPlatform.getContentFile()
which will make it independent ofapp.Base
andapp.Platform
classesso what do you think?
Stefterv commentedon May 21, 2025
Hi @AhmedMagedC, Thank you for writing down the approach.
Perfect 👍
Let's use the existing
Platform
for now, I'd rather avoid duplicating code where we can. Then we create a new issue for thePlatform
class similar to this one after creating the newPreferences
is finished.Thank you for catching the dependency on
Platform
early on!AhmedMagedC commentedon May 31, 2025
Hi @Stefterv , so i managed to migrate the preference class to utils module and it properly compiles and runs
i took a different approach than using the Platform class because that made cyclic dependency problem (utils depend on app, app depends on utils)
i wanna make a PR so you and other devs can review the work done and prompts changes if needed
also note that i didnt yet work on the rest of requirements, i will once the migration alone makes sense
Stefterv commentedon Jun 1, 2025
Hi @AhmedMagedC, thanks so much for the update and the work you’ve done so far! Please go ahead and open a draft PR. We can take a look and continue the discussion there.
Stefterv commentedon Jun 20, 2025
Hi @AhmedMagedC Thank you so much for this initial work and thank you for checking in to see if this approach is correct. I learned the following:
By renaming the class to
AppPreferences
we have to update all the references as well which makes the PR hard to check. I would suggest that we instead create a new classPreferences
inutils
and extend the existing class from there. That way we can slowly migrate over functionality whilst keeping the references the same. Also some functionality could be extended more easily by overriding methods in theapp
version of the class.Looking at the
utils.Preferences
I would like the system proxy stuff to be in theapp.Preferences
instead. I would suggest that keeping all side-effects out of the utils classI'm happy for the
Location
classes that you have now to be a single class/file.In any case, this has been super helpful and I hope you are also still excited to implement these changes! Again sorry that I assigned this to you and then did not have the time to review your work sooner.
AhmedMagedC commentedon Jun 20, 2025
Hi @Stefterv , Thanks for the suggestions and I'm still interested in implementing these changes and finishing the todo tasks
for the first point, I have already made the
Preferences
class inutils
which is extended byAppPreferences
, i will just renameAppPreferences
Back to It's original namePreferences
which would resolve these many changes of references.for the second point, I don't fully understand what do you mean by
side-effects
can you please elaborate more?Stefterv commentedon Jun 20, 2025
Sure! Side effects are in this case configuration changes that are not explicitely requested. The
Preferences
class seems like it should only handle saving and loading preferences, but here it also changes the proxy settings while the program is running. I think a utility class should focus on just one thing.AhmedMagedC commentedon Jun 22, 2025
@Stefterv , I made the changes I hope that's what you had in mind
i renamed the
AppPreferences
andAppMessages
back to the original namePreferences
andMessages
respectivelyand i moved extra configurations to
app.preferences
which is unrelated to theutils.preferences
class like