Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java AWT/SWT/Swing: How to plan a GUI?

I've already realized some applications with a small graphical user interface. Nothing complex, but I've encountered several problems that components aren't displayed or just not behaving as expected.

Now my question:

How do you plan those user interfaces? What do you do when you need to make changes? How do you debug strange behaviours?!

This applies for nearly every type of gui-design. Sure, with Microsofts Visual Studio you have a big advantage because you nearly get what you see in the designer.

Does a good and open-source (or freeware) designer for AWT exist? Already looked around and didn't find anything really intelligent.

EDIT: Until now, I've also created all of my GUIs by hand. Sure it is cleaner code but sometimes it's very hard to find the layouting bugs. If Visual Studio by MS is able to create approximately clean code, why aren't the others?

I've heard about some Eclipse Visual designer. Is that one already production-ready?

like image 294
Atmocreations Avatar asked Nov 16 '09 12:11

Atmocreations


People also ask

Is Swing good for GUI?

Java Swing is a more prominent GUI component which is part of the Oracles JFC – Java Foundation Classes API. This provides a more sophisticated Graphical interface option to the Java Programs.

Is Java Swing a GUI?

Swing in Java is a lightweight GUI toolkit which has a wide variety of widgets for building optimized window based applications. It is a part of the JFC( Java Foundation Classes). It is build on top of the AWT API and entirely written in java. It is platform independent unlike AWT and has lightweight components.


1 Answers

I'm not a big fan of GUI builders: They typically autogenerate bucket-loads of code that then locks in your whole development team to using one IDE. Also, this code is often unreadable (check the code generated when using Matisse under Netbeans).

My recommendations for GUI design / debugging would be:

  • Add a main method to each panel (or "top-level" component) implementation, allowing other developers to easily determine what a component looks like.
  • Favour the use of Actions over ActionListeners and register these actions with each JComponent's ActionMap. This allows them to be "extracted" and added to other parts of the UI (e.g. JToolBar) whilst still having their state controlled by the "owning" JComponent (i.e. loose coupling).
  • Use assert to ensure that all UI component modifications are occurring on the Event Dispatch thread; e.g. assert SwingUtilities.isEventDispatchThread().
  • To debug strange layout behaviour consider painting a component's background in red!
  • Centralise the capturing and reporting of workflow events and exceptions. For example, I typically implement a TaskManager class that is registered with my UI's status bar. Any background processing (performed within SwingWorkers) is passed a handle to a Task created by the TaskManager. Interracting with the Task (by calling setDescription(String), setThrowable(Throwable), cancel()) causes the status bar to be updated. It also causes the glass pane to be displayed for "global" tasks ... but this is all decoupled / hidden from the individual SwingWorkers.
  • Do not use the Observer / Observable classes, but instead favour ChangeListener, PropertyChangeListener or your own custom listener implementation for propagating events. Observer passes an Object as it's event, forcing client code to check the type using instanceof and to perform downcasts, making code unreadable and making relationships between classes less clear.
  • Favour the use of JTable over JList, even in situations where your table only has one column. JList has some nasty features in its API including the fact that you need to provide a prototype value for it to calculate its size correctly.
  • Never use DefaultTableModel as it typically results in you storing your "model" data in two places: In your actual business objects and also within the 2D array that DefaultTableModel sits on. Instead, simply subclass AbstractTableModel - It's very easy to do this and means your implementation can simply delegate through to the data structure (e.g. List) storing your data.
like image 179
Adamski Avatar answered Oct 09 '22 02:10

Adamski