How to prevent GWT DialogBox from being dragged out of the screen? - java

I am looking for a simple solution for the issue that my GWT DialogBox can be dragged out of the screen. The host has the CSS rule overflow:hidden because I do not want any scrollbars to appear.
Obviously I need to attach somehow a listener to the dragging and prevent moves that would bring it outside. I can only see onMouseMove, beginDragging, endDragging methods in DialogBox.

"We" have worked around this issue in the following way:
#Override
protected void endDragging(MouseUpEvent event)
{
int genericMargin = 60;
int leftMargin = -(this.getOffsetWidth() - genericMargin);
int lowerMargin = Window.getClientHeight() - genericMargin;
int rightMargin = Window.getClientWidth() - genericMargin;
int upperMargin = 0;
if (this.getAbsoluteLeft() > rightMargin)
{this.setPopupPosition(rightMargin, this.getPopupTop()); }
if (this.getAbsoluteLeft() < leftMargin)
{ this.setPopupPosition(leftMargin, this.getPopupTop()); }
if (this.getAbsoluteTop() > lowerMargin)
{ this.setPopupPosition(this.getPopupLeft(), lowerMargin);}
if (this.getAbsoluteTop() < upperMargin)
{ this.setPopupPosition(this.getPopupLeft(), upperMargin);}
super.endDragging(event);
}
BTW it correctly works as it is! ;)

I would suggest trying gwtquery-dnd. I have been using the drag and drop plugin and it works great. It has an option to setContianment(Element elem) which is what you are looking for. Some other features is that it has snap so you can snap to other widgets if you wish to dock your dialog box somewhere. It also has the ability to specify a handle similar to the DialogBox header for dragging.
http://code.google.com/p/gwtquery-plugins/wiki/DragAndDropPluginForGWTDeveloppers

You can investigate com.google.gwt.user.client.ui.DialogBox source code and override all methods for your need. There are a couple of methods responsible for dragging there.
Not sure you can solve this problem in other ways. Otherwise you need to develop custom draggable popup panel which I am sure not a good solution.

Related

JavaFX Button onAction property does not fire when Button pressed on touchscreen

I'm learning JavaFX and working on a JavaFX application that will turn my laptop's touchscreen into a mini-piano. My prototype has a bunch of Buttons in place of piano keys, with each button mapped to a different Midi note. Clicking on a button with the mouse successfully triggers the button's onAction property and plays the associated note. Poking the button with my finger doesn't. The program clearly knows where my finger is because when I poke a button with my finger the button changes color, just as it does when I move the mouse pointer into it. I know that the problem is with JavaFX rather than with Java more generally or with my touchscreen because I wrote an essentially identical prototype in Swing where poking the screen succesfully plays a note. (I would gladly have stuck to Swing, too, if only Swing had any kind of multi-touch support. I want to play chords.) Is there something about JavaFX that I'm missing, such as a touchscreen event handler, or is something deeply wrong here?
For the record, I'm using OpenJDK 11.0.7 and OpenJFX 11.0.2 with a Xubuntu laptop. Here's the relevant bits of code.
#Override
public void start(Stage stage) {
stage.setTitle("Midi Test");
buttons = new Button[NOTE_VALUE.length];
for (int i = 0; i < NOTE_VALUE.length; i++) {
buttons[i] = new Button(NOTE_NAME[i]);
buttons[i].setPrefSize(KEY_WIDTH,KEY_HEIGHT);
buttons[i].setOnAction(this);
}
// Layout omitted for brevity
stage.show();
}
public void handle(ActionEvent event) {
// Identifies which button was pressed and plays the corresponding note
int index = -1;
for (int i = 0; i < buttons.length; i++) {
if (event.getSource().equals(buttons[i])) {
index = i;
break;
}
}
if (index != -1) {
channels[0].allNotesOff();
channels[0].noteOn(NOTE_VALUE[index],93);
}
}
After adopting #James_D's diagnostic suggestions (thanks, James) and doing some additional research, it looks like the problem is due to a known (but obscure) bug deep in the guts of OpenJFX 11. See the discussion here for details. There appear to be some workarounds, but the most straightforward solution would seem to be to try a more recent version of OpenJFX.

Validate CTabFolder before switching tabs

In a CTabFolder, I'd like to check the content for unsaved data before the user can switch from one tab to another. SWT does not provide a PreSelection event, as stated here.
I found a workaround, suggesting to switch back to the old tab when a selection is triggered, validate the data and then perform the desired switch again, if data is valid.
I do understand the general idea of this workaround, however, it is not working for me. oldPageIndex and newPageIndex do always have the same value, though I did not click on the same tab.
this.tabContainer.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent event) {
int oldPageIndex = tabContainer.getSelectionIndex();
int newPageIndex = tabContainer.indexOf((CTabItem)event.item);
// Here: oldPageIndex == newPageIndex
...
}
});
Is this workaround still working or is there anything I could possibly be doing wrong? Or maybe, has there been any fix for a real PreSelection event in the meantime? I tried using event.doit, but the SelectionEvent is fired, when the tabs have been switched already.
You can use the selection listener but as you have found the getSelectionIndex() does not give you the old tab. So you will have to maintain the old tab index yourself.
This is the technique used by the Eclipse FormEditor.

How to disable "Window animation scale" programmatically on Android 4.0+ devices?

I'm using a Service that displays a view using WindowManager, and animation occurs every time I change the view's size using
windowManagerLayoutParams.height = newHeight;
((WindowManager) getSystemService(WINDOW_SERVICE)).updateViewLayout(mMainLayout, windowManagerLayoutParams);
If I disable manually the scale animations, no animation occurs.
Scale animation disabled manually like so:
http://www.cultofandroid.com/11143/android-4-0-tip-how-to-find-and-disable-animations-for-a-snappier-experience/
Is there a way to disable the window scale animations for my application programmatically?
I just had this same problem while working on a system overlay in the SystemUI package and decided to dig through the source to see if I could find a solution. WindowManager.LayoutParams has some hidden goodies that can solve this problem. The trick is to use the privateFlags member of WindowManager.LayoutParams like so:
windowManagerLayoutParams.privateFlags |= 0x00000040;
If you look at line 1019 of WindowManager.java you'll see that 0x00000040 is the value for PRIVATE_FLAG_NO_MOVE_ANIMATION. For me this did stop window animations from occurring on my view when I change the size via updateViewLayout()
I had the advantage of working on a system package so I am able to access privateFlags directly in my code but you are going to need to use reflection if you want to access this field.
As #clark stated this can be changed using reflection:
private void disableAnimations() {
try {
int currentFlags = (Integer) mLayoutParams.getClass().getField("privateFlags").get(mLayoutParams);
mLayoutParams.getClass().getField("privateFlags").set(mLayoutParams, currentFlags|0x00000040);
} catch (Exception e) {
//do nothing. Probably using other version of android
}
}
Did you try Activity#overridePendingTransition(0, 0)?
Check out the documentation:
Call immediately after one of the flavors of startActivity(Intent) or finish() to specify an explicit transition animation to perform next.

Swt FormToolkit focus issue

I have a strange issue: there is a SectionPart with composite, which is create from FormToolkit#createComposite(getSection()). Composite contains some number of widgets, which are positioned vertically one under other (as in a usual form). When the cursor is inside some widget, let's say input filed and I am clicking right between two fields on empty space, then focus automatically jumps to the first field in this composite.
I've tried to set SWT.NO_FOCUS style bit to the first widget in the form (usually it is a TableComboViewer) but it didn't helped (it seems, that this bit is not set on TableCombo, which is inside TableComboViewer).
So, have anybody faced something similar, or are there any workarounds for this problem or any clues what could it be?
Upd1: setting NO_FOCUS style helps for non TableComboViewer widgets (in this case they are not receiving focus). In case of TableComboViewer TableCombo widget contains Text widget, which receives focus, but even, if I add NO_FOCUS bit, it is not applied to Text style. I've checked source of TableCombo and there is a method checkStyle, which does following:
private static int checkStyle (int style) {
int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT | SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
return SWT.NO_FOCUS | (style & mask);
}
I am not actually sure what it does, cause I am not really good in bitwise operation, but seems, that this is the problem, why I can't set NO_FOCUS flag.
I don't understand though, why when I am clicking on Composite, it tries to set foxus on it's children, can I somehow suppress this?
Upd2: The reason is probably found, it is said, that:
When the view is activated, focus is transferred to the form, which passes it to the first control capable of accepting focus, our link in this case.
And it seems, that it is not possible to forbid this.
Thanks in advance,
AlexG
You problem lies in Composite.setFocus().. have a look at this:
public boolean setFocus () {
checkWidget ();
Control [] children = _getChildren ();
for (int i= 0; i < children.length; i++) {
if (children [i].setFocus ()) return true;
}
return super.setFocus ();
}
As you can see, this will try to set the focus on the first control in the composite that will allow for the focus...
[EDIT - the following is added to clarify...]
The above method would not be a problem if it wasn't for the MouseListener that is installed on all Composites in FormToolkit.adapt(Composite composite):
public void adapt(Composite composite) {
composite.setBackground(colors.getBackground());
composite.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent e) {
((Control) e.widget).setFocus();
}
});
if (composite.getParent() != null)
composite.setMenu(composite.getParent().getMenu());
}
I have solved this problem on a number of occasions by having my own FormToolkit.adapt(Composite composite) in a sub-class that does the right thing - I just exchange setFocus() with forceFocus(). Though that can occasionally give you other problems...

Wrapping/decorating GWT FileUpload

GWT FileUpload comes as a widget that produces so that one can upload a file during form submit (at least it's how I understand it :) ) What I want to do is to make it a better-looking and get rid of standard "Browse..." button.
Since I don't have good GWT experience (and no JavaScript), I looked for existing solutions and found quite a good project - gwtupload. It's good, but I realized I'd love to have my own miniature version (and also, I was curious about how it works). So I browsed through code and tried to extract the magic part. I realized that GWT FileInput is used, but it's not shown, and Button clicks are delegated to this FileInput. The code I tried to extract (only the part that delegates the click) after reviewing sources of gwtupload contains this tricky elem.click() JSNI:
class MyUpload extends Composite {
private static native void clickOnInputFile(Element elem) /*-{
elem.click();
}-*/;
public MyUpload() {
final FileUpload upload = new FileUpload();
AbsolutePanel container = new AbsolutePanel();
// container.add(upload);
Button btn = new Button("My Browse..");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
clickOnInputFile(upload.getElement());
}
});
container.add(btn);
initWidget(container);
}
}
But this seems not to work: clicking on 'My Browse..' results in no effect (just in case I also tried running with un-commented container.add(upload) line) . Could you please help me in understanding what's wrong/missing in this code sample?
Thank you in advance.
P.S. I know that I have to place it on the FormPanel, and I know the rest about how to perform the actual submit/handling in Servlet; the only thing I want to do is this kind of decoration.
Since I have not received any answers, I had to have more investigation of this issue, so I performed a deeper code analysis of gwtupload project in order to understand how GWT FileUpload (which gets transformed into ) can be decorated.
It turned out that element.click() will only work in browsers which support #click() method (IE, Chrome, Safari). Actually, Manuel Carrasco MoƱino - project author - mentions it within comments. There's second approach (for Firefox & Opera) that uses hack when FileInput is placed on transparent panel, which however is placed over some decorated button (using absolute positioning); comment by Manuel:
When the user puts his mouse over the button and clicks on it, what really happens is that the user clicks on the transparent file input showing the choose file dialog.
After that, the main work is correctly applying style attributes to elements.
Thus, there are two implementations of custom file upload component, and GWT deferred binding is used to instantiate them depending on Browser.
As for example I mention in my question, there're few fixes ("upload" has to be added to to the container, and it can be set to #setVisible(false)):
class MyUpload extends Composite {
private static native void clickOnInputFile(Element elem) /*-{
elem.click();
}-*/;
public MyUpload() {
final FileUploadWithMouseEvents upload = new FileUploadWithMouseEvents();
AbsolutePanel container = new AbsolutePanel();
container.add(upload);
upload.setVisible(false);
Button btn = new Button("My Browse..");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
clickOnInputFile(upload.getElement());
}
});
container.add(btn);
initWidget(container);
}
}
This example works fine in IE8.
P.S. Thanks to Manuel for his great library :)

Categories

Resources