Gwt按钮需要双击才能加载div中的所有数据

时间:2016-11-28 14:02:55

标签: javascript css gwt

在我的应用程序中,我有一个可以管理整个软件的超级用户。 当记录的用户是管理员时,他可以看到一些按钮(管理)。

问题出在这个按钮之一,管理按钮,当他被解雇时,他必须显示一个隐藏的div并在他内部加载几个按钮。 当我单击“管理”按钮时,他只加载div,如果我再次单击它,则加载其余代码(按钮)并获取阻塞。

我认为DOM.getElementById("center_top").getStyle().setDisplay(Display.BLOCK);会阻止其他代码,我需要再次单击才能加载按钮。

以下是该方法的代码:

package com.unibo.questionandanswer.client.view;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.unibo.questionandanswer.client.CategoriesInterface;
import com.unibo.questionandanswer.client.QuestionAndAnswer;
import com.unibo.questionandanswer.client.UsersService;
import com.unibo.questionandanswer.client.UsersServiceAsync;
import com.unibo.questionandanswer.shared.User;
import com.unibo.questionandanswer.shared.UserRights;

/**
 * 
 * @author Dario
 *
 */
public class AdminController {

    UserRights rightsFilter = UserRights.USER;

    private final UsersServiceAsync usersService = GWT
            .create(UsersService.class);

    private QuestionAndAnswer controller;

    public AdminController(CategoriesInterface categorie) {

        if (categorie instanceof QuestionAndAnswer) {
            this.controller = (QuestionAndAnswer) categorie.getController();
        }

        amministraSito();

    }

    @SuppressWarnings("deprecation")
    private void amministraSito() {

        // Bottone per l'admin gestione software
        final Button amministra = new Button("Amministra");
        final Button sitoNormale = new Button("Q&A Sito");

        RootPanel.get("top_header").add(amministra);
        RootPanel.get("top_header").add(sitoNormale);
        DOM.setElementAttribute(amministra.getElement(), "id",
                "amministraButton");
        DOM.setElementAttribute(sitoNormale.getElement(), "id",
                "backSitoButton");

        /**
         * Esce dalla modalità amministra
         */
        sitoNormale.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                controller.setSelectedImpostaCat(false);
                amministra.setEnabled(true);
                sitoNormale.setEnabled(false);
                Window.Location.reload();

            }
        });

        /**
         * Entra in modalità amministra
         */
        amministra.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {

                // RootPanel.get("center").clear();
                // DOM.getElementById("center_top").getStyle().setDisplay(Display.BLOCK);
                Document.get().getElementById("center_top").getStyle()
                        .setDisplay(Display.BLOCK);
                RootPanel.get("center_top").clear();
                // Util per promuovere giudici o rimuoverli
                giudiceUtil();
                // Util per rimuovere una risposta
                removeAnswerUtil();
                // Util per rimuovere una domanda
                removeQuestionUtil();
                // Util per modificare le categorie
                mangeTreeUtil();

                amministra.setEnabled(false);
                sitoNormale.setEnabled(true);

            }
        });

    }

    /**
     * Metodo che permette all'admin di modificare le categorie
     */
    private void mangeTreeUtil() {

        // Bottone per l'admin gestione software
        final Button manageTree = new Button("Imposta categorie");

        RootPanel.get("center_top").add(manageTree);

        manageTree.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {
                RootPanel.get("center").clear();
                controller.setSelectedImpostaCat(true);
                controller.buildAdminTree();
            }
        });
    }

    /**
     * Metodo che permette all'admin di rimuovere una domanda
     */
    private void removeQuestionUtil() {

    }

    /**
     * Metodo che permette all'admin di rimuovere una risposta
     */
    private void removeAnswerUtil() {

    }

    /**
     * Metodo che permette all'admi di selezionare un giudice o rimuoverlo
     */
    private void giudiceUtil() {

        // Bottone per inviare dati login al server-side
        final Button showUsers = new Button("All Users");

        RootPanel.get("center_top").add(showUsers);

        showUsers.addClickHandler(new ClickHandler() {

            @Override
            public void onClick(ClickEvent event) {

                controller.setSelectedImpostaCat(false);
                showAllRegisterdUsers();

            }
        });

    }

    /**
     * Metodo che motra tutti gli utenti registrati
     */
    private void showAllRegisterdUsers() {

        usersService.registeredUsers(new AsyncCallback<List<User>>() {

            @Override
            public void onFailure(Throwable caught) {
                String alert = "Errore in fase di registrazione";
                for (StackTraceElement el : caught.getStackTrace())
                    alert += "\n" + el.toString();

                Window.alert(alert);
            }

            @Override
            public void onSuccess(List<User> result) {

                RootPanel.get("center").clear();

                final Button users = new Button("Users");
                final Button giudici = new Button("Giudici");
                HorizontalPanel buttonFilter = new HorizontalPanel();

                buttonFilter.add(users);
                buttonFilter.add(giudici);

                RootPanel.get("center").add(buttonFilter);

                // Codice HTML che spiega il funzionamento del come fare
                HorizontalPanel hp = new HorizontalPanel();
                HTML html = new HTML(
                        "<p style='margin-left: 20px'>Selezionare il nome utente per cambiare i suoi diritti da USER a GIUDICE e viceversa!</p><hr>");
                hp.add(html); // adds the widget to the panel

                RootPanel.get("center").add(hp);

                users.addClickHandler(new ClickHandler() {

                    @Override
                    public void onClick(ClickEvent event) {

                        rightsFilter = UserRights.USER;
                        showAllRegisterdUsers();
                        controller.setSelectedImpostaCat(false);

                    }
                });

                giudici.addClickHandler(new ClickHandler() {

                    @Override
                    public void onClick(ClickEvent event) {

                        rightsFilter = UserRights.GIUDICE;
                        showAllRegisterdUsers();
                        controller.setSelectedImpostaCat(false);

                    }
                });

                for (User curr : result) {

                    if (curr.get_userRight().equals(rightsFilter)) {

                        // Label per il dialog promozione a giudice
                        final Label textDialogGiud = new Label(
                                "Promuovere l'utente a Giudice?");
                        // Label per il dialog declassa a user
                        final Label textDialogGiudRemove = new Label(
                                "Declassare l'utente a User?");

                        // Bottone per promuovere user
                        final Button promuovi = new Button("Promuovi!");
                        // Bottone per declassare user
                        final Button declassa = new Button("Declassa!");
                        // Bottone per chiudere la dialog
                        final Button closeWindow = new Button("Chiudi");

                        // promuovi.getElement().setId("promuoviUser");
                        closeWindow.getElement().setId("chiudiDialog");

                        HorizontalPanel lineDialogText = new HorizontalPanel();
                        HorizontalPanel controllButtonsDialog = new HorizontalPanel();
                        FlowPanel flowPanelGiudice = new FlowPanel();

                        // Se l'utente selezionato è giudice carico i pulsanti
                        // per declassare
                        if (curr.get_userRight().equals(UserRights.GIUDICE)) {

                            controllButtonsDialog.add(declassa);
                            lineDialogText.add(textDialogGiudRemove);

                        } else if (curr.get_userRight().equals(UserRights.USER)) {
                            // Se l'utente selezionato è user carico i pulsanti
                            // per promuovere
                            controllButtonsDialog.add(promuovi);
                            lineDialogText.add(textDialogGiud);

                        }

                        // lineDialogText.add(textDialogGiud);
                        // controllButtonsDialog.add(promuovi);
                        controllButtonsDialog.add(closeWindow);
                        // Carico gli horizontal panel con i label e button che
                        // mi servono
                        // in base allo user
                        flowPanelGiudice.add(lineDialogText);
                        flowPanelGiudice.add(controllButtonsDialog);

                        final DialogBox dialogSelectGiud = new DialogBox();

                        dialogSelectGiud.setAnimationEnabled(true);

                        dialogSelectGiud.setWidget(flowPanelGiudice);

                        final HorizontalPanel userPanel = new HorizontalPanel();
                        final Label username = new Label(curr.getUsername());

                        // Handler che gestisce la gestione del click sulla
                        // lista
                        // di utenti o giudici
                        username.addClickHandler(new ClickHandler() {

                            @Override
                            public void onClick(ClickEvent event) {

                                dialogSelectGiud.setText("Selezionato: "
                                        + username.getText().toString());
                                dialogSelectGiud.center();
                                dialogSelectGiud.show();

                            }
                        });

                        userPanel.add(username);
                        RootPanel.get("center").add(userPanel);

                        /*
                         * BUTTON PROMUOVI UTENTE
                         */
                        promuovi.addClickHandler(new ClickHandler() {

                            @Override
                            public void onClick(ClickEvent event) {

                                dialogSelectGiud.hide();

                                usersService.findUser(username.getText()
                                        .toString(), new AsyncCallback<User>() {

                                    @Override
                                    public void onFailure(Throwable caught) {

                                        Window.alert("Errore nel trovare lo User!");

                                    }

                                    @Override
                                    public void onSuccess(User result) {

                                        result.set_userRight(UserRights.GIUDICE);

                                        usersService.changeUserRights(result,
                                                new AsyncCallback<Void>() {

                                                    @Override
                                                    public void onFailure(
                                                            Throwable caught) {

                                                        Window.alert("Errore nella promozione utente!");

                                                    }

                                                    @Override
                                                    public void onSuccess(
                                                            Void result) {

                                                        Window.alert("Utente promosso a giudice!  "
                                                                + username
                                                                        .getText()
                                                                        .toString());

                                                        showAllRegisterdUsers();

                                                    }
                                                });

                                    }
                                });

                            }
                        });

                        /*
                         * BUTTON DECLASSA UTENTE
                         */
                        declassa.addClickHandler(new ClickHandler() {

                            @Override
                            public void onClick(ClickEvent event) {

                                dialogSelectGiud.hide();

                                usersService.findUser(username.getText()
                                        .toString(), new AsyncCallback<User>() {

                                    @Override
                                    public void onFailure(Throwable caught) {

                                        Window.alert("Errore nel trovare lo User!");

                                    }

                                    @Override
                                    public void onSuccess(User result) {

                                        result.set_userRight(UserRights.USER);

                                        usersService.changeUserRights(result,
                                                new AsyncCallback<Void>() {

                                                    @Override
                                                    public void onFailure(
                                                            Throwable caught) {

                                                        Window.alert("Errore nel declassare l'utente!");

                                                    }

                                                    @Override
                                                    public void onSuccess(
                                                            Void result) {

                                                        Window.alert("Utente declassato a user!  "
                                                                + username
                                                                        .getText()
                                                                        .toString());

                                                        showAllRegisterdUsers();

                                                    }
                                                });

                                    }
                                });

                            }
                        });

                        /*
                         * BUTTON CHIUDI DIALOG PROMOZIONE
                         */
                        closeWindow.addClickHandler(new ClickHandler() {

                            @Override
                            public void onClick(ClickEvent event) {

                                dialogSelectGiud.hide();

                            }
                        });

                        /*
                         * QUALCHE CSS PER BUTTONS
                         */
                        userPanel.getElement().setAttribute("style",
                                "margin: auto; padding: 10px");
                        users.getElement().setAttribute("style",
                                "margin: 5px 0 5px 5px;");
                        giudici.getElement().setAttribute("style",
                                "margin: 5px 0 5px 5px; ");

                        //CSS per bottoni dentro dialogbox
                        controllButtonsDialog.setWidth("100%");
                        controllButtonsDialog.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);

                        promuovi.getElement().setAttribute("style",
                                "margin: 20px 5px 5px 5px; float: left;");
                        declassa.getElement().setAttribute("style",
                                "margin: 20px 5px 5px 5px; float: left;");
                        closeWindow.getElement().setAttribute("style",
                                "margin: 20px 5px 5px 5px; float: right;");

                    }
                }
            }
        });

    }

}

这里隐藏“center_top”div的css

#center_top{
    position: absolute;
    top: 0;
    width: 100%;
    height: 30px;
    border-bottom:1px solid black;
    display: none; 

}

为什么只有这个按钮我需要双击show div并在里面加载按钮?

DOM.getElementById是否阻止了代码的执行?

浏览器控制台取消了这行代码

  /**
   * Adds a widget to the detach list. This is the list of widgets to be
   * detached when the page unloads.
   * 
   * <p>
   * This method must be called for all widgets that have no parent widgets.
   * These are most commonly {@link RootPanel RootPanels}, but can also be any
   * widget used to wrap an existing element on the page. Failing to do this may
   * cause these widgets to leak memory. This method is called automatically by
   * widgets' wrap methods (e.g.
   * {@link Button#wrap(com.google.gwt.dom.client.Element)}).
   * </p>
   * 
   * <p>
   * This method may <em>not</em> be called on any widget whose element is
   * contained in another widget. This is to ensure that the DOM and Widget
   * hierarchies cannot get into an inconsistent state.
   * </p>
   * 
   * @param widget the widget to be cleaned up when the page closes
   * @see #detachNow(Widget)
   */
  public static void detachOnWindowClose(Widget widget) {
    assert !widgetsToDetach.contains(widget) : "detachOnUnload() called twice "
        + "for the same widget";
    assert !isElementChildOfWidget(widget.getElement()) : "A widget that has "
        + "an existing parent widget may not be added to the detach list";

    widgetsToDetach.add(widget);
  }

1 个答案:

答案 0 :(得分:1)

因此,在将分组添加到分离列表时会出现错误。

首先,您需要知道分离列表是什么。它在detachOnWindowClose方法的注释中进行了解释。我会尝试以更简单的方式解释这一点。

每当您使用页面上显示的窗口小部件时,窗口小部件都会创建一个DOM(Document Object Model)结构并与之相连。例如,窗口小部件具有事件处理程序的代码。 GWT需要保持对该连接的控制,因此当删除DOM时(例如,页面被清除或卸载 - 通常分离),它可以释放先前所述事件处理程序(或其他资源)使用的内存)。否则可能导致内存泄漏。

当小部件没有父窗口小部件时,必须将其添加到分离列表

  • 当您通过RootPanel(RootPanel.get().add(widget);或仅RootPanel.get("element_id");)直接将小部件添加到DOM时
  • 将小部件包装在现有DOM元素(Panel.wrap(element);
  • 周围

其他窗口小部件中包含的窗口小部件由父窗口小部件分离。

如果在向分离列表添加小部件时出错,则可能意味着您满足以下两个条件之一:

  • 小部件已在分离列表中
  • 您尝试使用DOM元素创建一个小部件,该元素是另一个小部件的一部分。

您需要知道,当您调用RootPanel.get("center_top");时,您实际上正在使用与带有center_top id的DOM元素连接的RootPanel小部件。这意味着下次调用RootPanel.get("center_top");时会出现错误,因为它已经在分离列表中。此外,如果使用RootPanel.get(id);元素中包含的元素的id调用center_top,您也会收到错误,因为它已经有RootPanel.get("center_top");的第一次调用创建的父窗口小部件方法

我希望你现在能够了解分离清单是什么,我也希望我不会因为这种简化的解释而被投票;)

现在让我们回到你的问题。我想是其中之一 giudiceUtil();removeAnswerUtil();removeQuestionUtil();mangeTreeUtil();方法符合上述提出错误的条件。

您可以重复使用先前通话创建的RootPanel(不要使用相同的ID两次调用RootPanel.get())或以自下而上的顺序创建它们(这意味着首先你得到一个子元素的RootPanel然后是父元素。)

干杯!