I am making a real time graph with values that come in via serial communication. I have the data coming in called my "Celsius" value. I am displaying that on the GUI in a JLabel, so the value constantly changes. The problem I am having is I want to have buttons that can change the value in the JLabel to Fahrenheit or back to Celsius. So right now, I have my actionPerformed calling the updateTemp() method so it will update the JLabel right away when the program beings. I have the code below for the 3 methods I think need to be changed around.
public void actionPerformed(final ActionEvent e) {
updateTempC();
final Double n = serial.x;
series.addOrUpdate(new Millisecond(), n);
Object source = e.getSource();
if (e.getSource() == buttonF){
degree.setText("degrees F");
updateTempF();
}
if (e.getSource() == buttonC){
degree.setText("degrees C");
updateTempC();
}
}
public void updateTempF(){
int step1;
int step2;
int step3;
String indata = serial.temp;
int temp = Integer.parseInt(indata);
step1 = temp*9;
step2 = step1/5;
step3 = step2 + 32;
String indata1 = Integer.toString(step3);
this.realtime.setText(indata1);
}
public void updateTempC(){
String indata = serial.temp;
this.realtime.setText(indata);
}
Right now when I press the JButton to change to Fahrenheit, it changes for a second but then goes right back to displaying Celsius because the graph is updated every second and the actionPerformed will go right back to calling the updateTempC(). I am wondering how, when I hit the button for Fahr. or Cels., it will change for the rest of the time. THanks
You should have a variable like boolean fahrenheitTemp. When buttonF is clicked, fahrenheitTemp will be set to true. When buttonC is clicked, fahrenheitTemp will be set to false. If fahrenheitTemp is true, call updateTempF(), else call updateTempC(). (Also, you have a Object source variable, but you never use it.)
Try modifying your actionPerformed(ActionEvent) to something like this:
boolean fahrenheitTemp = false;
public void actionPerformed(final ActionEvent e) {
if (fahrenheitTemp) {
updateTempF();
} else {
updateTempC();
}
final Double n = serial.x;
series.addOrUpdate(new Millisecond(), n);
Object source = e.getSource();
if (source == buttonF) {
degree.setText("degrees F");
fahrenheitTemp = true;
updateTempF();
} else if (source == buttonC) {
degree.setText("degrees C");
fahrenheitTemp = false;
updateTempC();
}
}
Related
I'm developing an application in Java to help me land my first job as a junior developer. It's a chess game with a GUI that both human players click on from the same machine.
When it's, say, white's turn to move, the application calls white's getMove(Interface interaction) method until a valid MoveAttempt is returned. Here's the getMove(Interface interaction) method of HumanPlayer:
public MoveAttempt getMove(Interface interaction) {
while(!interaction.selectionMade()) {
}
byte pieceFile = interaction.getPenultimateFile();
byte pieceRank = interaction.getPenultimateRank();
byte toFile = interaction.getUltimateFile();
byte toRank = interaction.getUltimateRank();
return new MoveAttempt(pieceFile, pieceRank, toFile, toRank, getIsWhite());
}
penultimateFile, penultimateRank, ultimateFile and ultimateRank are supposed to store the file (column) and rank (row) of the last two chess tiles clicked. This is achieved through this actionPerformed(ActionEvent event) which Interface has because it implements ActionListener
public void actionPerformed(ActionEvent event) {
LocalizedButton button = (LocalizedButton) event.getSource();
if(penultimateFile == -1) {
penultimateFile = button.getFile();
penultimateRank = button.getRank();
}
else {
ultimateFile = button.getFile();
ultimateRank = button.getRank();
}
}
and by calling this method before each call to getMove(Interface interaction)
public void resetClicks() {
penultimateFile = -1;
penultimateRank = -1;
ultimateFile = -1;
ultimateRank = -1;
}
So the idea is that a move attempt is not made until someone has clicked on two chess squares which is why I have a while loop indefinitely calling selectionMade():
public boolean selectionMade() {
return penultimateFile != -1 && penultimateRank != -1 && ultimateFile != -1 && ultimateRank != -1;
}
This didn't work---pieces didn't move---so in an attempt to see what was happening I put this print statement
System.out.println(interaction.getPenultimateFile() + ", " +
interaction.getPenultimateRank() + ", " +
interaction.getUltimateFile() + ", " +
interaction.getUltimateRank());
into the while loop to see what was going on and now it works---pieces move---except I may have encountered times in which it didn't work but I last I tried I couldn't get it to fail.
I don't want to print anything to the console; what should I do in lieu of having this while loop?
Edit: Putting boolean lol = 0 just above the loop and lol = !lol in the loop doesn't allow the code to work. Neither does calling doNothing().
Edit: Here's the source code: https://github.com/JosephBGriffith/Chess
Right now only the pawns work because I have other bugs that I need to fix. En passant works except the opponent piece doesn't get eliminated.
I would invert the control, so that the UI pushes moves to the game, rather than the game trying to pull moves from the UI.
So your game class might have:
class Game {
boolean move(int fromFile, int fromRank, int toFile, int toRank) { ... }
...
}
If the move wasn't legal (e.g. if it was the other player's turn) then move returns false and the move doesn't occur. That is, the internal state of the Game is unchanged.
And your actionPerformed method becomes:
public void actionPerformed(ActionEvent event) {
LocalizedButton button = (LocalizedButton) event.getSource();
if(penultimateFile == -1) {
penultimateFile = button.getFile();
penultimateRank = button.getRank();
}
else {
game.move(penultimateFile, penultimateRank, button.getFile(), button.getRank());
penultimateFile = -1;
}
}
You could use the return value of move to provide some feedback to the user if the move is illegal.
Something to note about this suggestion is that move is executed on the Swing event thread. In theory this is bad practice, although unless your move method is very slow it won't matter.
Read https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html and consider whether you want to use invokeLater.
When I press the button the first time it's supposed to display a message, but the next time I am to press it it should do it's normal use.
private void jButton1ActionPerformed (java.awt.event.ActionEven evt) {
jTextArea1.setText(jTextArea1.getText()+"Let the battle begin!\n");
Basically that is what I want it to do at first click, as well as:
if (jProgressBar1.getValue() > 0) {
if (publicInt.rndNum() > 90)
}
etc, etc..
EDIT:
This is what I did to make it work, thanks to a commenter.
if (publicInt.startPhrase() == true) {
jTextArea1.setText("The battle has begun!\n");
publicInt.sp = false;
}
You should use a boolean, let's say pressed, which will be false, and after pressing the button you set if true... the code will be something like:
boolean pressed = false;
private void jButton1ActionPerformed (java.awt.event.ActionEven evt) {
if (!pressed) {
jTextArea1.setText(jTextArea1.getText()+"Let the battle begin!\n");
pressed = true;
}
please see my attached code below and then my question at the end.
class events extends JFrame{
private JLabel label;
private JButton button;
public events() {
setLayout(new FlowLayout());
button = new JButton("Click for text");
add(button);
label = new JLabel("");
add(label);
event e = new event();
button.addActionListener(e);
}
public class event implements ActionListener {
public void actionPerformed(ActionEvent e) {
int x = 0;
if (x == 0) {
label.setText("the new label");
System.out
.println("setting x to 0 and label to display a label");
x = 1;
System.out.println(x);
} else {
label.setText("newerer label");
System.out.println("i reached the else segment");
x = 0;
System.out.println(x);
}
}
}
public static void main(String args[]) {
events gui = new events();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setTitle("Events Test");
gui.setSize(300, 100);
gui.setVisible(true);
}
}
Background: I am learning java and attempting to understand a concept. With this program I was attempting to create a small gui with a button that when clicked would assign a JLabel the String value of "the new label." I wanted to use that same button however to change the label to "newerer label" if clicked a second time and back again if clicked a third. I attempted to do this using an If/ Else statement with a variable x to hold essentially a state of 1 or 0. At the end of each portion of the If/Else i change the state of x to either 1 or 0 appropriately. When attempting to run the program in eclipse however, I have run into some kind of error. I assigned a system.out.println to each portion of the If/Else in an attempt to see how the program switches between the two states but it appears that my else statement is never reached.
Questions:
Is an If/Else statement appropriate to perform such a simple 2 state switch?
Is there a more appropriate way to do this? (i know about switch statements but opted for this as it was only a two state project).
What did I do wrong and why is my Else path never achieved when the state should be 1?
Thank you for your responses,
Pano
Your variable "x" must be declared as a class member.
public class event implements ActionListener{
private int x = 0;
public void actionPerformed(ActionEvent e){
if(x == 0){
label.setText("the new label");
System.out.println("setting x to 0 and label to display a label");
x = 1;
System.out.println(x);
}
else {
label.setText("newerer label");
System.out.println("i reached the else segment");
x = 0;
System.out.println(x);
}
}
}
You are initializing x every time the action listener gets called, so x is always 0. Move x somewhere else, possibly declare it as a class member.
Yes, I personally would use an if/else statement here, although if you are likely to add more states a switch statement may be appropriate, but I think given you have more than 1 line of code in the if/else blocks I would keep it as if/else as it has better readability in my experience.
I guess my answer to 1 covers this!
The reason your else block isn't being reached is that your x variable is only in scope (only exists) inside that method. As soon as you leave the method the value is no longer in scope so as far as your code in concerned it no longer exists. The code P Lalonde posted shows the correct way: having the variable as a member variable (object scope). Read more about member variable scope here: http://docs.oracle.com/javase/tutorial/java/javaOO/variables.html
If you are just looking for a switch of state you could actually do something like:
if( label.getText().equals("the new label") ) {
label.setText("newerer label");
} else {
label.setText("the new label");
}
I've been trying for a while to get a JButton I have to return a string and I have it working to an extent however it only works when i'm using the System.out.println() method.
My Relevant Code:
private String answer;
public void inputDataButton(JButton inButton)
{
inButton.addActionListener(new Action1());
}
public String returnAnswer()
{
return answer;
}
private void fileAnswer(String inString)
{
answer = new String(inString);
}
public class Action1 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String sub = JOptionPane.showInputDialog("Input The Date");
fileAnswer(sub);
}
}
With my Main controlling it:
public class test
{
protected static JTextField text;
public static void main(String[] args)
{
javaUI base = new javaUI("Date Killer", 800, 800);
JLabel label = new JLabel("Place Holder");
base.addLabel(label, 1, 0, false);
JButton button = new JButton("Press Here");
base.addButton(button, 0, 0, false);
String str = "EMPTY";
base.inputDataButton(button);
while (str == "EMPTY")
{
str = base.returnAnswer();
}
System.out.println(str + " TEST");
label.setText(str + "SETTED");
}
}
JavaUI is simply another class with simplifies the entire JFrame and Jpanel setup for Labels, Buttons etc.
Anyways, heres my problem. In the main class, in the while statement, str is successfully set to the string if I have a System.out.println() statement directly after.
This obviously makes quite a mess of the terminal as it repeates "EMPTY" 100+ times until the button is pressed.
However if I remove that statement, nothing is obviously printed out, but str is never set to the str either.
I've been messing around with this for quite a while (New to all java UI stuff, mainly just worked in the calculations part of things) and I've yet to find a working solution that doesn't make a mess of my terminal. Thanks for all the Help!!!
Cail
1) It's a little strange to use a loop to "wait" for the action to happen. You can watch your cpu usage and it could be dead if it loops forever.
2) Also, the method will return no matter whether your button is clicked -- Before the action happens, the method returns a null string according to your code. And in your main method, str == "EMPTY" soon becomes false after the first round. Then you'll see "null TEST" on your screen.
Try to put the code after while loop into actionPerformed method or fileAnswer method and delete the loop:
public void actionPerformed(ActionEvent e)
{
String sub = JOptionPane.showInputDialog("Input The Date");
System.out.println(sub + " TEST");
label.setText(sub + "SETTED");
}
Also, I am not sure why you call answer = new String(inString). If you want to assign it to another variable, you only need to call answer = inString since String is unmodifiable. And in this case, you don't to do this.
my problem ist that my while loop just runs one time when I run it. Here is my code. I would be very thankful if someone would check it and maybe look for other faults (i'm new at programming java!)
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Program {
boolean exit;
JFrame frame;
JPanel panel;
JTextField title;
JButton start;
JButton stop;
long x;
public Program() {
frame = new JFrame("Überlast your PC");
panel = new JPanel();
title = new JTextField("Überlast your PC v1.0");
start = new JButton("Start");
stop = new JButton("Stop");
x = 1;
exit = false;
stop.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e) {
exit = true;
}});
start.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e) {
panel.remove(start);
panel.add(stop);
frame.repaint();
frame.revalidate();
start.setForeground(Color.red);
while(x <= 9223372036854775807L) {
System.out.println(x * x);
x++;
if (exit = true) {
break;
}
}
}});
frame.add(panel);
panel.add(title);
panel.add(start);
frame.setVisible(true);
frame.setSize(150,100);
title.setEditable(false);
start.setForeground(Color.green);
stop.setForeground(Color.red);
}
}
if(exit = true) {
break;
}
should be
if(exit == true) {
break;
}
Or even simpler, just use
if(exit){
break;
}
exit=true assigns true to exit, thus the if condition is true thus it breaks outta of the loop.
As #jlordo pointed, even after fixing the error its an infinite loop.
if(exit = true)
This is the first problem. The above if condition will always be true. You need to do comparison instead of assignment. In fact you should not do comparison for boolean variable. Just use: -
if (exit)
Secondly, you are not changing your exit anywhere in your while loop, so, it doesn't make sense for using it as a exit condition.
And you don't need to hard code the value of Long.MAX_VALUE. You already have that constant defined. Now, even if you get through that problem of if, you will face the problem of infinite loop. See below how: -
// Your below while loop is `infinite`
// every long value will satisfy this condition
while(x <= Long.MAX_VALUE) { // Don't hard code max long value
System.out.println(x * x);
x++;
// You are not changing `exit` anywhere, so this check is absurd.
if (exit) {
break;
}
}
What probably you want: -
Probably you want to run your loop infinitely, until your exit value if false. In that case, just use while (true). And change the value of exit somewhere in your loop.
In fact, if you are using exit as exit criteria, I would change your while loop to: -
while (exit) {
System.out.println(x * x);
if (someCondition) {
exit = false;
}
}
you are using
if(exit = true) {
instead of
if(exit == true) {
or even better
if (exit) {
But when you fix it, you will have an infinite loop, because all long values are smaller than 9223372036854775807, which is the the highest value long can have.
It is because of this line:
if(exit = true)
You are assigning true to exit here. Use == for comparing values:
if(exit == true)
And in the case of boolean values, you don't need to compare it to true at all. Write it like this:
if(exit)
if (exit = true) will set the value exit to true. You need to compare using ==