Refresh data in a JLabel - java

I have a program which calculates an integer and then uses the value within a JLabel. On intital creation everything is fine with the initialized value, but when I change the value of the int within the label I can't seem to find a way to update the JLabel. The relevant code is as follows:
JLabel carbLbl;
int totCarbs = 0;
public Main() {
carbLbl = new JLabel("Total Carbs: " + totCarbs);
carbLbl.setFont(new Font("KidSans", Font.PLAIN, 38));
carbLbl.setAlignmentX(Component.RIGHT_ALIGNMENT);
void addFoodToTable() {
String[] s = new String[3];
s = (String[]) foodData.get(foodChoice.getSelectedIndex());
foodList.addRow(s);
totCarbs += Integer.parseInt(s[2]);
carbLbl.repaint();
}
}
There's obviously much more code, but it's too long to include the entire script. Is there a way I can have the label update whenever I invoke the addFoodToTable() method?

The JLabel is not "bound" to your integer variable. When you change the integer you need to update the JLabel using carbLbl.setText(String.valueOf(totCarbs))

Is there not a way to simply update the JLabel using the initial constructor parameters?
carbLbl = new JLabel("Total Carbs: " + totCarbs);
What parameters? There is only a single parameter, the String to be displayed.
The compiler concatenates the hard coded String with the value of your "totCarbs" variable to create a single String.
The compiler will essentially treat the above code like:
String text = "Total Carbs" + totCarbs;
carbLbl = new JLabel( text );
The JLabel has no idea how the String was created (ie. that a variable was used to build the string).
I understand the concept of concatenation, but I just feel like that's a workaround
It is not a work around. The API of the setText(...) method states you provide a single String. So, if you want to update the label you need to provide the entire String.

Related

setting a color value in the jlabel[] in java

While I was writing a code, I found out that you can't do setColor to the Label I assigned. It tells me to put the length and put a variableDeclaration. However, I do not know ho to do that.. How do you assign a font type or a color for "JLabel[] answerLabels;"?
JLabel[] answerLabels;
answerLabels = new JLabel[question.getAnswers().length];
answerLabels.length[new Font("PT Serif",Font.BOLD,16)];
I recommend you to learn more about arrays.
Look mate, you have an array(think of it as a list) of JLabel. Not a single JLabel
JLabel[] answerLabels;
The two square brackets[] after JLabel represent that you are creating an array, not a single JLabel.
Therefore, when you call,
answerLabels = new JLabel[question.getAnswers().length];
answerLabels.length[new Font("PT Serif",Font.BOLD,16)];
you are not referring to a JLabel but you are referring to an array. Since, array doesn't have any methods such as, setForeground() or setFont(), your program will run into an error.
So if you want to set the color or font of a particular JLabel, you have to refer to it.
To refer to that JLabel, you have to write code as follows :
answerLabels[i].setForeground(Color.RED);
Here, 'i' represents the number of JLabel you want to access. Suppose, you want to access the third JLabel, then you have to write 2 in the place of 'i' in the above line.
Why 2, why not 3? Because arrays start at 0.
Note that, the JLabel you are trying to access should be initialized before setting it's color or font by something like,
answerLabels[i] = new JLabel();
Otherwise, your program will throw NullPointerException. So, make sure to initialize the JLabel you are accessing from the array before setting it's color or font.
It looks like your trying to do something like this:
JLabel[] answerLabels = new JLabel[question.getAnswers().length];
// This will loop through all of the JLabels and set the font and color
for(int i=0; i<answerLabels.length; i++) {
answerLabels[i] = new JLabel("Text from question/answer");
answerLabels[i].setFont(new Font("PT Serif",Font.BOLD,16));
answerLabels[i].setForeground(Color.red);
}

Java - Pass JLabel to Integer

I want to pass the JLabel to Integer, The following code does not work even with Integer.valueOf() and Integer.parse()
This are the following code I've Tried:
Test 1:
JLabel life = new JLabel("204");
int x = Integer.valueOf(life).intValue();
Test 2:
JLabel life = new JLabel("204");
int x = Integer.parseInt(life);
No. You can't magically convert a Label to Integer.
However you can get the string of that label and then convert.
JLabel life = new JLabel("204");
int x = Integer.parseInt(life.getText());
Note that, you'll be succeed when there is proper text. For ex
"203", "34343" works but not "A2342"

Changing variables on button clicks - or in events in general

Introduction to the problem
It seams impossible to change a Veriable in a event (like so for example button.setOnAction(e -> { x = x+2});) and I can see why, but what if that's exactly what I need? It's actually not the first time that I needed to do that, but last time I got around it by saving the changed property directly to a file.
This time I used a really tricky trick to create a 'fake variable' by using the text in an invisibe TextField as my veriable. It works, that's not the problem, but I'd like to have a more 'elegant' salution :D
Friuts of my research
The only two salutions I could find were to either declare a Variable as a class member (which I don't want to do seeing that I already have six of them and don't want to tripple that amount) or to use seperate classes. (I found that here: How to change a variable when a button has been clicked in JavaFx )
The programm
Here is the code of my popup window (I'll spare you of the rest of my stupid programm ^^ ), I'll explain what it does after the codebox. (Note that props is a properties object and one of the mentioned class members as well as propPath (meaning I declared it at the very top of the programm so that it can be accessed from every function)):
private void createNewBuff() throws Exception {
Stage popupStage = new Stage(StageStyle.UTILITY);
popupStage.initModality(Modality.APPLICATION_MODAL);
popupStage.setTitle("Creating a new Buff");
popupStage.setMinWidth(400);
popupStage.setMinHeight(300);
GridPane layoutGP = new GridPane();
layoutGP.getColumnConstraints().addAll(
new ColumnConstraints(200), //TextField column col 0
new ColumnConstraints(10), //Gab column col 1
new ColumnConstraints(60), //tf manips column col 2
new ColumnConstraints(30), //Gab column col 3
new ColumnConstraints(80)); //Main buttons col col 4
TextField tfName = new TextField("Unknown Buff");
tfName.setPromptText("Name of the Buff, e.g. \"Unknown Buff\"");
Label lblName = new Label("Name");
layoutGP.add(tfName, 0, 0);
layoutGP.add(lblName, 2, 0);
TextField varTF = new TextField();
TextField tfEffect = new TextField();
tfEffect.setPromptText("Effect of the Buff, e.g. \"+10 LP\"");
Button btnAdd = new Button("Add");
btnAdd.setOnAction(e -> {
String input = tfEffect.getText();
String[] comps = input.split(" "); //components
if (Array.getLength(comps) == 2) {
if (input.contains("+")) {
varTF.setText(varTF.getText() + input + ";");
layoutGP.add(new Label(input), 0, 1 + Array.getLength(varTF.getText().split(";")));
} else if (input.contains("-")) {
varTF.setText(varTF.getText() + input + ";");
layoutGP.add(new Label(input), 0, 1 + Array.getLength(varTF.getText().split(";")));
}
}
});
layoutGP.add(tfEffect, 0, 1);
layoutGP.add(btnAdd, 2, 1);
Button btnDone = new Button("Done");
btnDone.setOnAction(e -> {
int buffNumber = 1;
while (props.containsKey("Buff-" + buffNumber + "-name"))
buffNumber++;
props.setProperty("Buff-" + buffNumber + "-name", tfName.getText());
props.setProperty("Buff-" + buffNumber + "-effect", varTF.getText());
try {
FileOutputStream streamOut = new FileOutputStream(propPath);
props.store(streamOut, null);
streamOut.close();
popupStage.close();
}catch (IOException someE){/*something meaningful*/}
});
btnDone.setMaxWidth(Double.MAX_VALUE);
Button btnCancel = new Button("Cancel");
btnCancel.setOnAction(e -> popupStage.close());
btnCancel.setMaxWidth(Double.MAX_VALUE);
layoutGP.add(btnDone, 4, 0);
layoutGP.add(btnCancel, 4, 1);
layoutGP.setAlignment(Pos.TOP_CENTER);
Scene popupScene = new Scene(layoutGP);
popupStage.setScene(popupScene);
popupStage.showAndWait();
}
I wanted to post a picture there of how it looks once you start it and another of how it looks after you used it, but my reputation is still to low ^^
Therefor I'll provide the links to the pictures: Befor something was done http://i.imgur.com/Wx3nIEX.png After it's used http://i.imgur.com/5QNmWP6.png
What the programm does
It's pretty strait forward actually: my main programm is a character sheet and with that popup you can add a buff to it (later I'll make it so that the effects of the buff get calculated into the values of the sheed, but one step at a time ^^ ). You can set the name of the buff you want to create ("Unknown Buff" is the standart in case you forgett to set one) and then you can simply add defferent effects by writing tem into the TextField and then pressing the 'Add' button. They will list themself top to bottom in the free space. They will also, behind the scenes, save themself as one large string into a hidden TextField to make figuring out in which line each individual Effect has to be displayed and to save it to the properties file afterwards. (and that salution with the undisplayed textfield is exactly the trick I want to remove and turn into a more 'elegant' salution)
Detailed explanaition of the code
At first the Stage is created. Then the layout is made in form of a gridpane und the column sizes are set (every second column is for spacing reasons). After that I'm creating the line for the name (the label and the textfield) and also my tricky textfield that's used as a String variable. Now I'm creating the effect textfield and add button, as well as the event for the button: at first it turns the input from the textfield into a easier to read name and splits it into it's components (at first I used tfEffect.getText() and tfEffect.getText().split(" ") inside the code below, but that was really messy) now I have if statements to verify it and make sure that the Effect is in the right format (that format beeing the amount a certain stat is raised or lowerd, consisting of either a plus or a minus symbol at the beginning and a number after that; followed by a space and then the index of the stat (I haven't been able to implement verifying if the typed thing actually is a valid stat, maybe that'll be content of a future question ;D )). After verifying the programm it adds the effect below all the others. If you're done and happy with you're buff you can click the Done button, it will first look up how many Buffs already exist, then assign the new on a number and save it all to the properties file. The cancel button with of course just cancel it and at the bottom I'm setting the scene and calling the stage.
What I'm hoping for with this question
Now I think you have a pretty clear idea of what I need to do and why I couldn't find a better salution then using a hidden TextField as a variable and I hope it's because I'm a beginner and not because there actually is no better way of doing it ^^
Also if you actually read all of this you may found one or two things I can improve besides that, but that would be the special bonus ;D

adding a field name as a method parameter

I have a Swing form where I want to detect edited field data so I can update the data via a web service. There doesn't seem to be a simple way to do this as there are a plethora of medium to complex code examples for this, most of which are over my head! However, I think I found a simple solution that will fit my needs and I wanted to run it by the group for input / suggestions. FYI: it may not matter but know that I am using NetBeans so things like listeners are auto-coded by the app.
Step 1: When I load the form, I am saving all the data to a Class array so I know the starting point of the each field. Here is the code for that load:
public void coSetSearchDetail(String coDetail){
String[] text;
System.out.println("SingleCO Result: "+ coDetail);
text = coDetail.split("\\|");
txtName_CoDetail.setText(text[1]);
txtAddr_CoDetail.setText(text[2]);
txtAddr2_CoDetail.setText(text[3]);
txtCity_CoDetail.setText(text[4]);
txtState_CoDetail.setText(text[5]);
txtZip_CoDetail.setText(text[6]);
stringarrayCoDetails[0] = text[0];
stringarrayCoDetails[1] = text[1];
stringarrayCoDetails[2] = text[2];
stringarrayCoDetails[3] = text[3];
stringarrayCoDetails[4] = text[4];
stringarrayCoDetails[5] = text[5];
stringarrayCoDetails[6] = text[6];
java.awt.CardLayout card = (java.awt.CardLayout)pnlMain.getLayout();
card.show(pnlMain, "pnlCoDetail");
}
Step 2: I created a Lost Focus event listener for one field and am testing the current value of the field against the array:
private void txtName_CoDetailFocusLost(java.awt.event.FocusEvent evt) {
if (!(txtName_CoDetail.getText().equals(stringarrayCoDetails[1]))){
createEditBorder();
}
}
private void createEditBorder (){
Border border = BorderFactory.createLineBorder(Color.RED, 2);
txtName_CoDetail.setBorder(border);
}
Besides the general question of "is this an OK approach?", I would like to be able to pass the field name to the createEditBorder method so the listener for each data field can call it and I have one method for "edited text" formatting.

How to have a unique identifier of a Jlabel?

I am new to java swing and I am creatin a Jlabel as follows :
JLabel Lport = new JLabel ("Port: ");
final JTextField Tport = new JTextField ("1883", 10);
what i want to do is to get the name of the label as a string because i want to use it in a switch-case, so i need to get the label name or a unique identifier of that label, some thing like an ID as it exists in Android, i tried the method ",getAction.toString", ".getName" but none of them displayed the name of the labe, which is according to the code posted is "Port: ". please see my attempts below:
if ( (isIPReady(Tip)) && (isPortReady(Tport)) ) {
Thread mqttThread = new Thread(MQTTRunnable, MQTT_THREAD);
mqttThread.start();
System.out.println("Action: " + Tport.get); //here i do not know which method to use
setViewEnableState(Bconnect, true);
}
The short answer is to use JLabel#getText which will return the text which is displayed by the JLabel.
An alternative could be to store your own key-value pair into the different JComponent instances. Each JComponent allows to put and retrieve client properties. A copy-paste from the class javadoc:
Support for component-specific properties. With the
putClientProperty(java.lang.Object, java.lang.Object) and
getClientProperty(java.lang.Object) methods, you can associate
name-object pairs with any object that descends from JComponent.
This would allow you to write:
private static final String ID_KEY = "MyUniqueIDKey";
JLabel label = new JLabel( "Whatever" );
label.putClientProperty( ID_KEY, "labelName" );
and then later on
String labelName = (String) label.getClientProperty( ID_KEY );
Note that this works with any JComponent, including JLabel and JTextField instances like the ones you are using in your code.
JLabel's name is different than the text it displays. To get the text from a JLabel, use getText().
You mention you want the name of the label but in your example you're calling a get on your textfield.
This applies to both a textfield and a label anyway.
That constructor sets the initial text that will display in the text field (or label).
If you want to set a name, you must first set it using setName() then use getName().

Categories

Resources