I´ve implemented a drag and drop function on some of my images. And it works great besides that the new position of the images isn´t saved and they end up in the bottom left corner each time I restart the app. This is how I´ve done:
public GameScreen() {
stageImage = new Stage();
#Override
public void render(float delta) {
game.batch.setProjectionMatrix(camera.combined);
camera.update();
game.batch.begin();
flowerImage.setSize(300, 300);
stageMove.act(Gdx.graphics.getDeltaTime());
stageMove.draw();
}
#Override
public void show() {
flowerImage.addListener(new DragListener() {
public void drag(InputEvent event, float x, float y, int pointer) {
flowerImage.moveBy(x - flowerImage.getWidth() / 2, y - flowerImage.getHeight() / 2);
flowerImage.setPosition(x,y);
}
});
stageMove.addActor(flowerImage);
btnArrow.addListener(new ChangeListener() {
#Override
public void changed(ChangeEvent event, Actor actor) {
stageMove.clear();
game.setScreen(0);
I have to .clear() the stage when exiting the screen, otherwise the stage will create a duplicate of the image when I re-enter.
So does anyone have a solution to this? I tried just acting the stage and drawing the image from it´s source, but that has the same effect.
"Isn't saved" - who you expect to save it for you? You have to save it after dragging and to load it when you app starts.
https://github.com/libgdx/libgdx/wiki/File-handling
Related
I am using the android's custom keyboard to build a keypad. The OnKeyboardActionListener in android returns the "keyCode" of the key being pressed. But I want in particular, the onscreen x and y coordinates of that key ( with or without using the keyCode ).
P.S : Even coordinates of the center of the key would help. I have found a method "squaredDistanceFrom" which returns the squared distance between the center of the key and point where the screen is touched. Is there a function which returns the center's coordinates?
I know this question is quite old now, but I have been working on a project over the past two weeks with similar requirements and I struggled finding a solution. So here is what I propose:
Build a working keyboard
First, let start from a functional keyboard. Some very useful resources to get started:
The official android API guide and the sample from the sdk. The later can be compiled and used without modification.
A first tutorial that helps building a simple keyboard, and another one with lots of explanations.
Get the coordinates of the key pressed
I haven't found a direct way of retrieving the coordinates from the key pressed in the API.
However, we can determine and retrieve the actual instance the key pressed. First we need to create an onTouchListener on the KeyboardView. This will allow us to retrieve a MotionEvent and consequently the coordinates of the touch event within the view.
Then, there is a method in the Keyboard class which is called getKeys returning a list of Keys. We can then use the isInside method from the Key class to verify that the coordinates retrieved previously are inside of the key or not, and thereby retrieving the instance of the key pressed.
We need to retrieve the list of keys from the current keyboard every time is is displayed. This way, even if the user swaps from one layout to another (by using symbols or numbers for instance), we get the correct set of keys. We can do so by overriding the onStartInputView method from our class.
Sample
Retrieve the keys:
public void retrieveKeys() {
keyList = kv.getKeyboard().getKeys();
}
Override the onStartInputView which is called when the keyboard is displayed:
#Override
public void onStartInputView(EditorInfo info, boolean restarting) {
super.onStartInputView(info, restarting);
retrieveKeys();
}
Create an onTouchListener for the KeyboardView:
#Override
public View onCreateInputView() {
kv = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard, null);
kv.setOnKeyboardActionListener(this);
keyboard = new Keyboard(this, R.xml.qwerty);
kv.setKeyboard(keyboard);
retrieveKeys();
// Set the onTouchListener to be able to retrieve a MotionEvent
kv.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// For each key in the key list
for (Keyboard.Key k : keyList) {
// If the coordinates from the Motion event are inside of the key
if (k.isInside((int) event.getX(), (int) event.getY())) {
// k is the key pressed
Log.d("Debugging",
"Key pressed: X=" + k.x + " - Y=" + k.y);
int centreX, centreY;
centreX = (k.width/2) + k.x;
centreY = (k.width/2) + k.x;
// These values are relative to the Keyboard View
Log.d("Debugging",
"Centre of the key pressed: X="+centreX+" - Y="+centreY);
}
}
// Return false to avoid consuming the touch event
return false;
}
});
return kv;
}
Entire example (without the package and imports):
public class MyTestKeyboard extends InputMethodService
implements KeyboardView.OnKeyboardActionListener {
private KeyboardView kv;
private Keyboard keyboard;
private boolean caps = false;
private List<Keyboard.Key> keyList;
public void retrieveKeys() {
keyList = kv.getKeyboard().getKeys();
}
#Override
public void onStartInputView(EditorInfo info, boolean restarting) {
super.onStartInputView(info, restarting);
retrieveKeys();
}
#Override
public View onCreateInputView() {
kv = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard, null);
kv.setOnKeyboardActionListener(this);
keyboard = new Keyboard(this, R.xml.qwerty);
kv.setKeyboard(keyboard);
retrieveKeys();
// Set the onTouchListener to be able to retrieve a MotionEvent
kv.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// For each key in the key list
for (Keyboard.Key k : keyList) {
// If the coordinates from the Motion event are inside of the key
if (k.isInside((int) event.getX(), (int) event.getY())) {
// k is the key pressed
Log.d("Debugging",
"Key pressed: X=" + k.x + " - Y=" + k.y);
int centreX, centreY;
centreX = (k.width/2) + k.x;
centreY = (k.width/2) + k.x;
// These values are relative to the Keyboard View
Log.d("Debugging",
"Centre of the key pressed: X="+centreX+" - Y="+centreY);
}
}
// Return false to avoid consuming the touch event
return false;
}
});
return kv;
}
#Override
public void onKey(int primaryCode, int[] keyCodes) {
InputConnection ic = getCurrentInputConnection();
switch(primaryCode){
case Keyboard.KEYCODE_DELETE :
ic.deleteSurroundingText(1, 0);
break;
case Keyboard.KEYCODE_SHIFT:
caps = !caps;
keyboard.setShifted(caps);
kv.invalidateAllKeys();
break;
case Keyboard.KEYCODE_DONE:
ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
break;
default:
char code = (char)primaryCode;
if(Character.isLetter(code) && caps){
code = Character.toUpperCase(code);
}
ic.commitText(String.valueOf(code),1);
}
}
#Override
public void onPress(int primaryCode) {}
#Override
public void onRelease(int primaryCode) {}
#Override
public void onText(CharSequence text) {}
#Override
public void swipeLeft() {}
#Override
public void swipeRight() {}
#Override
public void swipeDown() {}
#Override
public void swipeUp() {}
}
Note: Tested on a Motorola Moto G XT1039 Android 5.1 API 22
After taking cue from this ques. I ended up here but the problem is, view is coming on right hand side of the screen and not occupying the full space.
Here is the current screenshot .
and the code is
public class MonitorView extends CoreView
{
public MonitorView(final Composite parent)
{
super(parent);
setDisplayName(I18N("Visual Monitoring of iCommand"));
// setLayout(new FillLayout());
final Composite composite=GUIToolkit.newComposite(parent, SWT.FILL, new GridData(SWT.TOP,SWT.LEFT,true,true,1,1));
FillLayout layout=new FillLayout();
composite.setLayout(layout);
CreatePartControl(composite);
}
private void CreatePartControl(Composite parent)
{
// TODO Auto-generated method stub
final Canvas canvas=new Canvas(parent,SWT.NONE);
Color white = display.getSystemColor(SWT.COLOR_WHITE);
canvas.setBackground(white);
canvas.addPaintListener(new PaintListener() {
#Override
public void paintControl(PaintEvent event)
{
int offset_x=130;
int offset_y=70;
int j=0,i=0,n=3,x,y;
DrawRoundedRectangle d= new DrawRoundedRectangle();
//for loop for column 1.Placing elements column wise.
for(i=0;i<n;i++)
{ x=0;y=offset_y*j;
d.drawrectangle(event, x, y, j);
j++;
x=0;y=offset_y*j;
d.drawrectangle(event, x, y, j);
j++;
}
j=0;int flag=6;
//for loop for drawing column 2
for(i=0;i<n;i++)
{
x=offset_x; y=offset_y*j;
d.drawrectangle(event, x, y, flag);
j++;flag++;
x=offset_x;y=offset_y*j;
d.drawrectangle(event, x, y, flag);
flag++;
j++;
}
}
});
}
}
How do i bring the view on the left hand side and onto full screen
Solution. See comment thread of question for discussion
public MonitorView(final Composite parent)
{
super(parent);
setDisplayName(I18N("Visual Monitoring of iCommand"));
setLayout(new FillLayout());
CreatePartControl(this);
}
Rest everything is same for above. Hope it helps :)
I have a window resizeHandler, it is working fine. Except that I'm just interested in the final dimension of the window, in other words, I'm interested in the dimension of the window when the mouse button is released. Is there a way I can listen to window mouse events?
I've written a piece of code that accomplishes my goal but I'd prefer something more obvious. resizeRequestId is a field:
private void processResize() {
final Timer timer = new Timer() {
final Size windowSize = getWindowDimention();
final int requestId = ++resizeRequestId;
#Override
public void run() {
final boolean isLatestRequest = requestId == resizeRequestId;
if (isLatestRequest) {
//DO SOMETHING WITH windowSize
}
}
};
timer.schedule(100);
}
The browser doesn't pass along events that happen outside of the page, and the window resize counts as outside the page. That said, you still get a hook for resize actions of the entire browser window:
Window.addResizeHandler(new ResizeHandler() {
public void onResize(ResizeEvent event) {
//get, process window resize behavior
}
});
For some browsers and some resizes, you'll get lots of events as the mouse moves, and for others, you'll only get the complete one. In firefox, for example, the resize handle in the corner sends every change that is made, while the side handles each send only once the user releases the mouse. Minimizing and maximizing the window also result in a single event.
Colin is right.
Moreover, if you do a lot of calculations "on resize" (e.g. forceLayout), it is a good idea to add a Timer. This way the calculations will be fired once every...10th of second?
final Timer resizeTimer = new Timer() {
#Override
public void run() {
mainPanel.forceLayout();
}
};
Window.addResizeHandler(new ResizeHandler() {
public void onResize(ResizeEvent event) {
int height = event.getHeight();
mainPanel.setHeight(height + "px");
resizeTimer.cancel();
resizeTimer.schedule(100);
}
});
That's it
I use SmartGWT 3.0, and I need to detect a drop of an external Label in a TreeGrid, I tried many ways to do that but none work.
In a Canvas I can do drop, but the TreeGrid doesn't detect the drop.
Is there any way to do that?
TreeGrid tileGrid = new TreeGrid();
tileGrid.setAlign(Alignment.CENTER);
tileGrid.setWidth(300);
tileGrid.setHeight(300);
tileGrid.setCanAcceptDrop(true);
tileGrid.addDropHandler(new DropHandler() {
#Override
public void onDrop(DropEvent event) {
Window.alert("drop");
}
});
Canvas cv = new Canvas();
cv.setBorder("1px solid #CCCCCC");
cv.setWidth(300);
cv.setHeight(300);
cv.setCanAcceptDrop(Boolean.TRUE);
cv.addDropHandler(new DropHandler() {
#Override
public void onDrop(DropEvent event) {
Window.alert("drop event"+event.toString());
}
});
Label lb = new Label("Drag me");
lb.setCanDrag(true);
lb.setCanDrop(true);
lb.setDragAppearance(DragAppearance.TARGET);
// added the components to a HLayout
panel.addMember(tileGrid);
panel.addMember(cv);
panel.addMember(lb);
panel.draw();
I think in the case of the canvas, it can accept everything as data dropped. In the case of the TreeGrid it expect something related to a record....
I tested with overriding
TreeGrid tileGrid2 = new TreeGrid(){
#Override
public Boolean willAcceptDrop(){
return new Boolean(true);
}
};
This in relation with this thread
And in this case The event is triggered but we get a javascript error so One solution will be to pickup the drag event from the label and create on the fly a TreeNode or something like that which could be accepted as dropped data on the grid side.
Hoping it could help....
Try
TreeGrid.addFolderDropHandler();
I use gwt popup to show some messages, but it is not displayed in the
center
of the display event if i call popup.center(). Actually it is not centered
only the first time, if i close it and open it again every thing is ok,
but not the first time. How to fix that?
GWT.runAsync(new RunAsyncCallback() {
#Override
public void onSuccess() {
Image fullImage = new Image(optionImageName);
fullImage.setAltText("Loading image ...");
imagePopup.setWidget(fullImage);
imagePopup.center();
}
});
I found this question on http://www.devcomments.com/gwt-Popup-is-not-centered-at107182.htm, and today I have had this problem too. I found the answer and i will post it here for future reference.
I found that the problem is that the image is not loaded completed when you center the popup. This happens the first time only because the second time the image is somehow cashed by the browser.
The solution is to center it on the onLoad event as well.
GWT.runAsync(new RunAsyncCallback() {
#Override
public void onSuccess() {
Image fullImage = new Image(optionImageName);
fullImage.setAltText("Loading image ...");
fullImage.addLoadHandler(new LoadHandler() {
#Override
public void onLoad(LoadEvent event) {
imagePopup.center();
}
});
imagePopup.setWidget(fullImage);
imagePopup.center();
}
});
I had this problem as well. The reason that you have to call center twice is because the popup container is actually removed from the DOM when the popup is "hidden". This is problematic because your popup has to now "show" the contents of the popup before you can check that the image is loaded.
The issue with the implementation recommended is that the first call to center() will be done incorrectly if the image is not cached. The second call to center will correct it. On the browser, this causes a shift of the popup dialog box (which looks pretty bad).
I would recommend the following:
1. Put a waiting spinner in the same display and show that initially.
2. One the loadHandler is called, display the image, hide the spinner, and recenter.
public void onClick(ClickEvent event) {
// TODO Auto-generated method stub
final ADPopup popup = new ADPopup();
popup.setHeight("300px");
popup.setWidth("500px");
popup.setPopupPositionAndShow(new PopupPanel.PositionCallback() {
public void setPosition(int offsetWidth, int offsetHeight) {
// TODO Auto-generated method stub
int left = (Window.getClientWidth() - offsetWidth) / 3;
int top = (Window.getClientHeight() - offsetHeight) / 3;
popup.setPopupPosition(left, top);
}
});
popup.show();
}
Hope this Help.