0

My goal is to create a flexible application-> to extend the functionality of my web-application I only to add a position to the database and upload the missing class to the server.

I created dynamic menu in Java-GWT. I use MenuBar() and loops, all positions, wchich were taken from db (array, string). Of course, 'end-option' in menu must do something, generally after clicking application will open i.e. FlowPanel with buttons, labels, textareas.

My idea was: using java reflection to add Command for all positions in menu. Every Command take name of option (string), name is the same, like name of class -> next, after clicking I will automatically create object. Unfortunatelly Java Reflection don't work with GWT, so this way is not possible.

My question is:

How to create object, when I have class name in string? Or if my idea is wrong, maybye is other way to create flexible menu/program?

Lukas
  • 43
  • 1
  • 6
  • One option is to send the string to server (via RPC), create object on a server side and return it back via the same RPC call. Please note that the return type will be `Object` and GWT compiler will give You warning about performance regarding serialization. – zolv May 09 '19 at 18:14
  • In case the class - represented by the String - is know at compile time, you can try to create something like this mentioned here: https://stackoverflow.com/questions/3034881/how-to-create-new-instance-from-class-name-in-gwt. Keep in mind, reflection is not available in GWT, cause JavaScript has no reflection. – El Hoss May 09 '19 at 21:01
  • Maybe you can get inspired by https://martinfowler.com/articles/refactoring-adaptive-model.html – Ignacio Baca May 09 '19 at 21:34
  • Thank you for all suggestions. I still looking for solutions for my problem. I have done first small step: I use 'Deffered Binding' in Command (in menubar, but still in static version) - in FlowPanel I use dynamicaly any object prepared in this method. – Lukas May 16 '19 at 19:15

1 Answers1

0

I thing, I found a small solution for this problem, but with another concept - only one class (and one interface); in this class I have one main method, which choose correct 'method to open'; in this example I check by int:

/-------------------------------------------/ Example loop in main part of program: /-------------------------------------------/ (...)

MenuBar menu = new MenuBar(true);

    for (int k = 0; k < 5; k++) {
            int ii=k;
            menu.addItem(tekst + k, new Command() {

                @Override
                public void execute() {
                    ClassMetodInterface metoda = (ClassMetodInterface) GWT.create(Method2.class);
                    vPanel.clear(); //clearing before I open a new widget.

/*I sent int (easier to tests), but I can sent string[i] too*/
/* logging - instance of main class to communicate with 'subclasses', in my project necessery*/

                    vPanel.add(metoda.defaultMethod(ii, logging));  
                }

            });
        }
(...)
/*-------------------------------------------*/
ClassMetodInterface, only for implementation class Method2 :
/*-------------------------------------------*/
    public interface ClassMetodInterface {
    Widget defaultMethod(int g, Logging logging);
}

/*-------------------------------------------*/
class Method2 with swich:
/*-------------------------------------------*/


public class Method2 implements ClassMetodInterface {

    public Widget zapisUsera(int g, Logging logging) {

        Logging logging;
        HorizontalPanel lPanel = new HorizontalPanel();

        switch(g) {
        case 1: {
            Window.alert("switch for test no:"+g);
            MenuWindow1(logging);

            break;

        }
        case 2:{
            Window.alert("switch for test no:"+g);
            break;
        }
        default:
            Window.alert("switch default - loop >2 && <1");
            break;
        }
        return lPanel;  //all methods will be void - they will be add widgets and Panels to lPanel

    }

    public Widget MenuWindow1(Logging logging) {
        this.logging = logging;

        lPanel.setBorderWidth(2);
        this.lPanel.setPixelSize(100, 50); 
        Button b1 = new Button("test button, not used");    
        lPanel.add(b1);

        Label lbl = new Label("label no "+logging.i);       

        lPanel.add(lbl);
        Button addGlobal = new Button("+");
        Button removeGlobal = new Button("-");
        lPanel.add(addGlobal);
        addGlobal.addClickHandler(new addGlobal());
        removeGlobal.addClickHandler(new removeGlobal());
        lPanel.add(removeGlobal);


        return lPanel;

    }

//for tests communication with class, where I have menu and global variable
    public class addGlobal implements ClickHandler {

        @Override
        public void onClick(ClickEvent event) {
            logging.i++;
        }

    }

    public class removeGlobal implements ClickHandler {

        @Override
        public void onClick(ClickEvent event) {
            logging.i--;
        }

    }
}

It is not finished, but you can show main idea. If I need to add new options to menu, I will update db and replace one class for version with more methods.

Lukas
  • 43
  • 1
  • 6