diff --git a/src/snap/games/DevConsole.java b/src/snap/games/DevConsole.java
index 32e77a4d..3cf117e3 100644
--- a/src/snap/games/DevConsole.java
+++ b/src/snap/games/DevConsole.java
@@ -6,7 +6,7 @@
/**
* A class to provide developer controls to a GameController.
*/
-public class DevConsole extends ViewController {
+public class DevConsole extends DefaultViewController {
// The GameController
private GameController _gameController;
diff --git a/src/snap/games/GameController.java b/src/snap/games/GameController.java
index 58180a02..717c22d0 100644
--- a/src/snap/games/GameController.java
+++ b/src/snap/games/GameController.java
@@ -7,7 +7,7 @@
/**
* The controller class for a GameView.
*/
-public class GameController extends ViewController {
+public class GameController extends DefaultViewController {
// The frame rate
private double _frameRate = 30;
diff --git a/src/snap/styler/FontPicker.java b/src/snap/styler/FontPicker.java
index 1f3c150c..74c55966 100644
--- a/src/snap/styler/FontPicker.java
+++ b/src/snap/styler/FontPicker.java
@@ -8,7 +8,7 @@
/**
* A panel to help users pick a font by preview.
*/
-public class FontPicker extends ViewController {
+public class FontPicker extends DefaultViewController {
// The DialogBox when running
private DialogBox _dbox;
diff --git a/src/snap/styler/StylerOwner.java b/src/snap/styler/StylerOwner.java
index bc55ae7f..0ea24fb2 100644
--- a/src/snap/styler/StylerOwner.java
+++ b/src/snap/styler/StylerOwner.java
@@ -1,10 +1,11 @@
package snap.styler;
+import snap.view.DefaultViewController;
import snap.view.ViewController;
/**
* A simple subclass of view controller to work with a Styler.
*/
-public class StylerOwner extends ViewController {
+public class StylerOwner extends DefaultViewController {
// The Styler
private Styler _styler;
diff --git a/src/snap/util/ActivityMonitorPanel.java b/src/snap/util/ActivityMonitorPanel.java
index 938bda4d..1d93a7a5 100644
--- a/src/snap/util/ActivityMonitorPanel.java
+++ b/src/snap/util/ActivityMonitorPanel.java
@@ -88,7 +88,7 @@ protected void handleMonitorPropChange(PropChange propChange)
/**
* This view controller class shows UI for ActivityMonitorPanel.
*/
- private class ActivityMonitorPanelViewOwner extends ViewController {
+ private class ActivityMonitorPanelViewOwner extends DefaultViewController {
// The dialog box
private DialogBox _dialogBox;
diff --git a/src/snap/view/DefaultViewController.java b/src/snap/view/DefaultViewController.java
new file mode 100644
index 00000000..6a288773
--- /dev/null
+++ b/src/snap/view/DefaultViewController.java
@@ -0,0 +1,63 @@
+package snap.view;
+
+/**
+ * An implementation of ViewController that has all abstract methods implemented with a standard default. To use this
+ * class properly, the class methods must be overridden methods to use this class.
+ */
+public class DefaultViewController extends SimpleViewController {
+
+ /**
+ * Constructor.
+ */
+ public DefaultViewController() {super();}
+
+ /**
+ * Constructor with given View for UI.
+ */
+ public DefaultViewController(View aView) {super(aView);}
+
+ /**
+ * Initializes the UI panel. This method provides the ability to alter any settings or components of the View that
+ * were not set by {@link #createUI()}.
+ *
+ * This method is called automatically by SnapKit after the view has been initialized, and does not need to be
+ * called inside of an implementation.
+ *
+ * Implementation note: It is not always necessary to implement this method, especially if the {@code createUI()}
+ * method was written by hand. It provides a way to add more initialization logic when the class has been loaded
+ * from a .snp file. By default, this method has no implementation.
+ */
+ @Override
+ protected void initUI() {
+
+ }
+
+ /**
+ * Called automatically by SnapKit after a user reacts with a UI component, this method allows the resetting of
+ * the UI. It will not cause accidental {@code respondUI(ViewEvent)} calls. It allows the user to reset or change
+ * aspects of the UI after an interaction, such as might be required for an animation or image draw.
+ *
+ * This method is overridable with no default implementation.
+ */
+ @Override
+ protected void resetUI() {
+
+ }
+
+ /**
+ * Called automatically by SnapKit when it detects a ViewEvent. This method should be overridden to respond to UI
+ * controls, and provide feedback to user interactions.
+ *
+ * If you are coming from a Swing environment, this class serves the same purposes as the action listeners attached
+ * to each individual component. In this case, all of the events are funnelled into the same method, making it
+ * easier to keep track of interactions. Everything is managed from the same location.
+ *
+ * This method is overridable with no default implementation.
+ *
+ * @param anEvent
+ */
+ @Override
+ protected void respondUI(ViewEvent anEvent) {
+
+ }
+}
diff --git a/src/snap/view/SimpleViewController.java b/src/snap/view/SimpleViewController.java
new file mode 100644
index 00000000..b05f8108
--- /dev/null
+++ b/src/snap/view/SimpleViewController.java
@@ -0,0 +1,32 @@
+package snap.view;
+
+/**
+ * A simple implementation of ViewController that has most functionality already implemented. This implementation will
+ * load the UI from a .snp file named the same as this class, located in the resources dir of the jar package. The UI
+ * can be managed by implementing the {@link #initUI()} method, and referencing the names of components inside of that
+ * loaded View. To add events or feedback to elements of the UI, implement the {@link #respondUI(ViewEvent)} method and
+ * add your logic there.
+ *
+ * All abstract methods of this class can be implemented or left empty depending on your needs.
+ */
+public abstract class SimpleViewController extends ViewController {
+
+ /**
+ * Constructor.
+ */
+ public SimpleViewController() {super();}
+ /**
+ * Constructor with given View for UI.
+ */
+ public SimpleViewController(View aView) {super(aView);}
+
+ /**
+ * Creates the top level view for this controller by loading the UI from a .snp file in the 'resources' directory.
+ * The .snp file loaded must share the same name as this class.
+ *
+ * This method is called automatically by SnapKit, and does not need to be called inside an implementation.
+ */
+ @Override
+ protected View createUI() { return UILoader.loadViewForController(this); }
+
+}
diff --git a/src/snap/view/ViewController.java b/src/snap/view/ViewController.java
index 4cc9babc..44a5e0c7 100644
--- a/src/snap/view/ViewController.java
+++ b/src/snap/view/ViewController.java
@@ -8,9 +8,39 @@
import snap.util.*;
/**
- * A base controller class that manages a UI View (usually loaded from a snp UI file).
+ * A base controller class that manages a UI View.
+ *
+ * A standard ViewController works around five simple methods:
+ *
+ * - {@link #createUI()}
+ * - {@link #initUI()}
+ * - {@link #resetUI()}
+ * - {@link #respondUI(ViewEvent)}
+ *
+ *
+ * createUI()
+ * Called by SnapKit when the View is initialized, this method is responsible for the creation of the view, and all of
+ * its components. The view can be created by hand, or loaded from a .snp file through the use of
+ * {@link UILoader#loadViewForController(ViewController)}.
+ *
+ * initUI()
+ * Similar to {@code createUI()}, this method is also called during initialization, after {@code createUI()} has been
+ * run. This method is responsible for any additional initialization that needs to take place after the view has been
+ * created, such as setting settings.
+ *
+ * resetUI()
+ * resetUI() is called automatically by SnapKit whenever the user reacts with any UI component, but will not cause
+ * accidental {@code respondUI(ViewEvent)} calls. It allows the user to reset or change aspects of the UI after an
+ * interaction, such as might be required for an animation or image draw.
+ *
+ * respondUI(ViewEvent)
+ * Called automatically by SnapKit whenever a ViewEvent/user event has been detected. Use this method to provide
+ * interactions and feedback to buttons and other user tools. In Swing, the listeners are attached to individual
+ * components, but in SnapKit all of the controls are provided in a single place, allowing pieces to be swapped in
+ * and out as necessary.
+ *
*/
-public class ViewController extends PropObject {
+public abstract class ViewController extends PropObject {
// The UI View
private View _ui;
@@ -124,14 +154,30 @@ public synchronized View getUI()
public T getUI(Class aClass) { return aClass.cast(getUI()); }
/**
- * Creates the top level view for this controller.
+ * Creates the top level view for this controller.
+ *
+ * This method is called automatically by SnapKit at initialization, and does not need to be called inside an
+ * implementation.
+ *
+ * Implementation Note: This is where all components and members of the view should be composed and initialized.
+ * This can be done by hand, or through use of the {@link UILoader#loadViewForController(ViewController)} loader
+ * method.
+ * @see UILoader#loadViewForController(ViewController)
*/
- protected View createUI() { return UILoader.loadViewForController(this); }
+ abstract protected View createUI();
/**
- * Initializes the UI panel.
+ * Initializes the UI panel. This method provides the ability to alter any settings or components of the View that
+ * were not set by {@link #createUI()}.
+ *
+ * This method is called automatically by SnapKit after the view has been initialized, and does not need to be
+ * called inside of an implementation.
+ *
+ * Implementation note: It is not always necessary to implement this method, especially if the {@code createUI()}
+ * method was written by hand. It provides a way to add more initialization logic when the class has been loaded
+ * from a .snp file.
*/
- protected void initUI() { }
+ abstract protected void initUI();
/**
* Returns the first focus UI view for when window/dialog is made visible.
@@ -468,14 +514,23 @@ public ToggleGroup getToggleGroup(String aName)
}
/**
- * Reset UI controls.
+ * Called automatically by SnapKit after a user reacts with a UI component, this method allows the resetting of
+ * the UI. It will not cause accidental {@code respondUI(ViewEvent)} calls. It allows the user to reset or change
+ * aspects of the UI after an interaction, such as might be required for an animation or image draw.
+ *
+ * This method is overridable with no default implementation.
*/
- protected void resetUI() { }
+ abstract protected void resetUI();
/**
- * Respond to UI controls.
+ * Called automatically by SnapKit when it detects a ViewEvent. This method should be overridden to respond to UI
+ * controls, and provide feedback to user interactions.
+ *
+ * If you are coming from a Swing environment, this class serves the same purposes as the action listeners attached
+ * to each individual component. In this case, all of the events are funnelled into the same method, making it
+ * easier to keep track of interactions. Everything is managed from the same location.
*/
- protected void respondUI(ViewEvent anEvent) { }
+ abstract protected void respondUI(ViewEvent anEvent);
/**
* Resets UI later.
diff --git a/src/snap/view/ViewOwner.java b/src/snap/view/ViewOwner.java
index 01a3a34c..dabfa014 100644
--- a/src/snap/view/ViewOwner.java
+++ b/src/snap/view/ViewOwner.java
@@ -2,7 +2,12 @@
/**
* Temporary support for legacy ViewOwner.
+ * @deprecated see {@link ViewController} for the new naming, or {@link DefaultViewController} for the new
+ * implementation.
+ * @see ViewController
+ * @see DefaultViewController
*/
-public class ViewOwner extends ViewController {
+@Deprecated(since="2026.03")
+public class ViewOwner extends DefaultViewController {
}
diff --git a/src/snap/view/ViewUpdater.java b/src/snap/view/ViewUpdater.java
index fe7f16b2..f6a34d86 100644
--- a/src/snap/view/ViewUpdater.java
+++ b/src/snap/view/ViewUpdater.java
@@ -411,7 +411,7 @@ public static void setShowFrameRate(boolean aValue)
_frameRateLabel.setMargin(10, 10, 10, 20);
_frameRateLabel.setPrefSize(100, 32);
_frameRateLabel.setFont(new Font("Arial", 24));
- ViewController frameRateOwner = new ViewController(_frameRateLabel);
+ ViewController frameRateOwner = new DefaultViewController(_frameRateLabel);
frameRateOwner.getWindow().setType(WindowView.Type.UTILITY);
frameRateOwner.getWindow().setAlwaysOnTop(true);
frameRateOwner.setWindowVisible(true);
diff --git a/src/snap/viewx/ColorPanel.java b/src/snap/viewx/ColorPanel.java
index a807101c..54095335 100644
--- a/src/snap/viewx/ColorPanel.java
+++ b/src/snap/viewx/ColorPanel.java
@@ -12,7 +12,7 @@
/**
* This class provides UI for selecting a color.
*/
-public class ColorPanel extends ViewController {
+public class ColorPanel extends DefaultViewController {
// The currently selected color
private Color _color = Color.BLACK;
diff --git a/src/snap/viewx/DefaultConsole.java b/src/snap/viewx/DefaultConsole.java
index dff79f0a..135744bb 100644
--- a/src/snap/viewx/DefaultConsole.java
+++ b/src/snap/viewx/DefaultConsole.java
@@ -9,7 +9,7 @@
/**
* This class is a real implementation of Console.
*/
-public class DefaultConsole extends ViewController implements Console {
+public class DefaultConsole extends DefaultViewController implements Console {
// The Console view
private ColView _consoleView;
diff --git a/src/snap/viewx/DevPane.java b/src/snap/viewx/DevPane.java
index e512304e..faa7bcd5 100644
--- a/src/snap/viewx/DevPane.java
+++ b/src/snap/viewx/DevPane.java
@@ -12,7 +12,7 @@
/**
* A view to allow inspection of View hierarchy.
*/
-public class DevPane extends ViewController {
+public class DevPane extends DefaultViewController {
// The RootView
private RootView _rootView;
diff --git a/src/snap/viewx/DevPaneConsole.java b/src/snap/viewx/DevPaneConsole.java
index 04a9ed4f..0ab11879 100644
--- a/src/snap/viewx/DevPaneConsole.java
+++ b/src/snap/viewx/DevPaneConsole.java
@@ -6,16 +6,14 @@
import snap.text.TextStyle;
import snap.util.Convert;
import snap.util.KeyChain;
-import snap.view.BoxView;
-import snap.view.ScrollView;
-import snap.view.View;
-import snap.view.ViewController;
+import snap.view.*;
+
import java.io.PrintStream;
/**
* A DevPane to show the console.
*/
-public class DevPaneConsole extends ViewController {
+public class DevPaneConsole extends DefaultViewController {
// The ConsoleView
private static ConsoleTextArea _consoleTextArea;
diff --git a/src/snap/viewx/DevPaneExceptions.java b/src/snap/viewx/DevPaneExceptions.java
index 2a2eaddb..db676bbc 100644
--- a/src/snap/viewx/DevPaneExceptions.java
+++ b/src/snap/viewx/DevPaneExceptions.java
@@ -7,7 +7,7 @@
/**
* A DevPane to show the console.
*/
-public class DevPaneExceptions extends ViewController {
+public class DevPaneExceptions extends DefaultViewController {
// The selected index
private int _selIndex = -1;
diff --git a/src/snap/viewx/DevPaneFiles.java b/src/snap/viewx/DevPaneFiles.java
index f1f5ca8a..dd1f0d7e 100644
--- a/src/snap/viewx/DevPaneFiles.java
+++ b/src/snap/viewx/DevPaneFiles.java
@@ -10,7 +10,7 @@
/**
* A DevPane tab for inspecting Graphics.
*/
-public class DevPaneFiles extends ViewController {
+public class DevPaneFiles extends DefaultViewController {
// The root URL string
private String _rootUrlString;
diff --git a/src/snap/viewx/DevPaneGraphics.java b/src/snap/viewx/DevPaneGraphics.java
index 583ae9cc..91e164d7 100644
--- a/src/snap/viewx/DevPaneGraphics.java
+++ b/src/snap/viewx/DevPaneGraphics.java
@@ -6,7 +6,7 @@
/**
* A DevPane tab for inspecting Graphics.
*/
-public class DevPaneGraphics extends ViewController {
+public class DevPaneGraphics extends DefaultViewController {
// The DevPane
private DevPane _devPane;
diff --git a/src/snap/viewx/DevPaneViewOwners.java b/src/snap/viewx/DevPaneViewOwners.java
index b60d168c..f4ac73a0 100644
--- a/src/snap/viewx/DevPaneViewOwners.java
+++ b/src/snap/viewx/DevPaneViewOwners.java
@@ -17,7 +17,7 @@
/**
* A DevPane tab for inspecting the view tree.
*/
-public class DevPaneViewOwners extends ViewController {
+public class DevPaneViewOwners extends DefaultViewController {
// The DevPane
private DevPane _devPane;
diff --git a/src/snap/viewx/DevPaneViews.java b/src/snap/viewx/DevPaneViews.java
index d9889cc7..88a638ce 100644
--- a/src/snap/viewx/DevPaneViews.java
+++ b/src/snap/viewx/DevPaneViews.java
@@ -16,7 +16,7 @@
/**
* A DevPane tab for inspecting the view tree.
*/
-public class DevPaneViews extends ViewController {
+public class DevPaneViews extends DefaultViewController {
// The DevPane
private DevPane _devPane;
diff --git a/src/snap/viewx/ExceptionReporter.java b/src/snap/viewx/ExceptionReporter.java
index 7903973d..0a8c4933 100644
--- a/src/snap/viewx/ExceptionReporter.java
+++ b/src/snap/viewx/ExceptionReporter.java
@@ -16,7 +16,7 @@
* er.setInfo("MyApp Version X, Build Date: " + MyUtils.getBuildDate());
* Thread.setDefaultUncaughtExceptionHandler(er);
*/
-public class ExceptionReporter extends ViewController implements Thread.UncaughtExceptionHandler {
+public class ExceptionReporter extends DefaultViewController implements Thread.UncaughtExceptionHandler {
// Backtrace text
private String _backtraceText;
diff --git a/src/snap/viewx/FilePanel.java b/src/snap/viewx/FilePanel.java
index 7c4c28f8..1f01959b 100644
--- a/src/snap/viewx/FilePanel.java
+++ b/src/snap/viewx/FilePanel.java
@@ -17,7 +17,7 @@
/**
* A class to select a file to open or save.
*/
-public class FilePanel extends ViewController {
+public class FilePanel extends DefaultViewController {
// Whether choosing file for save
private boolean _saving;
diff --git a/src/snap/viewx/FormBuilder.java b/src/snap/viewx/FormBuilder.java
index 5d74feb6..e36544dd 100644
--- a/src/snap/viewx/FormBuilder.java
+++ b/src/snap/viewx/FormBuilder.java
@@ -11,7 +11,7 @@
/**
* A class to build a form.
*/
-public class FormBuilder extends ViewController {
+public class FormBuilder extends DefaultViewController {
// The root pane
protected ColView _formView;
diff --git a/src/snap/viewx/ScanPane.java b/src/snap/viewx/ScanPane.java
index 1d29ed35..0f6b47a3 100644
--- a/src/snap/viewx/ScanPane.java
+++ b/src/snap/viewx/ScanPane.java
@@ -1,5 +1,6 @@
package snap.viewx;
import snap.gfx.Font;
+import snap.view.DefaultViewController;
import snap.view.ScrollView;
import snap.view.View;
import snap.view.ViewController;
@@ -13,7 +14,7 @@
* A class to display and process System IN/OUT/ERR.
* This can be useful to quickly add UI for Java command line programs.
*/
-public class ScanPane extends ViewController {
+public class ScanPane extends DefaultViewController {
// The ScanView
private ScanView _scanView;
diff --git a/src/snap/viewx/TextPane.java b/src/snap/viewx/TextPane.java
index 0a84ac12..e5e174b8 100644
--- a/src/snap/viewx/TextPane.java
+++ b/src/snap/viewx/TextPane.java
@@ -24,7 +24,7 @@
/**
* A panel for editing text files.
*/
-public class TextPane extends ViewController {
+public class TextPane extends DefaultViewController {
// The text file being edited
private WebFile _textFile;
diff --git a/src/snap/viewx/WebSitePane.java b/src/snap/viewx/WebSitePane.java
index cc2a3b45..df35a07f 100644
--- a/src/snap/viewx/WebSitePane.java
+++ b/src/snap/viewx/WebSitePane.java
@@ -1,6 +1,7 @@
package snap.viewx;
import snap.util.ArrayUtils;
import snap.util.ListUtils;
+import snap.view.DefaultViewController;
import snap.view.EventListener;
import snap.view.ViewEvent;
import snap.view.ViewController;
@@ -14,7 +15,7 @@
/**
* This class is the base class for WebSite open/save browsers.
*/
-public class WebSitePane extends ViewController {
+public class WebSitePane extends DefaultViewController {
// The site used to reference files
protected WebSite _site;