From: Svjatoslav Agejenko Date: Sun, 15 Mar 2026 22:38:25 +0000 (+0200) Subject: refactor(launcher): add descriptions to demo buttons X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;h=426d4ab5a26d59b0a1d2d0ea1b2ed8c454cab8f0;p=sixth-3d-demos.git refactor(launcher): add descriptions to demo buttons Redesign launcher panel with two-column layout showing button and description for each demo. Use GroupLayout properly and frame.pack() for automatic sizing. --- diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/ApplicationListPanel.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/ApplicationListPanel.java index 3344454..f34148c 100644 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/ApplicationListPanel.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/ApplicationListPanel.java @@ -2,7 +2,7 @@ * Sixth 3D engine demos. Author: Svjatoslav Agejenko. * This project is released under Creative Commons Zero (CC0) license. * -*/ + */ package eu.svjatoslav.sixth.e3d.examples.launcher; @@ -22,30 +22,91 @@ import java.awt.event.ActionEvent; /** * Panel containing buttons to launch each demo application. - * Displays a vertical list of buttons organized in a sequential group layout. + * Displays a vertical list with button and description for each demo. */ class ApplicationListPanel extends JPanel { private static final long serialVersionUID = 2012721856427052560L; - /** Constructs the panel with all demo launcher buttons. */ + private static final int BUTTON_WIDTH = 160; + private static final int GAP = 12; + + private record DemoEntry(String name, String description, AbstractAction action) {} + + private static final DemoEntry[] DEMOS = { + new DemoEntry("My First Scene", + "Minimal example showing a single red box", + new ShowMyFirstScene()), + new DemoEntry("Volumetric Octree", + "Octree-based rendering with on-demand raytracing", + new ShowOctree()), + new DemoEntry("Mathematical graphs", + "Function graphs rendered in 3D around a sphere", + new ShowMathGraphs()), + new DemoEntry("Point cloud galaxy", + "Spiral galaxy with 10,000 glowing points", + new ShowPointCloud()), + new DemoEntry("Raining numbers", + "Numbers falling through 3D space like rain", + new ShowRain()), + new DemoEntry("Text editors", + "5x5 grid of 3D text editor components", + new ShowTextEditors()), + new DemoEntry("Text editors city", + "3D city of text editor panels as buildings", + new ShowTextEditors2()), + new DemoEntry("Game of Life", + "Conway's Game of Life with 3D visualization", + new ShowGameOfLife()), + new DemoEntry("Random polygons", + "1000 semi-transparent triangles with depth sorting", + new ShowRandomPolygons()), + new DemoEntry("Shaded Shapes", + "Shapes lit by orbiting colored light sources", + new ShowShadedShapes()), + new DemoEntry("Graphics Benchmark", + "Automated performance measuring FPS across modes", + new ShowGraphicsBenchmark()), + }; + ApplicationListPanel() { - final GroupLayout groupLayout = new GroupLayout(this); - GroupLayout.SequentialGroup sequentialGroup = groupLayout.createSequentialGroup(); - sequentialGroup.addComponent(new JLabel("Choose an example to launch:")); - sequentialGroup.addComponent(new JButton(new ShowMyFirstScene())); - sequentialGroup.addComponent(new JButton(new ShowOctree())); - sequentialGroup.addComponent(new JButton(new ShowMathGraphs())); - sequentialGroup.addComponent(new JButton(new ShowPointCloud())); - sequentialGroup.addComponent(new JButton(new ShowRain())); - sequentialGroup.addComponent(new JButton(new ShowTextEditors())); - sequentialGroup.addComponent(new JButton(new ShowTextEditors2())); - sequentialGroup.addComponent(new JButton(new ShowGameOfLife())); - sequentialGroup.addComponent(new JButton(new ShowRandomPolygons())); - sequentialGroup.addComponent(new JButton(new ShowShadedShapes())); - sequentialGroup.addComponent(new JButton(new ShowGraphicsBenchmark())); + final GroupLayout layout = new GroupLayout(this); + setLayout(layout); + + layout.setAutoCreateGaps(true); + layout.setAutoCreateContainerGaps(true); + + final GroupLayout.SequentialGroup verticalGroup = layout.createSequentialGroup(); + final GroupLayout.ParallelGroup horizontalButtonGroup = layout.createParallelGroup(GroupLayout.Alignment.LEADING); + final GroupLayout.ParallelGroup horizontalDescGroup = layout.createParallelGroup(GroupLayout.Alignment.LEADING); + + final JLabel headerLabel = new JLabel("Choose an example to launch:"); + headerLabel.setFont(headerLabel.getFont().deriveFont(java.awt.Font.BOLD)); + verticalGroup.addComponent(headerLabel); + horizontalButtonGroup.addComponent(headerLabel); + horizontalDescGroup.addComponent(headerLabel); + + for (final DemoEntry entry : DEMOS) { + final JButton button = new JButton(entry.action()); + button.setPreferredSize(new java.awt.Dimension(BUTTON_WIDTH, button.getPreferredSize().height)); + + final JLabel descLabel = new JLabel(entry.description()); + descLabel.setFont(descLabel.getFont().deriveFont(java.awt.Font.PLAIN)); + + verticalGroup.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) + .addComponent(button) + .addComponent(descLabel)); + + horizontalButtonGroup.addComponent(button); + horizontalDescGroup.addComponent(descLabel); + } + + layout.setVerticalGroup(verticalGroup); + layout.setHorizontalGroup(layout.createSequentialGroup() + .addGroup(horizontalButtonGroup) + .addGap(GAP) + .addGroup(horizontalDescGroup)); } - /** Action to launch the MyFirstScene (minimal example). */ private static class ShowMyFirstScene extends AbstractAction { ShowMyFirstScene() { putValue(NAME, "My First Scene"); @@ -57,7 +118,6 @@ class ApplicationListPanel extends JPanel { } } - /** Action to launch the TextEditorDemo. */ private static class ShowTextEditors extends AbstractAction { ShowTextEditors() { putValue(NAME, "Text editors"); @@ -69,7 +129,6 @@ class ApplicationListPanel extends JPanel { } } - /** Action to launch the TextEditorDemo2 (city view). */ private static class ShowTextEditors2 extends AbstractAction { ShowTextEditors2() { putValue(NAME, "Text editors city"); @@ -81,8 +140,6 @@ class ApplicationListPanel extends JPanel { } } - - /** Action to launch the RainingNumbersDemo. */ private static class ShowRain extends AbstractAction { ShowRain() { putValue(NAME, "Raining numbers"); @@ -94,7 +151,6 @@ class ApplicationListPanel extends JPanel { } } - /** Action to launch the PointCloudDemo (galaxy simulation). */ private static class ShowPointCloud extends AbstractAction { ShowPointCloud() { putValue(NAME, "Point cloud galaxy"); @@ -106,7 +162,6 @@ class ApplicationListPanel extends JPanel { } } - /** Action to launch the GraphDemo (mathematical graphs). */ private static class ShowMathGraphs extends AbstractAction { ShowMathGraphs() { putValue(NAME, "Mathematical graphs"); @@ -118,7 +173,6 @@ class ApplicationListPanel extends JPanel { } } - /** Action to launch the RandomPolygonsDemo. */ private static class ShowRandomPolygons extends AbstractAction { ShowRandomPolygons() { putValue(NAME, "Random polygons"); @@ -130,7 +184,6 @@ class ApplicationListPanel extends JPanel { } } - /** Action to launch the OctreeDemo (volumetric rendering). */ private static class ShowOctree extends AbstractAction { ShowOctree() { putValue(NAME, "Volumetric Octree"); @@ -142,7 +195,6 @@ class ApplicationListPanel extends JPanel { } } - /** Action to launch the Game of Life 3D demo. */ private static class ShowGameOfLife extends AbstractAction { ShowGameOfLife() { putValue(NAME, "Game of Life"); @@ -154,10 +206,9 @@ class ApplicationListPanel extends JPanel { } } - /** Action to launch the ShadedShapesDemo (lighting demonstration). */ private static class ShowShadedShapes extends AbstractAction { ShowShadedShapes() { - putValue(NAME, "Shaded Shapes with Lights"); + putValue(NAME, "Shaded Shapes"); } @Override @@ -166,7 +217,6 @@ class ApplicationListPanel extends JPanel { } } - /** Action to launch the GraphicsBenchmark. */ private static class ShowGraphicsBenchmark extends AbstractAction { ShowGraphicsBenchmark() { putValue(NAME, "Graphics Benchmark"); @@ -177,5 +227,4 @@ class ApplicationListPanel extends JPanel { GraphicsBenchmark.main(null); } } - -} +} \ No newline at end of file diff --git a/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/Main.java b/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/Main.java index 9f87947..c04d42e 100755 --- a/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/Main.java +++ b/src/main/java/eu/svjatoslav/sixth/e3d/examples/launcher/Main.java @@ -38,7 +38,9 @@ class Main { frame.getContentPane().setLayout(new BorderLayout()); frame.getContentPane().add(new ApplicationListPanel(), CENTER); - frame.setSize(400, 300); + + frame.pack(); + frame.setMinimumSize(frame.getSize()); frame.setLocationRelativeTo(null); // center frame on screen frame.setVisible(true);