I've one Label in my custom FlowPanel which implements HasDoubleClickHandlers.
final Label label = new Label("Click here to write");
label.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
clicked();
}
});
final CustomFlowPanel customFlowPanel=new CustomFlowPanel();
customFlowPanel.addDoubleClickHandler(new DoubleClickHandler() {
#Override
public void onDoubleClick(DoubleClickEvent event) {
if (event.getSource() instanceof FlowPanel) {
doubleClicked();
}
}
});
custoFlowPanel.add(label);
The problem is when i double click to the label doubleClicked() should not execute.
How to prevent executing doubleClicked() when label is double clicked?
Thanks in advance!!!
You could just check the DoubleClickEvent if the label was clicked and if not you call doubleClicked().
customFlowPanel.addDoubleClickHandler(new DoubleClickHandler() {
#Override
public void onDoubleClick(DoubleClickEvent event) {
Element clicked = event.getNativeEvent();
if (!clicked.Equals(label.getElement())
{
doubleClicked();
}
}
});
I haven't tried it yet, but try adding a double click handler on the label and use Event.stopPropagation() on it. This prevents the event from being propagated to the parent.
Related
I am trying to build a simple planner app using JavaFX. My current goal is to be able to:
click on a panel of the calendar (already implemented)
type in a task, hit enter and have it show up as a Label (already implemented)
click on the currently placed labels and remove them from the calendar. (issue)
Step 3 is where I am having most trouble. I am confident that I am setting up my mouse event for the label correctly but when I click on one of the labels it runs the mouse event for the panel. I need a way to override the pane's mouse event so I can use the labels mouse event, but I'm not too sure how to go about that. Any feedback would be great!
this.setOnMouseClicked(e ->
{
TextField field = new TextField();
this.getChildren().add(field);
//sets field as a label
field.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent key) {
KeyCode k = key.getCode();
if ((k.equals(KeyCode.ENTER))) {
Label lab = new Label(field.getText());
getChildren().add(lab);
getChildren().remove(field);
}
}
});
//removes textfield and label
field.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent ke) {
KeyCode kc = ke.getCode();
if ((kc.equals(KeyCode.ESCAPE))) {
getChildren().remove(field);
}
}
});
});
if(lab != null)
{
lab.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent e) {
setStyle("-fx-background-color: #00FF00;");
}
});
}
In my ULC frame, I implemented some F hotkeys (from F1 to F12).
But there can be a little bug, for example if you want to press quickly the F10, maybe you press it with F11 also. I would like to avoid it somehow. Because now it will run both actions for these two keys.
What could be the best solution, if someone press two registered keys, but run only one from them. If this one is the first or the last, it does not matter.
I have tried with synchronized keyword, but it does not help, both command will be executed.
First code example (inner synchronized (parent)):
Button buttonFirst = createButton("F10");
buttonFirst.addActionListener(new IActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
synchronized (parent) {
System.out.println("F10 - pressed");
doSomething(1);
}
}
});
buttonFirst.addActionKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0, true));
Button buttonSecond = createButton("F11");
buttonSecond.addActionListener(new IActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
synchronized (parent) {
System.out.println("F11 - pressed");
doSomething(2);
}
}
});
buttonSecond.addActionKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0, true));
Second code example (outter synchronized method):
Button buttonFirst = createButton("F10");
buttonFirst.addActionListener(new IActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
doSomething("F10",1);
}
});
buttonFirst.addActionKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0, true));
Button buttonSecond = createButton("F11");
buttonSecond.addActionListener(new IActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
doSomething("F11",2);
}
});
buttonSecond.addActionKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0, true));
private synchronized void doSomething(String keyName, int value) {
System.out.println(keyName+" - pressed");
doSomething(value);
}
I have a game that displays an archer and I am trying to set it up so that when my button is pressed, the user is then allowed to click anywhere on the screen and then a new archer would be set to where the click happen. My code currently allows me to click the screen and set a new archer regardless of whether the button was pressed or not. Could someone explain what is wrong becuase I though MouseEvent would occur on the scene once the button was pressed.
myButton.setOnMouseClicked(
new EventHandler<MouseEvent>()
{
public void handle(MouseEvent e)
{
gc.setFill(color);
gc.fillRect(0,0,width,height);
scene.setOnMouseClicked(new EventHandler<MouseEvent>()
{
public void handle(MouseEvent e)
{
archer.setX((int)e.getSceneX());
archer.setY((int)e.getSceneY());
archer.drawCharStand(gc);
}
});
}
});
You could use a ToggleButton, so that you only place the archer when the toggle button is selected:
private ToggleButton myButton = new ToggleButton("Place Archer");
// ...
scene.setOnMouseClicked(e -> {
if (myButton.isSelected()) {
archer.setX((int)e.getSceneX());
archer.setY((int)e.getSceneY());
archer.drawCharStand(gc);
myButton.setSelected(false);
}
});
The last line will unselect the toggle button "automatically" after placing the archer. If you want the user to be able to place multiple archers easily (and have to manually switch off that mode), omit that line.
You will need to change your code slightly. Perhaps try with a variable that tracks if the button was clicked:
boolean archerPlacementMode = false;
....
myButton.setOnMouseClicked(new EventHandler<MouseEvent>(){
public void handle(MouseEvent e)
{
if(!archerPlacementMode) {
archerPlacementMode = true;
gc.setFill(color);
gc.fillRect(0,0,width,height);
archerPlacementMode = true;
return;
}
}
});
scene.setOnMouseClicked(new EventHandler<MouseEvent>() {
public void handle(MouseEvent e)
{
if(archerPlacementMode) {
archer.setX((int)e.getSceneX());
archer.setY((int)e.getSceneY());
archer.drawCharStand(gc);
archerPlacementMode = false;
}
}
});
I have a MenuItem that has a ScheduledCommand attached. When the user clicks on the menu, a new PopupPanel appears that has autoHide enabled. Now when the user clicks on the MenuItem while the popup is open, the panel gets closed, but immediately opens again as the PopupPanel's close event fires as a click event on the menu item. Can somebody tell me how can I prevent the PopupPanel from opening in this case?
My code is something like this:
#UiField
protected MenuItem menuItem;
....
menuItem.setScheduledCommand(new ScheduledCommand() {
#Override
public void execute() {
PopupPanel window = new PopupPanel();
window.init();
window.addCloseHandler(new CloseHandler<PopupPanel>() {
#Override
public void onClose(final CloseEvent<PopupPanel> event) {
// TODO Maybe something here?
}
});
window.show();
}
});
Create a single instance for the popup and use PopupPanel#isShowing method to hide or show the popup.
public class MyMenuClass{
private PopupPanel window;
....
....
menuItem.setScheduledCommand(new ScheduledCommand() {
#Override
public void execute() {
if(window==null){
window = new PopupPanel(true);
window.add(new Label("Hello close me!!!"));
}
if(window.isShowing()){
window.hide();
}else{
window.show();
}
}
}
OK, I managed to do this by checking whether the last hovered element on the Menubar was the menuItem that opens the window. To do this, I had to subclass the default MenuBar class and exposing the getSelectedItem() method (it was protected by default, why?)
#UiField
MyMenuBar myMenuBar;
....
menuItem.setScheduledCommand(new ScheduledCommand() {
#Override
public void execute() {
if (!wasHoveredWhenClosed) {
window.init();
window.addCloseHandler(new CloseHandler<PopupPanel>() {
#Override
public void onClose(final CloseEvent<PopupPanel> event) {
wasHoveredWhenClosed = myMenuBar.getSelectedItem() != menuItem;
}
});
window.show();
} else {
wasHoveredWhenClosed = false;
}
}
});
I have a button that decorates user ClickHandler with my one which controls button state -> makes it disabled on click preventing multiple clicks. When user clicks on it - corresponding DialogBox is opened and button becomes disabled. Here is my button:
public class MyButton extends Button {
private boolean isButtonClicked = false;
private ClickHandler clickHandler;
public MyButton(String html) {
this(html, null);
}
public MyButton(String html, final ClickHandler handler) {
super(html);
addClickHandler(handler);
}
public HandlerRegistration addClickHandler(final ClickHandler handler) {
clickHandler = handler;
ClickHandler ch = new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
if(!isButtonClicked) {
isButtonClicked = true;
setEnabled(false);
clickHandler.onClick(event); //Here is a click handler initiated on fly
}
}
};
return super.addClickHandler(ch);
}
}
And this is how it is used:
public TestClass {
protected OneClickButton button = new OneClickButton("Test Button);
//...
button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
SomeDialogWindow dialog = new SomeDialogWindow(/*args*/);
dialog.center();
}
});
}
When I click on a button it becomes disabled and dialog appears. But when I close the dialog, my button remains disabled. How to set button enable back on dialog close? What event and where should I handle on order to achieve this?
If your SomeDialogWindow extendes DIalogBox..you can do this
dialog.addCloseHandler(new CloseHandler<PopupPanel>() {
public void onClose(com.google.gwt.event.logical.shared.CloseEvent<PopupPanel> event) {
yourbutton.setEnabled(true);
};
});