I have a problem with ClickHandler in my project using GWT.
In the title of dialog box I want to insert a new button.
I created a new insert method: addToTitle(...).
I added ClickHandler to the button
Problem: click event by button doesn't fire. Why?
Here is my code:
DialogBox dialog = new DialogBox();
Button button = new Button("A new Button");
button.addClickHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
Window.alert("yuhuhuhu");
}
});
dialog.addToTitle(button);
code (extracted from the comments section) :
public class PlentyDialogWindow extends DialogBox {
private FlowPanel captionPanel = new FlowPanel();
public Widget closeWidget = null;
private boolean closeOnEscKey = false;
private FlowPanel titleContentWrapper = new FlowPanel();
public PlentyDialogWindow(boolean isModal) {
super( false, isModal);
this.addStyleName("DialogBox");
this.getElement().setId("DialogBoxId");
this.setAnimationEnabled(true);
this.closeWidget = generateCloseButton();
}
public void setCaption( String txt,Widget w) {
captionPanel.setWidth("100%");
this.addCaption(txt);
this.titleContentWrapper.getElement().getStyle().setDisplay(Display.INLINE_BLOCK);
captionPanel.add(this.titleContentWrapper);
FlowPanel widgetWrapper = new FlowPanel();
widgetWrapper.add(w);
widgetWrapper.addStyleName("PlentyPopupCloseIconWrapper");
captionPanel.add(widgetWrapper);
captionPanel.addStyleName("Caption");
Element td = getCellElement(0,1);
td.setInnerHTML("");
td.appendChild(captionPanel.getElement());
}
/** * * #param w */ public void addToTitle(Widget w) {
this.titleContentWrapper.add(w);
}
}
If your only problem is ClickHandler not being called try using addDOMHandler instead of addClickHandler
yourWidget.addDomHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
}
},ClickEvent.getType());
The solution is a bit tricky.
public class PlentyDialogWindow extends DialogBox {
/*
* Create custom inner class extending `FlowPanel`. You need it only
* to make `onAttach` and `onDetach` methods be visible to wrapping
* class (e.g. your `PlentyDialogWindow` class).
*/
static class MyCaptionPanel extends FlowPanel {
#Override
protected void onAttach() {
super.onAttach();
}
#Override
protected void onDetach() {
super.onDetach();
}
}
/*
* `PlentyDialogWindow`'s field `captionPanel` will be an instance of
* this class.
*/
private MyCaptionPanel captionPanel = new MyCaptionPanel();
/*
* ... leave the rest of your class untouched ...
*/
/*
* Finally, overwrite `PlentyDialogWindow`'s `onAttach` and `onDetach`
* methods to invoke `captionPanel`'s corresponding methods:
*/
#Override
protected void onAttach() {
super.onAttach();
captionPanel.onAttach();
}
#Override
protected void onDetach() {
super.onDetach();
captionPanel.onDetach();
}
}
That's all.
Related
I have created a TreeViewer using JFace, but now I have to add a right click listener to the nodes. When the right click is done it has to show a menu like:
Do something
Do Nothing
Delete
I am trying to do this as follows, but it is throwing a null pointer exception.
MenuManager menuMgr = new MenuManager();
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
#Override
public void menuAboutToShow(IMenuManager menuManager) {
IContributionManager menu = null;
MenuItem[] items = (MenuItem[]) menu.getItems();
for (int i = 0; i < items.length; i++)
items[i].dispose();
MenuItem itemCollectionFolder = new MenuItem((Menu) menu, SWT.NONE);
itemCollectionFolder.setText("Add Something" );
MenuItem itemNewTestCase = new MenuItem((Menu) menu, SWT.NONE);
itemNewTestCase.setText("Do Nothing" );
}
});
Control tree = treeViewer.getControl();
Menu menu = menuMgr.createContextMenu(tree);
tree.setMenu(menu);
Try this, don't forget to call:
createContextMenu(viewer);
/**
* Creates the context menu
*
* #param viewer
*/
protected void createContextMenu(Viewer viewer) {
MenuManager contextMenu = new MenuManager("#ViewerMenu"); //$NON-NLS-1$
contextMenu.setRemoveAllWhenShown(true);
contextMenu.addMenuListener(new IMenuListener() {
#Override
public void menuAboutToShow(IMenuManager mgr) {
fillContextMenu(mgr);
}
});
Menu menu = contextMenu.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
}
/**
* Fill dynamic context menu
*
* #param contextMenu
*/
protected void fillContextMenu(IMenuManager contextMenu) {
contextMenu.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
contextMenu.add(new Action("Do Something") {
#Override
public void run() {
// implement this
}
});
contextMenu.add(new Action("Do Nothing") {
#Override
public void run() {
// don't do anything here
}
});
contextMenu.add(new Action("Delete") {
#Override
public void run() {
// implement this
}
});
}
To get the selected element of the treeviewer, do this:
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
selection.getFirstElement();
selection.toList(); // or if you handle multi selection
I have the following problem:
I am trying to implement a menu with submenus in libgdx, using the table layout. When a submenu is clicked, a listener is fired, which should setVisible(false) the previous menu, and setVisible(true) the new one. But, although I successfully display the new one, the previous one is still here! Could someone help me?
Here is my code:
The Menu.java:
public class Menu extends Table {
private Stage stage;
public void attachToStage(Stage s) {
if (s != null) {
stage = s;
s.addActor(this);
}
}
public Menu() {
this(null);
}
public Menu(final Stage s) {
attachToStage(s);
setFillParent(true);
top();
left();
}
private void addButtonWithListener(String label, ClickListener listener) {
add().width(10);
Label l = new Label(label, SkinManager.get());
add(l).width(100);
row();
if (listener != null)
l.addListener(listener);
}
/**
* #param label
* #return The menu, for chaining
*/
public Menu addButton(String label) {
addButtonWithListener(label, null);
return this;
}
/**
*
* #param label
* #param m
* the menu to add
* #return The main menu, for chaining
*/
public Menu addMenu(String label, final Menu m) {
addButtonWithListener(label, new ClickListener() {
#Override public void clicked(InputEvent e, float x, float y) {
System.out.println(getChildren());
setVisible(false);
m.setVisible(true);
}
});
m.attachToStage(stage);
m.setVisible(false);
return this;
}
}
My Application:
public class TestApplication implements ApplicationListener {
private Stage stage;
#Override public void create() {
stage = new Stage();
Menu m = new Menu(stage).addButton("Move").addButton("Stay");
m.addMenu("Attack", new Menu().addButton("Sword").addButton("Bow"));
Gdx.input.setInputProcessor(stage);
}
#Override public void render() {
stage.draw();
}
// Other empty methods
}
Thanks a lot!
EDIT: Problem was unrelated, see my answer
Ok, found the problem: not related at all to the Table, just forgott to clear the screen in the Application.
I just added
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
in the render function.
I want to create a popup (implemented as a DialogBox or other similar component) which i should be able to reuse in multiple pages or forms. I want the DialogBox to be able to return a value to the "opener".
I am thinking i.e. on a DialogBox that shows a table (obtained via RPC). That DialogBox can be used in several different pages. When the user selects a row, an object is "passed back to the page" (for example, calling a method on it), so it can write it to a form field, or do whatever with it. The called doesn't know anything about the logic inside de DialogBox, only knows how to deal with the returning type.
A good example of what i'm intending to do could be a DatePicker that returns a java.util.Date.
Have you done something similiar?
I appreciate your help.
Thanks!
David
It's really easy. You should first create an interface that will be implemented by all the pages opening you DialogBox :
public interface DialogBoxOpener {
void dialogBoxValidated (Date selectedDate);
void dialogBoxCancelled ();
}
Then, create your DialogBox, and take a DialogBoxOpener as parameter to your showDialogBox method :
public class MyDialogBox extends DialogBox {
private DialogBoxOpener opener = null;
private final Button cancelButton = new Button("Cancel");
private final Button validButton = new Button("Ok");
private final DateBox myDateBox = new DateBox();
public MyDialogBox () {
cancelButton.addClickHandler(new ClickHandler () {
#Override
public void onClick(final ClickEvent event) {
hide();
if (opener!=null)
opener.dialogBoxCancelled();
}
});
validButton.addClickHandler(new ClickHandler () {
#Override
public void onClick(final ClickEvent event) {
hide();
if (opener!=null)
opener.dialogBoxValidated(myDateBox.getValue());
}
});
// TODO : create your DialogBox
}
public void showDialogBox (final DialogBoxOpener opener) {
this.opener = opener;
// Show the DialogBox
center ();
}
}
And now, you can show your DialogBox from your page :
public class MyPage implements DialogBoxOpener {
private MyDialogBox myDialogBox = getMyDialogBox();
private void openDialogBox () {
myDialogBox.showDialogBox(this);
}
public void dialogBoxValidated (Date selectedDate) {
// TODO : Do something with the date
}
public void dialogBoxCancelled () {
// TODO : Do something
}
}
I am working on a game using JME3 and Nifty GUI. I have an outer class that has a Nifty member variable. And the inner class should be able to access that variable regardless of access modifier. In the constructor I assign a new Nifty object to it. However when I access that variable in the inner class I run into problems. I did a little debugging and found out it's because the inner class thinks the Nifty member variable is null and I cant figure out why. Its not null in the outer class. Since this is a JME3 game I tried to have the inner class implement the AppState interface but it still shows the Nifty member variable as null. Here is the code:
public class MenuScreen extends SimpleApplication {
/** Used to configure Nifty GUI. */
private Nifty mNifty;
private NiftyJmeDisplay mNiftyDisplay;
private Element popup;
//*******************
// Overridden medhods
//*******************
/** This method is used to initialize everything needed to display the game screen. */
#Override
public void simpleInitApp() {
guiNode.detachAllChildren();
initNifty();
flyCam.setDragToRotate(true);
}
/**
* The game's main update loop.
*
* #param tpf Time Per Fram, the time it takes each loop to run.
*/
#Override
public void simpleUpdate(float tpf) {
// not used
}
#Override
public void simpleRender(RenderManager rm) {
// not used
}
public static void main(String[] args) {
MenuScreen app = new MenuScreen();
app.start();
}
/**
* Helper method to initialize and configure Nifty GUI.
*/
private void initNifty() {
mNiftyDisplay = new NiftyJmeDisplay(assetManager, inputManager, audioRenderer, guiViewPort);
mNifty = mNiftyDisplay.getNifty();
guiViewPort.addProcessor(mNiftyDisplay);
// If this is being run on a desktop then load the desktop main menu.
if (Strings.OS_NAME.contains("windows") || Strings.OS_NAME.contains("mac") || Strings.OS_NAME.contains("linux")) {
mNifty.fromXml("Interface/XML/DesktopMenuScreenGui.xml", "start", new MenuScreen().new MenuScreenGui());
}
// If its an Android device load the mobile main menu.
else if (Strings.OS_NAME.contains("android")) {
mNifty.fromXml("Interface/XML/MobileMenuScreenGui.xml", "mobile", new MenuScreen().new MenuScreenGui());
}
}
//**************
// Inner Classes
//**************
/**
* © Jason Crosby 2012 <p>
*
* This class handles all the GUI interactions like button clicks.
*
* #author Jason Crosby
*/
public class MenuScreenGui implements ScreenController, EventTopicSubscriber<MenuItemActivatedEvent>,
AppState {
#Override
public void initialize(AppStateManager stateManager, Application app) {
}
#Override
public void cleanup() {
}
#Override
public boolean isEnabled() {
return false;
}
#Override
public boolean isInitialized() {
return false;
}
#Override
public void postRender() {
}
#Override
public void setEnabled(boolean active) {
}
#Override
public void stateAttached(AppStateManager stateManager) {
}
#Override
public void stateDetached(AppStateManager stateManager) {
}
#Override
public void render(RenderManager rm) {
}
#Override
public void update(float tpf) {
}
#Override
public void bind(Nifty nifty, Screen screen) {
// not used
}
#Override
public void onEndScreen() {
// not used
}
#Override
public void onStartScreen() {
// not used
}
#Override
public void onEvent(String string, MenuItemActivatedEvent t) {
}
//**************
// Class methods
//**************
/**
* Called when the play button is clicked.
*/
public void playButton() {
}
/**
* Called when the high scores button is clicked.
*/
public void highScoresButton() {
}
/**
* Called when the settings button is clicked.
*/
public void settingsButton() {
}
public void quitButton() {
showDialog();
}
/**
* Called when the rate button is clicked. Only Available on mobile.
*/
public void rateButton() {
}
/**
* Called when the feedback button is clicked. Only on mobile devices.
*/
public void feedbackButton() {
}
/**
* Called when the help button is clicked.
*/
public void helpButton() {
}
/**
* Called when the dialog needs to be shown.
*/
public void showDialog() {
System.out.println("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW");
popup = new Nifty().createPopup("popup");
System.out.println("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
//Menu myMenu = popup.findNiftyControl("#menu", Menu.class);
//myMenu.setWidth(new SizeValue("100px")); // must be set
//myMenu.addMenuItem("Click me!", new menuItem("menuItemid", "blah blah")); // menuItem is a custom class
//mNifty.subscribe(mNifty.getCurrentScreen(), myMenu.getId(), MenuItemActivatedEvent.class, this);
mNifty.showPopup(mNifty.getCurrentScreen(), popup.getId(), null);
}
public void clsoseDialog() {
}
/**
* Used to return a String to the Nifty xml file.
*
* #param name The name key associated with the String.
* #return The String associated with the key.
*/
public String getString(String name) {
if (name.equals("play")) {
return Strings.PLAY_BUTTON;
}
else if (name.equals("high_score")) {
return Strings.HIGH_SCORES_BUTTON;
}
else if (name.equals("settings")) {
return Strings.SETTINGS_BUTTON;
}
else if (name.equals("quit")) {
return Strings.QUIT_BUTTON;
}
else if (name.equals("rate")) {
return Strings.RATE_BUTTON;
}
else if (name.equals("feedback")) {
return Strings.FEEDBACK_BUTTON;
}
else if (name.equals("rules")) {
return Strings.RULES_BUTTON;
}
return null;
}
}
}
What happens is I click on the quit button which calls the quitButton() method. That works fine. That in turn invokes showDialog() which is where the problem is. In the showDialog() method is this line popup = new Nifty().createPopup("popup"); and it is at that line which mNifty is null when it shouldn't be. Any assistance is appreciated.
The line
popup = new Nifty().createPopup("popup");
does not use mNifty. It creates a new instance of Nifty and then calls creatPopup() on this new instance. Since earlier you initialized mNifty by calling what looks like a factory method
mNifty = mNiftyDisplay.getNifty();
it is quite possible that obtaining a Nifty via new does not return a completely initialized instance. Since you haven't posted the code for Nifty it is unclear what is happening.
I would double-check to make sure that creating a Nifty via new will return a fully initialized instance, and that you really wanted a new instance here.
i am completly stuck ..
my goal is to implement a.. simple "listener" like action
but i dont know how ..
here is my code
// normaly i create an action like this
// this is JUST an example how i do this in swing
//
class la extends JFrame implements ..<someAciton>..{
JButton b = new JButton("");
add(b);
b.setAction( new Action(){
void click(){
// bla
}
});
}
my problem is, i want to create this funnctionality in android in general in java
currently i have 3 classes and 1 interface
// the interface, it holds my action, wich should be performed
//
//
public interface GameActionInterface extends EventListener {
public void onTouched( MotionEvent event );
}
// this is the class whichs runs the action
//
//
public class GameActionListener {
ArrayList<GameLayoutBase>touchedListener = new ArrayList();
public void addTouchListener(GameLayoutBase obj){
touchedListener.add(obj);
}
public void onTouched( MotionEvent event){
for( GameLayoutBase elem : touchedListener ){
elem.onTouched(event);
}
}
}
// this class should to the action later
//
//
public class GameLayoutElement extends GameLayoutBase {
public GameLayoutElement(String ID) {
super(ID);
}
}
// my main class
//
//
gameEventListener = new GameActionListener();
// creating the obj
layout_Element_Player[0] = new GameLayoutElement("Builder_countA");
//
// and here is the PROBLEM - i want to overwrite the current function with my "own" code
gameEventListener.addTouchListener(layout_Element_Player[0]);
// adding the element to the listener
//
//
layout_Element_Player[0].onTouched( new GameActionInterface(){
} );
i dont know how to solve thge problem :(
here is the answer .. its quite simple .. my mind went blank ..
// handels the button
public class TestButtonVerwaltung {
ArrayList <TestButton>liste = new ArrayList();
public void add( TestButton object){
liste.add(object);
}
public void doAction( MotionEvent event){
for( TestButton elem : liste ){
elem.on(event);
}
}
}
// new button
public class TestButton {
View.OnTouchListener it;
public void addOnTouched( View.OnTouchListener doit ){
it = doit;
}
public void on(MotionEvent event){
it.onTouch(null, event);
}
}
// in the main
TestButton testBt = new TestButton();
TestButtonVerwaltung tBV = new TestButtonVerwaltung();
tBV.add(testBt);
//the trigger function
#Override
public boolean onTouchEvent(MotionEvent event) {
tBV.doAction(event);
}