Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

New feature for SDK: AbstractControl + SerializableClass

Abierto
#520 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
25/100
Tipo de issue
Nueva funcionalidad
Claridad
Necesita aclaración
Estado de actividad
Estancado
Stack tecnológico
java
Área
tooling

Línea de trabajo

Comienza con la discusión del foro enlazada en el issue y el ejemplo Main.java; después revisa TreeEditorComponent.java, TreeBuilder.java, TreeSettings.java y SerializableClass.java. Se considera terminado cuando se haya definido e implementado la biblioteca SDK dedicada, de modo que los usuarios puedan añadir funciones gráficas a AbstractControls y crear sus propios editores desde proyectos de Maven o Gradle.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

feature

I opened this Issue to keep track of forum discussions

https://hub.jmonkeyengine.org/t/new-feature-for-sdk-abstractcontrol-serializableclass/47005

It requires the creation of a dedicated library, for example jme-sdk-devtools, to be published on the MAVEN repository. In this way, the library can be used by users in their Maven or Gradle projects to add graphical functions to AbstractControls and write their own editors with the SDK.

  1. Main.java
package com.test.ui.model;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.lang3.reflect.MethodUtils;

import com.jme3.app.SimpleApplication;
import com.jme3.math.ColorRGBA;
import com.jme3.scene.control.Control;
import com.jme3.system.AppSettings;

import jme.capdevon.ui.annotations.ButtonProperty;
import jme.capdevon.ui.annotations.SerializableClass;

public class Test_SerializableClass extends SimpleApplication {

    /**
     * @param args
     */
    public static void main(String[] args) {
        AppSettings settings = new AppSettings(true);
        settings.setResolution(640, 480);

        Test_SerializableClass app = new Test_SerializableClass();
        app.setShowSettings(false);
        app.setPauseOnLostFocus(false);
        app.setSettings(settings);
        app.start();
    }

    @Override
    public void simpleInitApp() {
        viewPort.setBackgroundColor(new ColorRGBA(0.5f, 0.6f, 0.7f, 1.0f));
        rootNode.addControl(new TreeEditorComponent());
        
        for (int i = 0; i < rootNode.getNumControls(); i++) {
            Control control = rootNode.getControl(i);
            buildUIPanel(control);
        }
    }
    
    private JPanel buildUIPanel(Control control) {

        JPanel container = new JPanel();
        
        System.out.println(control.getClass());
        Field[] fields = FieldUtils.getAllFields(control.getClass());
        for (Field field : fields) {
            System.out.println("\t" + field);
            addUIComponent(control, field, container);
        }
        
        List<Method> methods = MethodUtils.getMethodsListWithAnnotation(control.getClass(), ButtonProperty.class);
        for (Method method : methods) {
            ButtonProperty bp = method.getAnnotation(ButtonProperty.class);
            JButton button = new JButton(bp.name());
            button.setToolTipText(bp.tooltip());
            button.addActionListener(e -> this.enqueue(() -> {
                try {
                    method.invoke(control);
                } catch (ReflectiveOperationException ex) {
                    ex.printStackTrace();
                }
            }));
            
            container.add(new JLabel(""), "align righ");
            container.add(button, "wrap, pushx, growx");
        }
        
        return container;
    }
    
    private void addUIComponent(Object bean, Field field, JPanel panel) {
        
        String propertyName = field.getName();
        Class<?> fieldType = field.getType();
        
        if (fieldType.getAnnotation(SerializableClass.class) != null) {
            System.out.println("\t--SerializableClass: " + fieldType);
            Object value = getValueOf(propertyName, bean);
            Field[] fields = FieldUtils.getAllFields(value.getClass());
            for (Field fd : fields) {
                System.out.println("\t\t--" + fd);
                addUIComponent(value, fd, panel);
            }
        } else {
            JComponent aComponent = ...;
            panel.add(new JLabel(propertyName), "align righ");
            panel.add(aComponent, "wrap, pushx, growx");
        }
    }
    
    private static Object getValueOf(String propertyName, Object bean) {
        try {
            PropertyDescriptor pd = new PropertyDescriptor(propertyName, bean.getClass());
            return pd.getReadMethod().invoke(bean);

        } catch (ReflectiveOperationException | IntrospectionException e) {
            throw new RuntimeException(e);
        }
    }

}
  1. TreeEditorComponent.java
public class TreeEditorComponent extends AbstractControl {
    
    private TreeSettings buildSettings = new TreeSettings();
    
    @ButtonProperty(name="Generate", tooltip="Procedural Vegetation Placement")
    public void generateTrees() {
        TreeBuilder builder = new TreeBuilder();
        builder.buildTrees(buildSettings);
    }

    @Override
    protected void controlUpdate(float tpf) {
    }

    @Override
    protected void controlRender(RenderManager rm, ViewPort vp) {
    }

    public TreeSettings getBuildSettings() {
        return buildSettings;
    }

    public void setBuildSettings(TreeSettings buildSettings) {
        this.buildSettings = buildSettings;
    }

}
  1. TreeBuilder.java
public class TreeBuilder {
    
    public void buildTrees(TreeSettings settings) {
        System.out.println("Generate trees with settings: " + settings);
    }

}
  1. TreeSettings.java
@SerializableClass
public class TreeSettings {

    private float cellSize = 1f;
    private float cellHeight = 1.5f;
    private float minTraversableHeight = 7.5f;
    private float maxTraversableStep = 1f;
    private float maxTraversableSlope = 48.0f;

    // getters & setters

}
  1. SerializableClass.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface SerializableClass {

}

Here is the output:

class com.test.ui.model.TreeEditorComponent
	private com.test.ui.model.TreeSettings com.test.ui.model.TreeEditorComponent.buildSettings
	--SerializableClass: class com.test.ui.model.TreeSettings
		--private float com.test.ui.model.TreeSettings.cellSize
		--private float com.test.ui.model.TreeSettings.cellHeight
		--private float com.test.ui.model.TreeSettings.minTraversableHeight
		--private float com.test.ui.model.TreeSettings.maxTraversableStep
		--private float com.test.ui.model.TreeSettings.maxTraversableSlope
	protected boolean com.jme3.scene.control.AbstractControl.enabled
	protected com.jme3.scene.Spatial com.jme3.scene.control.AbstractControl.spatial
Lenguaje dominante
Java
Estrellas
348
Forks
104
Merge medio
6 d 16 h
PR fusionados (30 d)
2

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de jMonkeyEngine/sdk

Todos los issues de jMonkeyEngine/sdk

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.