I am trying to make a keyboard and everything works fine. I just want to break the if statement after each click to stop repetitiveness of the char. I don't want to use a Boolean because user can enter same character more than once. This is the image listener
a = new Image(new Texture("Sprites/Keyboard/a.png"));
a.addListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
apressed = true;
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
apressed= false;
}
});
And this is what i have in my update inside the activity or state.
#Override
public void handleInput() {
if (keyboard.apressed) {
builder.append('A');
currentWord = builder.toString();
//break; here doesn't work. says its outside the loop.
}
}
So in theory this is what i want but can't use because im guessing its to much work for every char?
#Override
public void handleInput() {
if (keyboard.apressed) {
builder.append('A');
currentWord = builder.toString();
try {
TimeUnit.MILLISECONDS.sleep(400);
} catch (Exception e) {
System.out.println("error");
}
}
any ideas? thanks in advance.
I made my own keyboard as well using LibGDX TextButtons. Since you are using images and not text, you could use the ImageButton instead. I then used the ChangeListener with the changed() method because it only triggers after pressing and releasing the button, which avoids repetitive characters while the button is being pressed.
keyButton.addCaptureListener(new ChangeListener() {
#Override
public void changed(ChangeEvent event, Actor actor){
// key logic here
Related
I'm trying to display a GIF file to a JLabel. No problem I load the GIF and set it as the icon of the label. But now i really need to know when this ends, because it has to function as a cutscene. What i already tried is this (GameScene is a custom object but i know setIcon works, trust me) :
private GameScene scene;
private ImageIcon _temp;
private ImageIcon toplay;
private Thread anim;
public Cutscene(ImageIcon gif, GameScene scene, int length){
this._temp = scene.getIcon();
this.toplay = gif;
this.scene = scene;
anim = new Thread(){
#Override
public void run(){
scene.setIcon(gif);
scene.repaint();
try {
Thread.sleep(length);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
private void _s(){
scene.setSolidColor(false);
scene.setIcon(toplay);
scene.repaint();
}
public void play(){
_s();
anim.start();
}
public void await(){
try {
anim.join();
scene.setIcon(_temp);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Now, Is there anyway I can achieve this without, just letting the whole program sleep for the given amount of time and then continue with the rest of the code and completely not drawing the GIF file?
This is a really simply example, it will only work with non-looping gifs, if your gif repeats you'll have to test the time between requests for FRAMEBITS and try and determine if you can detect the point at which loops.
public class MonitoringLabel extends JLabel {
public MonitoringLabel(Icon image) {
super(image);
}
public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
public void removeActionListener(ActionListener listener) {
listenerList.remove(ActionListener.class, listener);
}
protected void fireActionPerformed() {
ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
if (listeners.length > 0) {
ActionEvent evt = new ActionEvent(this, 0, "stopped");
for (ActionListener listener : listeners) {
listener.actionPerformed(evt);
}
}
}
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
boolean finished = super.imageUpdate(img, infoflags, x, y, w, h);
if (!finished) {
fireActionPerformed();
}
return finished;
}
}
The above class provides an ActionListener which is triggered when the image "finishes" loading (this is triggered when their are no new frames in the animation to be played - repeating gifs never return false)
You can use a different listener interface if you want, I just threw it together as an example.
The reason I choose to override imageUpdate is because the JLabel is already acting as the ImageObserver to the image when it paints it, this way we can use the power of the JLabel without fussing about with manually painting a gif ... yes I've done it, it's pain
Would it be possible to make the GIF non-repeating with the program used to make it? Most photo editors that make GIF images give you the option of making it repeating or not.
If I'm understanding your problem, it seems like you just want the gif to play once?
If it's for a cut scene, why not make the program sleep during that time?
I'm am trying to properly setup button clicks for my UI. I want my buttons to respond right after clicking them instead of releasing by using ClickListeners touchDown method.
I've created a class which creates and displays a table with text input:
public class InputBox {
public static float OFFSET = 20;
private Table table;
private TextField inputField;
private TextButton okButton;
private TextButton closeButton;
private String saveText;
private TextButtonStyle style;
private Skin skin;
public InputBox(Skin skin, float x, float y, float width, float height, boolean visible) {
this.skin = skin;
table = new Table();
// Creating a new style as suggested.
style = new TextButtonStyle();
style.up = skin.getDrawable("button_normal_up");
style.down = skin.getDrawable("button_normal_down");
style.font = skin.getFont("default");
inputField = new TextField("", skin);
okButton = new TextButton("Ok", style);
okButton.addListener(new ClickListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if (button != Buttons.LEFT) {
return false;
}
Game.resources.getSound("click_2").play();
table.setVisible(false);
if (inputField.getText().equals("")) {
saveText = null;
return false;
}
saveText = inputField.getText();
return true;
}
});
closeButton = new TextButton("Close", style);
closeButton.addListener(new ClickListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if (button != Buttons.LEFT) {
return false;
}
Game.resources.getSound("click_2").play();
saveText = null;
table.setVisible(false);
return true;
}
});
table.setVisible(visible);
table.setX(x);
table.setY(y);
table.setWidth(width);
table.setHeight(height);
table.add(inputField).colspan(2).center().width(width - OFFSET).expand().padRight(2);
table.row();
table.add(okButton).width(width / 2 - OFFSET / 2).right();
table.add(closeButton).width(width / 2 - OFFSET / 2).left();
table.pad(5);
}
public void setUnclicked() {
style.down = skin.getDrawable("button_normal_up");
// I think these two lines ar uneeded.
okButton.setStyle(style);
closeButton.setStyle(style);
}
public void setClicked() {
style.down = skin.getDrawable("button_normal_down");
// Same here.
okButton.setStyle(style);
closeButton.setStyle(style);
}
public void setText(String text) {
inputField.setText(text);
}
public String getSaveTextOnce() {
String temp = saveText;
saveText = null;
return temp;
}
public void setBackground(Drawable background) {
table.setBackground(background);
}
public boolean isVisible() {
return table.isVisible();
}
public void setVisible(boolean visible) {
table.setVisible(visible);
}
public Table getTable() {
return table;
}
}
The table is being set to visible after clicking a different button:
// Save map button.
saveMap = new ImageButton(new ImageButtonStyle());
saveMap.getStyle().imageUp = uiSkin.getDrawable("save");
saveMap.getStyle().up = uiSkin.getDrawable("button_flat_up");
saveMap.getStyle().down = uiSkin.getDrawable("button_flat_down");
saveMap.addListener(new ClickListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
if (button != Buttons.LEFT) {
return false;
}
Game.resources.getSound("click_2").play();
if (saveBox.isVisible()) {
saveBox.setVisible(false);
saveBox.setUnclicked();
return false;
}
saveBox.setVisible(true);
saveBox.setClicked();
return true;
}
});
The entire class for the saveMap button: http://pastebin.com/62ZGfcch
However, if I close the table by clicking the "ok" or "close" button and click and hold the mouse over the show table button, the table reappears with last clicked button being held down.
This video illustrates whats happening:
https://www.youtube.com/watch?v=Jf3WzU8G4dE&feature=youtu.be
If I move the mouse while holding it down, the last clicked button on the table resets to its normal state.
First i would recommend you to rather use a TextButtonStyle instance for setting the style of the buttons rather than a Skin instance.
You could somehow get the TextButton's references to the saveMap.addListener anonymous inner class. Then you could manualy set the style of the Ok and Cancel TextButton's, something like this:
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
Game.resources.getSound("click_2").play();
if (saveBox.isVisible()) {
saveBox.setVisible(false);
okButtonReference.setStyle(unclickedTextButtonStyle) // Not-clicked TextButtonStyle as parameter
cancelButtonReference.setStyle(unclickedTextButtonStyle) // Not clicked TextButtonStyle as parameter.
return false;
}
saveBox.setVisible(true);
return true;
}
By forcing the TextButton to change it's TextButtonStyle by calling setStyle() you can be confident that the button will change.
Also i noticed that you are not calling the debug() method on the Table object. This is not necessary but it is advisable:
table.add(inputField).colspan(2).center().width(width - OFFSET).expand().padRight(2);
table.row();
table.add(okButton).width(width / 2 - OFFSET / 2).right();
table.add(closeButton).width(width / 2 - OFFSET / 2).left();
table.pad(5);
table.debug();
After more fiddling I found out that the way I setup my games InputProcessor was causing this issue. I did not handle the touchUp event properly.
Game.inputs.addProcessor(new InputProcessor() {
...
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
releasedButton = -1;
if (UI.isOver()) {
return false;
}
if (button == Buttons.LEFT) {
releasedButton = Buttons.LEFT;
}
if (button == Buttons.RIGHT) {
releasedButton = Buttons.RIGHT;
}
return true; // <--- setting this to false fixes the issue
}
});
I have 5 button and a want each button can't print number 1,2,3,4,5. but each button only print "5". Is there any wrong with my code? Or its bug on libgdx? I use libgdx v1.2.0
for (Integer i = 1; i <=5 ; i++){
tabeldalam=new Table(skin);
tabeldalam.row();
tabeldalam.add(new Label("GAmbar :", skin)).height(100).width(100);
tabeldalam.row();
tabeldalam.add(new Label("Harga",skin)).height(30).width(100);
tabeldalam.row();
TextButton nextbutton = new TextButton("Beli",skin);
nextbutton.setWidth(100);
nextbutton.setHeight(20);
nextbutton.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
beli(i);
}
});
tabeldalam.add(nextbutton).height(20).width(100);
tabelLuar= new Table(skin);
tabelLuar.add(tabeldalam).width(100).height(150);
}
private void beli(Integer i){
text2.setText(i.toString());
}
Use int instead of Integer for your for loop. All of your click listeners are referencing the same instance of Integer because it is an object and not a primitive.
For code non-ambiguity I would copy the variable to a final int variable and use that for the click listener so it is absolutely clear that a separate int is used for each.
final int index = i;
...
//use index in the ClickListener instead of i
try this simple example:
...// Change in your Code addListener for this:
nextbutton.addListener(new ClickListenerOverflow(i) {
#Override
public void clicked(InputEvent event, float x, float y) {
beli(n);
}
});
...//
Add this code inside of your Class:
private class ClickListenerOverflow extends ClickListener{
int n;
public ClickListenerOverflow(int n){
this.n = n;
}
}
when you click call beli (i), i then its value is 5, it is the latter who won the for.
First of all, i'm trying to make a puzzle game with the same concept as this game,
LINK: http://www.youtube.com/watch?v=-b2LunJPXC0 (the title of the game is Siren Fantasia)
Where in the user will hold a single piece of item from the gameboard and the objects that is surrounding it will be rotated clockwise until the user releases it.
I want to imitate that, When the user holds the button, the action will continuously loop until the user releases it.
Heres a sample of the code that i have already made:
float delay = 2f;
button.addListener(new ClickListener() {
#Override
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
if(pointer == 0) {
Timer.schedule(new Task(){
#Override
public void run() {
int counter = 0;
do{
Timer.schedule(new Task() {
#Override
public void run() {
button2.setVisible(false);
}
}, delay);
Timer.schedule(new Task() {
#Override
public void run() {
button2.setVisible(true);
}
}, delay);
}while( counter >= 1 );
}
}, buttonDelay);
}
return false;
}
});
And the output ain't the one that i wanted it to be. When i hold button, the button2 doesn't set to visible(false) and visible(true). But when i kept holding it over and over again, it would sometimes work.
I really need help.
Thank you.
A JComponent of mine is firing a mouseDragged event too vigorously. When the user is trying to click, it interprets is as a drag even if the mouse has only moved 1 pixel.
How would I add a rule for a particular component that amounted to:
Do not consider it a drag event unless
the mouse has moved 10 pixels from the
point at which is was pressed down.
Note: I know it's not a system setting in my OS, since only events on that component suffer from this over sensitivity.
Thank you.
Previous answers combined together, with proper event type:
public class DragInsensitiveMouseClickListener implements MouseInputListener {
protected static final int MAX_CLICK_DISTANCE = 15;
private final MouseInputListener target;
public MouseEvent pressed;
public DragInsensitiveMouseClickListener(MouseInputListener target) {
this.target = target;
}
#Override
public final void mousePressed(MouseEvent e) {
pressed = e;
target.mousePressed(e);
}
private int getDragDistance(MouseEvent e) {
int distance = 0;
distance += Math.abs(pressed.getXOnScreen() - e.getXOnScreen());
distance += Math.abs(pressed.getYOnScreen() - e.getYOnScreen());
return distance;
}
#Override
public final void mouseReleased(MouseEvent e) {
target.mouseReleased(e);
if (pressed != null) {
if (getDragDistance(e) < MAX_CLICK_DISTANCE) {
MouseEvent clickEvent = new MouseEvent((Component) pressed.getSource(),
MouseEvent.MOUSE_CLICKED, e.getWhen(), pressed.getModifiers(),
pressed.getX(), pressed.getY(), pressed.getXOnScreen(), pressed.getYOnScreen(),
pressed.getClickCount(), pressed.isPopupTrigger(), pressed.getButton());
target.mouseClicked(clickEvent);
}
pressed = null;
}
}
#Override
public void mouseClicked(MouseEvent e) {
//do nothing, handled by pressed/released handlers
}
#Override
public void mouseEntered(MouseEvent e) {
target.mouseEntered(e);
}
#Override
public void mouseExited(MouseEvent e) {
target.mouseExited(e);
}
#Override
public void mouseDragged(MouseEvent e) {
if (pressed != null) {
if (getDragDistance(e) < MAX_CLICK_DISTANCE) return; //do not trigger drag yet (distance is in "click" perimeter
pressed = null;
}
target.mouseDragged(e);
}
#Override
public void mouseMoved(MouseEvent e) {
target.mouseMoved(e);
}
}
I've had to do exactly this before. Here's my mouse event processing code, cut down to just the bits relating to making drag require a few pixels before being treated as a drag.
public void mousePressed(int mod, Point loc) {
pressLocation=copyLocation(loc,pressLocation);
dragLocation=null;
}
public void mouseReleased(int mod, Point loc) {
if(pressLocation!=null && dragLocation!=null) {
// Mouse drag reverted to mouse click - not dragged far enough
// action for click
pressLocation=null;
}
else if(dragLocation!=null) {
// action for drag completed
}
else {
// do nothing
}
pressLocation=null;
dragLocation=null;
}
public void mouseDragged(int mod, Point loc) {
if(pressLocation!=null) { // initial drag actions following mouse press
dragLocation=pressLocation; // consider dragging to be from start point
if(Math.abs(loc.x-pressLocation.x)<dragMinimum && Math.abs(loc.y-pressLocation.y)<dragMinimum) {
return; // not dragged far enough to count as drag (yet)
}
// action drag from press location
pressLocation=null;
}
else {
// action drag from last drag location
dragLocation=copyLocation(loc,dragLocation);
}
}
And note, I also had problems with Java some JVM's generating click events after dragging, which I had to detect and suppress.
If I read your question correctly, you're tracking both click and mousedrag events. Can you track the coordinates upon mousedown, followed by a short computation in mousedrag to see if the mouse has moved your desired minimum numbers of pixels? Of course, you then also want to cancel/reset on mouseup or when the mouse is dragged outside the bounds of your JComponent.
Caveat: I haven't done this myself, but I think it's where I'd start if it were me.
Software Monkey's code seemed to be missing some code, so I wrote this solution:
navigationTree.addMouseListener(new DragInsensitiveMouseClickListener(10) {
#Override
public void mouseClicked(MouseEvent e) {
TreePath treePath = navigationTree.getPathForLocation(e.getX(), e.getY());
if(treePath != null) {
processChoice();
}
}
});
This will still fire the mouseClicked() event when the user produces at most 10 pixels of "drag travel".
The code for the click listener:
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class DragInsensitiveMouseClickListener extends MouseAdapter {
private final int allowedTravel;
public Point mouseDownPoint;
public DragInsensitiveMouseClickListener(int allowedTravel) {
this.allowedTravel = allowedTravel;
}
#Override
public void mousePressed(MouseEvent e) {
mouseDownPoint = e.getPoint();
}
#Override
public void mouseReleased(MouseEvent e) {
double horizontalTravel = Math.abs(mouseDownPoint.getX() - e.getX());
double verticalTravel = Math.abs(mouseDownPoint.getY() - e.getY());
if (horizontalTravel < allowedTravel && verticalTravel < allowedTravel) {
mouseClicked(e);
}
}
}