Gwt 按钮需要双击才能加载 div 中的所有数据
Gwt button need double click for load all data in a div
在我的应用程序中,我有一个可以管理整个软件的超级用户。
当登录的用户是管理员时,他可以看到一些按钮(管理)。
问题出在这个按钮之一,管理按钮,当它被触发时,他必须显示一个隐藏的 div 并在他里面加载几个按钮。
当我单击 "administration" 按钮时,他只加载 div,如果我再次单击它,他会加载其余代码(按钮)并获取 blocket。
我认为 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;");
}
}
}
});
}
}
这里的 css 隐藏了 "center_top" div
#center_top{
position: absolute;
top: 0;
width: 100%;
height: 30px;
border-bottom:1px solid black;
display: none;
}
为什么只有这个按钮我需要双击才能显示 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);
}
所以在将小部件添加到分离列表时出现错误。
首先你需要知道分离列表是什么。 detachOnWindowClose
方法的注释中对此进行了解释。我将尝试以更简单的方式解释这一点。
每当您使用页面上显示的小部件时,小部件都会创建一个 DOM (Document Object Model) 结构并与之连接。例如,小部件具有事件处理程序的代码。 GWT 需要保持对该连接的控制,因此当 DOM 被删除时(例如页面被清除或卸载 - 通常 detached)它可以释放之前使用的内存所述事件处理程序(或其他资源)。否则可能会导致内存泄漏。
当小部件没有父小部件时,必须将它们添加到分离列表中
- 当您通过 RootPanel 直接将小部件添加到 DOM 时(
RootPanel.get().add(widget);
或只是 RootPanel.get("element_id");
)
- 当您围绕现有 DOM 元素包装小部件时 (
Panel.wrap(element);
)
其他小部件中包含的小部件被父小部件分离。
如果您在将小部件添加到分离列表时出错,这可能意味着您满足以下两个条件之一:
- 小部件已经在分离列表中
- 您尝试使用属于另一个小部件的 DOM 元素创建一个小部件。
您需要知道,当您调用 RootPanel.get("center_top");
时,您实际上是在使用与具有 center_top
id 的 DOM 元素连接的 RootPanel 小部件。这意味着下次你调用 RootPanel.get("center_top");
时你会得到一个错误,因为它已经在分离列表中了。此外,如果您使用 center_top
元素中包含的元素的 ID 调用 RootPanel.get(id);
,您也会收到错误,因为它已经有一个由 RootPanel.get("center_top");
的第一次调用创建的父窗口小部件方法。
我希望现在您已经了解分离列表是什么,我也希望我不会因为这种简化的解释而被否决 ;)
现在让我们回到您的问题。我想其中之一
giudiceUtil();
、removeAnswerUtil();
、removeQuestionUtil();
或 mangeTreeUtil();
方法满足引发上述错误的条件。
你可以通过重用之前调用创建的 RootPanel
s(不要使用相同的 id 调用 RootPanel.get()
两次)或按自下而上的顺序创建它们(这意味着首先你得到一个子元素的 RootPanel,然后是父元素)。
干杯!
在我的应用程序中,我有一个可以管理整个软件的超级用户。 当登录的用户是管理员时,他可以看到一些按钮(管理)。
问题出在这个按钮之一,管理按钮,当它被触发时,他必须显示一个隐藏的 div 并在他里面加载几个按钮。 当我单击 "administration" 按钮时,他只加载 div,如果我再次单击它,他会加载其余代码(按钮)并获取 blocket。
我认为 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;");
}
}
}
});
}
}
这里的 css 隐藏了 "center_top" div
#center_top{
position: absolute;
top: 0;
width: 100%;
height: 30px;
border-bottom:1px solid black;
display: none;
}
为什么只有这个按钮我需要双击才能显示 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);
}
所以在将小部件添加到分离列表时出现错误。
首先你需要知道分离列表是什么。 detachOnWindowClose
方法的注释中对此进行了解释。我将尝试以更简单的方式解释这一点。
每当您使用页面上显示的小部件时,小部件都会创建一个 DOM (Document Object Model) 结构并与之连接。例如,小部件具有事件处理程序的代码。 GWT 需要保持对该连接的控制,因此当 DOM 被删除时(例如页面被清除或卸载 - 通常 detached)它可以释放之前使用的内存所述事件处理程序(或其他资源)。否则可能会导致内存泄漏。
当小部件没有父小部件时,必须将它们添加到分离列表中
- 当您通过 RootPanel 直接将小部件添加到 DOM 时(
RootPanel.get().add(widget);
或只是RootPanel.get("element_id");
) - 当您围绕现有 DOM 元素包装小部件时 (
Panel.wrap(element);
)
其他小部件中包含的小部件被父小部件分离。
如果您在将小部件添加到分离列表时出错,这可能意味着您满足以下两个条件之一:
- 小部件已经在分离列表中
- 您尝试使用属于另一个小部件的 DOM 元素创建一个小部件。
您需要知道,当您调用 RootPanel.get("center_top");
时,您实际上是在使用与具有 center_top
id 的 DOM 元素连接的 RootPanel 小部件。这意味着下次你调用 RootPanel.get("center_top");
时你会得到一个错误,因为它已经在分离列表中了。此外,如果您使用 center_top
元素中包含的元素的 ID 调用 RootPanel.get(id);
,您也会收到错误,因为它已经有一个由 RootPanel.get("center_top");
的第一次调用创建的父窗口小部件方法。
我希望现在您已经了解分离列表是什么,我也希望我不会因为这种简化的解释而被否决 ;)
现在让我们回到您的问题。我想其中之一
giudiceUtil();
、removeAnswerUtil();
、removeQuestionUtil();
或 mangeTreeUtil();
方法满足引发上述错误的条件。
你可以通过重用之前调用创建的 RootPanel
s(不要使用相同的 id 调用 RootPanel.get()
两次)或按自下而上的顺序创建它们(这意味着首先你得到一个子元素的 RootPanel,然后是父元素)。
干杯!