So basically i need to be able to click a button, and each time its clicked it takes away 10 from 100. so after 10 clicked it should display 0.
public class numberclass{
public String numbermethod() {
int number = 100;
String result = Integer.toString(number);
return result;
}
}
//part of swing class below
String numberString = numberclass.numbermethod();
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textArea.append(numberString);
}
}
});
obviously as it stands it only displays 100 in the text field upon a click. I have tried many ways to make this work, but i feel like i'm missing something crucial. i have tried to google this basic, basic problem, however i seem to not be able to word it correctly.
Start by subtracting something from something. Now, there's any number of ways you might achieve this, but lets start by using a method and maintain the class encapsulation...
public class NumberClass {
private int number = 100;
public void update() {
number -= 10;
}
public String numbermethod() {
String result = Integer.toString(number);
return result;
}
}
Then update the text to be displayed
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
numberClass.update();
String numberString = numberClass.numbermethod();
textArea.append(numberString);
}
});
You numbermethod() is flawed. You set number to 100 and return that value (100) as a String. It will never be something other than "100"! Move int number = 100; outside the method (member variable)
In your button listener add:
number -= 10; // or number = number - 10;
Related
I am attempting to create a calculator app, when I try to add 2 decimals together, I do not get the results I anticipated.
examples:
user inputs [1.1 + 1.1] and [1.1 + 1] or 2.1 is returned.
It is as if as if second value is being truncated, I am not entirely sure where this would be occurring
user inputs[2.1 + 2] and [2.1 + 2] or 4.1 is returned
user inputs [2 + 2.1] and [2 + 2] or 4 is returned
I have not used the debugger, though I have placed print line statements through out the code and I have not been able to see the issue.
Code:
information
I only attached a single number (image button) as all numbers 1-9 have identical code
variables that are not instantiated in code below have been instantiated as "" if they are a string and 0.0 if they are a double
I am using an array list called values which takes in strings, and using double.parsedouble() to convert it to a double, this occurs in the equals method
please let me know if their is anything I need to add to make this question easier to understand, and any help is appreciated
thank you!
1 button
one_button_ET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (plus_selected) {
update_selected_buttons(); //for boolean variables and to change mathematical function button image
screen_value = "";
updateScreen("1");
System.out.println(screen_value);
values.add(screen_value);
} else {
updateScreen("1");
System.out.println(screen_value);
}
}
});
addition button
addition_button_ET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!plus_selected) {
plus_selected = true;
addition_button_ET.setImageResource(R.drawable.addition_selected_500_500);
if(Double.parseDouble(screen_value) == current_value){
}
else
values.add(screen_value);//
} else {
plus_selected = false;
addition_button_ET.setImageResource(R.drawable.addition_button_500_500);
}
}
});
update screen
private void updateScreen(String value) { //being used for only one_button
//to reset title text
if (screen_value.equals(initial_screen_value)) {
screen_value = "0.0";
screen_TV.setTextSize(50);
}
//clears default value (0.0), allowing user to enter in a number
if (screen_value.equals("0.0")) {
screen_value = value;
screen_TV.setText(screen_value);
} else {
screen_value += value;
System.out.println(screen_value);
screen_TV.setText(screen_value);
}
}
clear button (clear button calls this method, and that is the only parameter it has)
private void resetScreen() {
screen_value = "0.0";
//values.clear();
screen_TV.setTextSize(50);
screen_TV.setText(screen_value);
}
equals button
equals_button_ET.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
current_value = 0;
sum = 0;
System.out.println(values);
for(int i = 0; i<values.size();i++) {
sum += Double.parseDouble(values.get(i));
}
current_value = sum;
screen_value = "" + sum;
screen_TV.setText(screen_value);
}
});
First of all, thank you for taking your time to read this.
this is what am trying to make:
A Text editor with multiple options.
a button for a virtual keyboard. I've managed to create the buttons, also successfully added all the buttons, however I am having difficulties linking each button to my text area and making each button press work.
Not looking for anything complex also all other aspects of the app works, as you will see from the screenshot provided.
this is the bits of code in relation to my keyboard.
class KbListener implements ActionListener //kb function.
{
public void actionPerformed(ActionEvent e) //checking events.
{
keyboard = new JFrame("VK");
keyboard.setSize(400,300);//setting initial size of app.
keyboard.setVisible(true);//making sure its active.
keyboard.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);//closes when the x is pressed.
JButton[] letter = new JButton[27];
keyboard.setLayout(new GridLayout(3,9));
for (int i = 0;i<27;i++)
{
letter[i] = new JButton(""+(char)('A'+ i));
keyboard.add(letter[i]);
//up until this point all is fine.
letter[i].addActionListener = (new ActionListener());
if(e.getSource() ==letter[A])
textArea.append("A");
}
}
}
You need to create a String that is used in the button and used in its listener both, something like,
for (int i = 0; i < 27; i++) {
final String buttonText = String.valueOf((char) ('A' + i));
letter[i] = new JButton(buttonText);
keyboard.add(letter[i]);
letter[i].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textArea.append(buttonText);
}
});
}
Note that buttonText must be final so that it is accessible within the anonymous inner ActionListener class.
Also, consider avoiding magic numbers. For instance, you could do
for (int i = 0; i <= (int)('Z' - 'A'); i++) {
or
int i = 0;
for (char myChar = 'A'; myChar <= 'Z'; myChar++) {
final String btnText = String.valueOf(myChar);
letter[i] = new JButton(btnText);
keyboard.add(letter[i]);
letter[i].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textArea.append(btnText);
}
});
i++;
}
Edit
Another and perhaps better way to do this is to use Actions rather than ActionListeners. For instance,...
//....
int i = 0;
for (char myChar = 'A'; myChar <= 'Z'; myChar++) {
final String btnText = String.valueOf(myChar);
MyKeyBoardAction action = new MyKeyBoardAction(btnText);
letter[i] = new JButton(action);
i++;
}
}
private class MyKeyBoardAction extends AbstractAction {
public MyKeyBoardAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
textArea.append(getValue(NAME).toString());
}
}
You also ask about the space character,
do u know how to add a space to the code as well?
That would not work with your for loop but can be added on its own.
Also,
but why avoid the numbers?
Because it's easy to make hard to fix bugs if you use "magic" numbers that don't intrinsically make sense. Also, by using constants, variables rather than hard-coded numbers, your variables make your code self-commenting.
Why don't create direct the action listener?
letter[i].addActionListener = (new ActionListener() {
public void onClick(View view) {
textArea.append(""+(char)('A'+ i));
}
);
Hope you are all well.
Also I'm so sorry for how long winded this is. And I'm new to Java so please forgive me for my lack of knowledge/terminology/Java conventions.
Basically I've created a program which takes user input and moves the vehicle across the surface area. So the user input can be "50 left 4" so that means go 50 meters forward, turn left and go 4 meters forward.
For the vehicle I'm using a paint method on a JPanel. When the vehicle moves forward, it initially jumped from one side of the area to another. I wanted to be able to see it moving meter by meter. So I added a Swing Timer which moves the vehicle 1 meter, pauses for a second, moves the vehicle 2 meter and so on.
Now, the problem is that when I enter the commands "50 left 4", the vehicle simply turns left and then moves 4 meters forward. It ignores the first number command. The same happens when I enter "3 4", it will ignore 3 and just move 4 meters forward. Also when I enter "3 left", it will turn left first and then move 3 meters forward. Now I've got methods which takes the user input, chop it up into an array, feed each element of the array through a loop, check if it's an integer or not. If it is an integer it moves the vehicle forward, if not it turns the vehicle either left or right. That all works fine and I'm happy with it.
So what I thought I'd do is have the class which moves the vehicle implement Runnable so that this method will be executed from a separate thread, making the main thread wait and that way it will won't ignore every command except for the last. But that doesn't work either.
Here is the movement class which moves the vehicle forward 1 meter at a time using a Swing Timer.
It implements Runnable. It's abstract because I needed the run method to take the user input commands as a parameter. Is that what's causing the problem?
public abstract class Movement implements Runnable {
static int count = 0;
static int distance;
public static void moveRover() {
// Every 1 second the timer will move the Rover 40 pixels.
at.translate(0, 40);
}
public static void getDistance(int num) {
distance = num;
}
static Timer timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
moveRover();
count++;
System.out.println(count);
if (count == distance) {
stop();
System.out.println("Timer stopped");
count = 0;
}
}
});
public static void start(int num) {
getDistance(num);
System.out.println("Distance rover will travel: " + distance);
System.out.println("\nTimer started");
timer.start();
}
public static void stop() {
timer.stop();
}
public void run(int num) {
start(num);
}
public Movement(int num) {
System.out.println("Start RUN method");
run(num);
}
And here is the code from another class which runs the for loop and thread:
public static void action(final String[] commands) {
for (int i = 0; i < commands.length; i++) {
if (isInteger(commands[i])) {
int distance = Integer.parseInt(commands[i]);
Movement h1 = new Movement(distance) {
#Override
public void run() {
System.out.println("Empty run method");
}
};
Thread t1 = new Thread(h1);
t1.start();
System.out.println(t1.isAlive());
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else {
Direction.start(commands[i]);
String pos = Direction.getDirection(); // GET DIRECTION
}
}
}
I really appreciate you reading all that, thank you so much!
And thank you to anyone who replies! If you know where I'm going wrong and what I can do to fix it, you're an absolute lifesaver, I really appreciate it :D
So yeah, you need to learn about Threading in Java. You should NEVER use Thread.start() as of Java 1.6 and later. Quite frankly, I'm not even sure why you're using Threads in your for-loop. Ignoring for the moment all of your questionable design choicess, try this code:
public static void action(final String[] commands) {
for (int i = 0; i < commands.length; i++) {
if (isInteger(commands[i])) {
int distance = Integer.parseInt(commands[i]);
new Movement(distance) {
#Override
public void run() {
System.out.println("Empty run method");
}
}.run();
} else {
Direction.start(commands[i]);
String pos = Direction.getDirection(); // GET DIRECTION
}
}
}
These two buttons are cycling through an array and when pressed increment to many times and depending on what the maximum index is. I thought it might be because (for backwards a least I have "i set as maximum index" but changing to current index stops the button functioning all together.
btnprev.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = dataArrayMaxIndex; i >= 0; i-- ) {
System.out.println("backwards");
dataArrayCurrentIndex = i;
websitetxt.setText(dataArray[i].getWebsitename());
usernametxt.setText(dataArray[i].getUsername());
passwordtxt.setText(dataArray[i].getPassword());
notestxt.setText(dataArray[i].getNotes());
}
}
});
btnnext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i<dataArrayMaxIndex; i++) {
System.out.println("foward");
dataArrayCurrentIndex = i;
websitetxt.setText(dataArray[i].getWebsitename());
usernametxt.setText(dataArray[i].getUsername());
passwordtxt.setText(dataArray[i].getPassword());
notestxt.setText(dataArray[i].getNotes());
}
}
});
I am unsure as to fixing this problem and could use some help and suggestions. I feel it would be more helpful for myself to not be given the answer but to have some constructive criticism to lead myself to it, that being said feel free to post an a straight, working answer if that's your thing.
I think that your for loops don't belong in this code as you'll loop all the way to the end or all the way to the beginning with each button press. Instead, simply increment or decrement an index variable and use that index. I assume that you'll be using the dataArrayCurrentIndex for this functionality.
i.e.,
btnprev.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dataArrayCurrentIndex--;
// if you want to do a cyclic loop of the data
if (dataArrayCurrentIndex < 0) {
dataArrayCurrentIndex= maxIndex - 1;
}
System.out.println("backwards");
websitetxt.setText(dataArray[dataArrayCurrentIndex].getWebsitename());
usernametxt.setText(dataArray[dataArrayCurrentIndex].getUsername());
passwordtxt.setText(dataArray[dataArrayCurrentIndex].getPassword());
notestxt.setText(dataArray[dataArrayCurrentIndex].getNotes());
}
});
btnnext.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dataArrayCurrentIndex++;
// if you want to do a cyclic loop of the data
if (dataArrayCurrentIndex >= maxIndex) {
dataArrayCurrentIndex = 0;
}
// etc...
}
});
I am creating a hangman game and I was having trouble getting the jlabel that contained each character of the word to update after the right letter button has been clicked. I have been having trouble with this as I am relatively new to working with Java Guis. Below is the action listener for the letter buttons.
private class LetterHandler implements ActionListener{
private char letterVal;
public LetterHandler(char lv){
letterVal = lv;
}
//checks if clicked button has the correct value as word char
public void actionPerformed(ActionEvent e){
for(int x = 1; x <= selectedWord.wordLength; x++){
if(selectedWord.wordValue.charAt(x - 1) == letterVal){
// JLabel letterValLabel = new JLabel(String.valueOf(letterVal));
wordSpacesArray.get(x-1).setName(String.valueOf(letterVal));
wordSpacesArray.get(x-1).revalidate();
continue;
}
else{
continue;
}
}
checkWin();
triesLeft--;
triesLeftLabel.revalidate();
}
//finds if all jlabels are complete or not
public void checkWin(){
for(int x = 1; x <= wordSpacesArray.size(); x++){
String charVal;
charVal = String.valueOf(wordSpacesArray.get(x-1));
if(charVal != "?"){
System.out.println("youWon");
System.exit(0);
}
else{
break;
}
charVal = null;
}
}
}
Any help is appreciated. Let me know if you need for of the programs code Thanks :)
There are some issues with the code. However, I'll first try to focus on your current problem:
I assume that wordSpacesArray is a list that contains the JLabels of individual letters of the word.
When this ActionListener will be notified, you try to update the labels in wordSpacesArray with the letter that corresponds to this button. However, in order to update the text that is shown on a JLabel, you have to call JLabel#setText(String) and not JLabel#setName(String). So the line should be
wordSpacesArray.get(x-1).setText(String.valueOf(letterVal));
// ^ Use setText here!
Now, concerning the other issues:
As pointed out in the comments, you should use 0-based indexing
The calls to revalidate are not necessary
The use of continue in its current for is not necessary
You should not compare strings with ==, but with equals
// if(charVal != "?") { ... } // Don't do this!
if(!charVal.equals("?")){ ... } // Use this instead
But the charVal in this case will be wrong anyhow: It will be the string representation of the label, and not its contents. So you should instead obtain the text from the label like this:
// String charVal = String.valueOf(wordSpacesArray.get(x-1)); // NO!
String charVal = wordSpacesArray.get(x-1).getText(); // Yes!
The triesLeftLabel will not be updated as long as you don't call setText on it
I think the logic of the checkWin method is flawed. You print "You won" when you find the first letter that is not a question mark. I think it should print "You won" when no letter is a question mark.
You should not call System.exit(0). That's a bad practice. Let your application end normally. (In this case, maybe by just disposing the main frame, although that would also be questionable for a game...)
So in summary, the class could probably look like this:
private class LetterHandler implements ActionListener
{
private char letterVal;
public LetterHandler(char lv)
{
letterVal = lv;
}
// checks if clicked button has the correct value as word char
#Override
public void actionPerformed(ActionEvent e)
{
for (int x = 0; x < selectedWord.wordLength; x++)
{
if (selectedWord.wordValue.charAt(x) == letterVal)
{
wordSpacesArray.get(x).setText(String.valueOf(letterVal));
}
}
checkWin();
triesLeft--;
triesLeftLabel.setText(String.valueOf(triesLeft));
}
// finds if all jlabels are complete or not
public void checkWin()
{
for (int x = 0; x < wordSpacesArray.size(); x++)
{
String charVal = wordSpacesArray.get(x).getText();
if (charVal.equals("?"))
{
// There is still an incomplete label
return;
}
}
// When it reaches this line, no incomplete label was found
System.out.println("You won");
}
}