Saltar al contenido principal
← Blog

Java GUI framework: Swing vs JavaFX vs web with webforJ

· 9 min de lectura

cover image

If you want to keep writing Java and you are picking a Java GUI framework today, webforJ is the option that gets you a browser-delivered UI without leaving the language. You build screens from Java classes, run them on the server, and users open a URL. Swing and JavaFX remain the choice when the app must work offline. If offline isn't a requirement, a webforJ app can be installed too, so it sits on the desktop, home screen or app menu like a native app.

The decision is mostly about delivery. Swing and JavaFX put the UI on each user's machine. A web UI written in Java puts it on one server and shows it in a browser. This post compares the three on the questions that change the outcome, then shows what the same button handler looks like in Swing and in webforJ.

Swing, JavaFX and web at a glance​

QuestionSwingJavaFXWeb UI in Java (webforJ)
Where the UI runsOn the user's machineOn the user's machineOn the server, rendered in a browser
How users get itAn installer or a launcherAn installer or a launcherA URL
UpdatingRedeploy to every machineRedeploy to every machineDeploy once
PlatformsDesktop operating systems with a JVMDesktop, with mobile and embedded targetsAny device with a browser
Look and feelJava toolkit componentsJava toolkit componentsHTML, CSS and web components
UI threadEvent dispatch threadFX threadOne server thread per session

The sections below take each row in turn.

Distribution and installation​

Swing ships in the JDK. The java.desktop module defines the AWT and Swing toolkits, so a Swing app needs nothing beyond a Java runtime. JavaFX is distributed separately as OpenJFX, through Maven modules or a standalone SDK.

Either way, you still have to get the program onto each machine. The JDK's jpackage tool builds native installers (exe and msi on Windows, pkg and dmg on macOS, deb and rpm on Linux) and bundles a runtime. Its documentation states that app packages must be built on the target platform, so supporting all three operating systems means running the packaging step on each.

A webforJ app has no installer for end users. It is a Spring Boot JAR or a WAR, and users reach it by URL. If you want an icon on the home screen or desktop, @AppProfile generates a web app manifest so supporting browsers can install the app, and the installable apps post shows the result.

Updates​

With a desktop client, every release is a rollout. You build installers, publish them, and wait for users to take the update. Versions drift, and support has to know which build each person runs.

With a server-rendered UI, a release is a deployment. The next page load serves the new code to everyone, so the version on the server is the version in use. For internal business apps, where the people who need a fix are the same people filing the ticket, this is often the whole argument.

Platforms and mobile​

Swing targets the desktop. OpenJFX describes itself as a platform for desktop, mobile and embedded systems, so JavaFX gives you a path to more form factors, though each target brings its own build and packaging work.

A webforJ app reaches any device that has a modern browser. The same views serve a laptop and a phone. ColumnsLayout is responsive by design, calculating how many columns to show from the width of its container, and the component catalog lists the rest.

Look and feel​

Swing's own documentation says its components are lightweight and, to the maximum degree possible, work the same on all platforms. That consistency is also why a Swing app reads as a Swing app. The module also exports javax.swing.plaf, the pluggable look-and-feel API, for changing it.

A web UI uses the browser's rendering stack. webforJ components are web components, so theming is CSS custom properties and shadow parts. The framework ships light, dark and dark-pure themes and one @AppTheme annotation selects the default. Brand colors, spacing and typography are tokens you override, as the themes documentation describes. Your designer's CSS knowledge applies directly.

Threading model​

Both desktop toolkits have a single UI thread you must respect. Oracle's Swing tutorial says that Swing component methods other than those labeled thread safe must be invoked from the event dispatch thread, and background work reaches the UI through invokeLater. JavaFX has the same shape, with Platform.runLater posting a Runnable to the JavaFX UI thread.

webforJ also enforces one UI thread, per user session. Events are processed sequentially on it, so handlers don't race each other. When a background task needs to update the UI, Environment.runLater() schedules the update back on that thread. It is documented as experimental, and the asynchronous updates guide covers its use. The mental model is the one you already have from Swing, with the extra fact that the UI thread lives on the server.

What the same handler looks like​

Swing:

public class SwingSave {
private final JLabel status = new JLabel();

public JButton build() {
JButton save = new JButton("Save");
save.addActionListener(e -> status.setText("Saved"));
return save;
}
}

webforJ:

@Route("save")
public class WebSave extends Composite<Div> {
private final Paragraph status = new Paragraph();

public WebSave() {
Button save = new Button("Save", ButtonTheme.PRIMARY);
save.onClick(e -> status.setText("Saved"));
getBoundComponent().add(save, status);
}
}

The listener is the same lambda. The component is a Java object that you construct, then add to a container. The difference is that @Route("save") makes this class a page with its own URL.

Which desktop skills carry over​

Most of what you know from Swing transfers.

  • Listener-based events become onClick(...) and the other on methods. See the events guide.
  • Layout managers become FlexLayout, ColumnsLayout and AppLayout.
  • Model objects stay as plain Java beans, and BindingContext plays the role a form-binding layer would. The data binding docs have the details.
  • A table over a collection becomes a Table bound to a Repository.
  • Your services, validation and domain classes stay as they are. Under Spring Boot they are injected into views through the constructor.

What you stop writing is the code that moves data between a client and a server. The Spring Boot without a REST API post explains why that layer drops out when both sides are Java.

Teams moving off Swing​

webforJ fits teams that have a Swing app and need it on the web. You don't have to start with a rewrite. Webswing runs Swing, JavaFX or SWT apps in a browser without modification, and the WebswingConnector component embeds that app inside a webforJ page. New screens are written in webforJ beside it, and old screens retire one at a time. The Webswing modernization roadmap lays out the stages, and the modernization tutorial builds one on a Swing customer app.

The same pattern applies to server-rendered legacy pages. The JSP modernization post shows how a JSP page becomes a component tree.

Which Java GUI framework should you choose?​

Choose Swing or JavaFX when the program must run offline or drive local hardware. Being installed is not a reason on its own, since a webforJ app can be installed from the browser as well. Choose webforJ when users are on different devices, when you want one deployment instead of many installs, or when your app is a business system that people reach from a browser. You keep the language, your build tool, and your Spring services, and you add delivery to every device that has a browser.

To try it, generate a project with startforJ or follow the getting started guide.

Frequently asked questions​

Is Swing still used?​

Yes. Swing is part of the JDK's java.desktop module, and many enterprise desktop apps still run on it. Teams that want those apps in a browser can keep them running through Webswing while they build new screens in webforJ.

Is JavaFX better than Swing?​

JavaFX is distributed as OpenJFX with a stated path to mobile and embedded targets, and Swing ships with the JDK. Neither removes the work of installing and updating a desktop client. A web UI removes that work.

Can I build a web UI in Java without writing JavaScript?​

Yes. In webforJ you build views from Java components, route them with @Route, and style them with CSS. When you need a third-party web component, ElementComposite wraps it as a Java class.

What replaces Swing for new Java applications?​

It depends on delivery. For a desktop program that must work offline, JavaFX is the toolkit built for that. For an app that people open in a browser on any device, a web UI written in Java with webforJ keeps your team in Java.

Building something with webforJ?

Talk to the team about your project, a migration, or whether webforJ fits.

Contact us