Libgdx error clickListener - java

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.

Related

JButtons don't follow the intended handlers?

I'm making a minesweeper game, in the first part, I'm deciding whether or not there is a bomb at a certain button by using boolean1 (the field is a 16x16 array) I have tested this part, and the output is correct. 50 random true values and the rest are false my problem starts at the second part, where I want to get a certain action by the button based on the value of the boolean1. When implementing the code, all of the jbuttonsfollow the second ActionListener where the icon is set to bomb I want to get the jbuttons to also follow the first handler.
1st procedure
static void placeMines()
{
for (int x=0;x<16;x++)
{
for (int y=0;y<16;y++)
{
if(boolean1[x][y]=(true))
{
boolean1[x][y]=false;
}
}
}
int minesPlaced = 0;
Random random = new Random();
while(minesPlaced < 50)
{
int a = random.nextInt(Width);
int b = random.nextInt(Height);
boolean1[a][b]=(true);
minesPlaced ++;
}
}
2nd procedure:
static void buttonfunctions()
{
for(int c=0;c<16;c++)
{
for(int d=0;d<16;d++)
{
if (boolean1[c][d]=false)
{
final int temp3=c;
final int temp4=d;
jbuttons[c][d].addActionListener(new ActionListener()
{
#Override
public void actionPerformed (ActionEvent e)
{
jbuttons[temp3][temp4].setIcon(clickedCell);
}
});
}
if(boolean1[c][d]=true)
{
final int temp1=c;
final int temp2=d;
jbuttons[temp1][temp2].addActionListener(new ActionListener()
{
#Override
public void actionPerformed (ActionEvent e)
{
jbuttons[temp1][temp2].setIcon(bomb);
}
});
}
}
}
}
In order to check if a boolean is true, you want to do :
if (myBoolean)
doing
if (myBoolean == true)
is equivalent, but more verbose than needed.
doing
if (myBoolean = true) is syntactically correct, but has the effect of assigning true to myBoolean, and then evaluating the result of the assignment, which is true. So, going back to your code:
If the intent of the following code is to reset the matrix:
if(boolean1[x][y]=(true))
{
boolean1[x][y]=false;
}
then you should just do
boolean1[x][y] = false;
Also
if (boolean1[c][d]=false)
should probably be:
if (! boolean1[c][d])
There may be more stuff wrong with your code, but you may want to start fixing this.

Breaking If statements.. Clicking a button once

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

How do I declare custom JButtons with composition and add action listeners to them?

I am currently in the process of changing my extended buttons to making them use composition and in the process of turning my MouseListeners to action listeners. I will need to know when it is clicked and isRollover(); I'm new to GUI and help is appreciated. How do I declare the buttons correctly in the different class? Where do I add the actionListeners in the EmptySpace class?
public class EmptySpace{
private JButton button;
protected int x;
protected int y;
protected String name;
public EmptySpace(String text, int x, int y){
this.name = text;
this.x = x;
this.y = y;
button = new JButton(text);
}
public String toString(){
return "Name: " + name + " Xcoords: " + x + " Ycoords: " + y;
}
public JButton getButton(){
return button;
}
}
different class
for (int i = 0; i < lengthx*lengthy; i++) {
if(i<lengthx){
x = i+1;
}else x = i % lengthx+1;
if(i<lengthx){
y=1;
}else y = i/lengthx+1;
String xString = Integer.toString(x);
String yString = Methods.getChar(y);
buttons[x-1][y-1] = new EmptySpace(xString+yString,x,y);
buttons[x-1][y-1].setPreferredSize(new Dimension(25, 25)); //error
buttons[x-1][y-1].setBackground(Color.WHITE); //error
buttons[x-1][y-1].setText(""); //error
buttons[x-1][y-1].setToolTipText(xString+yString); //error
pane.add(buttons[x-1][y-1]); //error
If you want to add action listeners to your buttons instead of mouse listeners then first make sure that you have imported java.awt.event
Add an actionlistener to your button like this:
button.addActionListener(new myButtonListener());
Then create a inner class with the name of your action listener like this:
public class myButtonListener implements ActionListener {
public void actionPerformed(ActionEvent ev){
//do what you want your button to do
}
}
Make sure that the function is always called action performed and always has an actionEvent as the parameter.

libGDX - Button is set to down even if outside of bounds

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
}
});

Java NullPointerExpection Problems

So, I'm pretty sure I did everything correctly, but when I run my program, it gives me this log:
Exception in thread "main" java.lang.NullPointerException
at com.BLANK.handler.ButtonHandler.<init>(ButtonHandler.java:19)
at com.BLANK.BLANKScreen.<init>(BLANKScreen.java:28)
at com.BLANK.BLANKWindow.<init>(BLANKWindow.java:28)
at com.BLANK.BLANKWindow.main(BLANKWindow.java:11)
Here's the code that's giving me errors in the ButtonHandler class:
public Button button;
public int buttonX = button.x;
public int buttonY = button.y;
public int buttonSizeX = button.xSize;
public int buttonSizeY = button.ySize;
And here's the button integers that it's referring to:
public int x;
public int y;
public int xSize;
public int ySize;
public Button(int x, int y, int xSize, int ySize, String s, Graphics g) {
this.x = x;
this.y = y;
this.xSize = xSize;
this.ySize = ySize;
}
Anyone have any ideas as to what I am doing wrong and how I could fix it?
P.S. If you need any more code snippets just tell me and I'll provide them.
Problem
When you declare this:
public Button button;
public int buttonX = button.x;
You are creating and initializing the fields of a class:
button does not have any initialization, so it defaults to null
buttonX is supposed to be assigned button.x, but this expression is trying to get the field of a null object, which causes NPE (this is the very meaning of this exception)
Solution
The direct solution would be to initialize button before declaring the other fields. But from what I see you'd rather not use fields to "store" button.x. Use button.x directly where needed.
You're declaring a Button:
public Button button;
and without initializing it you're trying to assign:
public int buttonX = button.x;
which gives you NPE because button is still null
If this
public Button button;
public int buttonX = button.x;
public int buttonY = button.y;
public int buttonSizeX = button.xSize;
public int buttonSizeY = button.ySize;
is a consecutive code block and there are no lines of code between these, then your code can't work.
You declare a new variable button. This variable will be initialized with null by default. After that you try to access a property of that variable which is null at this point. This causes your NullPointerException.
To have accurate access to a property you need to initialize the variable correctly.
public Button button = new Button(x, y, xSize, ySize, string, graphics);
You need to initialize a variable before you use it ...
By doing this you will get an null pointer
public Button button;
public int buttonX = button.x;
Because button is not initialized yet.
button is null and you get a null pointer when you try to perform some action on an object which is null.

Categories

Resources