Java - Listen to variable change - java

First of all i am brand new to Java : /
I have been trying to solve this problem on my own for about 2 days now but cant get around it the problem is i am trying to implement a variable change listener. I have tried without successes to implement Observer and Observable to my project but whit no successes at best i came up by wrapping some elements of the code in to while loops but that well fails.
Any how this is my class and if you look at it i have some global variables defined after the constructor i need to listen for a change in all of those global variables if one changes i would like to execute a method.
I have been told JavaFX has methods that can listen to variables can someone confirm this.
Anyhow thanks for help in advance.
public class Tower_Controller {
public Tower_Controller() {
}
//Global variables
String isSelected = null;
int hasModules = 0;
int cap_s = 0;
int cpu_s = 0;
int cap = 0;
int cpu = 0;
int shield = 0;
int armor = 0;
double em = 00.00;
double th = 00.00;
double ki = 00.00;
double ex = 00.00;
public void invoke() {
Invoke_GUI runnable = new Invoke_GUI();
final JLabel tower_name = runnable.tower_name;
final JComboBox tower_select = runnable.tower_select;
final JTree module_browser = runnable.module_browser;
final JTree selected_modules = runnable.selected_modules;
final JProgressBar cap_bar = runnable.cap_bar;
final JProgressBar cpu_bar = runnable.cpu_bar;
final JLabel em_res = runnable.em;
final JLabel th_res = runnable.thermic;
final JLabel ki_res = runnable.kinetic;
final JLabel ex_res = runnable.explosive;
tower_select.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (isSelected != null) {
Events evt = new Events();
evt.towerSelected(isSelected);
} else {
tower_name.setText(tower_select.getSelectedItem().toString());
isSelected = tower_name.toString();
}
}
});
removeTower(tower_name);
runnable.setVisible(true);
}
public void updateValues(final JProgressBar cap_bar, final JProgressBar cpu_bar, final JLabel em_res,
final JLabel th_res, final JLabel ki_res, final JLabel ex_res){
cap_bar.setMaximum(cap);
cap_bar.setString(cap_s + " / " + cap);
cap_bar.setStringPainted(true);
cpu_bar.setMaximum(cpu);
cpu_bar.setString(cpu_s + " / " + cpu);
cpu_bar.setStringPainted(true);
String em_v = String.valueOf(em);
em_res.setText(em_v);
String th_v = String.valueOf(th);
th_res.setText(th_v);
String ki_v = String.valueOf(ki);
ki_res.setText(ki_v);
String ex_v = String.valueOf(ex);
ex_res.setText(ex_v);
}
public void updateList(final ArrayList<String> nodes, final JTree selected_modules) {
DefaultMutableTreeNode nod = new DefaultMutableTreeNode();
for (int i = 0; i < nodes.size(); i++) {
nod.add(new DefaultMutableTreeNode(nodes.get(i)));
}
selected_modules.setModel(new DefaultTreeModel(nod));
}
public void removeTower(final JLabel tower_name) {
tower_name.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
if (hasModules == 1 & isSelected != null) {
Events evt = new Events();
evt.towerHasModules();
} else if (isSelected == null) {
} else {
tower_name.setText("No Control Tower selected");
isSelected = null;
}
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
});
}
public JLabel setTowerName(JLabel a, String name) {
a.setText(name);
return a;
}
}

The general procedure to be notified of a change to a variable is as follows:
First, make the variables private.
Create two methods for each variable, one which sets its value to an argument (often called setX(), where X is the variable name), the other which retrieves its value (getX())
Everywhere you need to read or set the variable, call the methods instead.
In the setX() method, call notifyObserver() on your Observers, in a loop.
And there you go! Now every time the variable is changed, registered Observers are notified. The key part of this solution is that the variables have to be private, so that no code can set their values without going through the setX() methods.

Related

How to display in Java jTextField the data from Arduino RFID

I have this problem in my system where when I scan the card on RFID, it displays the UID using System.out.println(str); but when I passed it thru jTextField.setText(str);, it doesn't display the UID. Also, the weird part is, when i try to System.out.println(jTextField.getText()); it display the UID.
Can someone help me with this problem? And explain if possible why does it happen?
This is my main class:
public class IDSystem {
public static String devicePortName = "Arduino Uno";
public static SerialPort arduinoPort = null;
public static InputStream arduinoStream = null;
public static int PACKET_SIZE_IN_BYTES = 8;
public static void main(String[] args) {
int len = SerialPort.getCommPorts().length;
SerialPort serialPorts[] = new SerialPort[len];
serialPorts = SerialPort.getCommPorts();
for (int i = 0; i < len; i++) {
String portName = serialPorts[i].getDescriptivePortName();
if (portName.contains(devicePortName)) {
arduinoPort = serialPorts[i];
arduinoPort.openPort();
break;
}
}
PacketListener listener = new PacketListener();
arduinoPort.addDataListener(listener);
Login l = new Login();
l.setVisible(true);
}
}
This is my PacketListener class:
public final class PacketListener implements SerialPortPacketListener {
String ex = "/";
String id;
#Override
public int getPacketSize() {
return IDSystem.PACKET_SIZE_IN_BYTES;
}
#Override
public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_RECEIVED;
}
#Override
public void serialEvent(SerialPortEvent event) {
byte[] newData = event.getReceivedData();
String str = new String(newData).split("\n", 2)[0].replaceAll("\\s+", "");
int byteSize = 0;
try {
byteSize = str.getBytes("UTF-8").length;
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(PacketListener.class.getName()).log(Level.SEVERE, null, ex);
}
if (byteSize == IDSystem.PACKET_SIZE_IN_BYTES) {
System.out.println(str);
Login l = new Login();
l.jTextField.setText(l.jTextField.getText() + str);
System.out.println(l.jTextField.getText());
}
}
}
I'm assuming that your jtextfield is an instance of javax.swing.JTextField.
If it doesn't display the text you specified, check that:
You are setting the text on the correct JTextField instance,
You are adding the correct JTextField instance to a container (JPanel, etc...) that is being displayed.
As a last resort, if it's because you added the JTextField instance to its container after the container was already showing on the screen, try container.validate(); container.repaint(); .
If you could show the code for your Login class and how your jtextfield is being added to a container and displayed on the screen that would help in diagnosing the problem.

JAVA - Trying to use a variable from inside an actionperformed outside the class

I am trying to access the (double) percentage variable outside my actionPerformed while retaining the changes that it goes through.
it is a drop down menu, and an ok button you press. once you press it, it calculates a value for percentage, which then i want to use later on in the program.
Here is a snippet of the code:
btn.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent e){
String currentCountry = (String)cb.getSelectedItem();
double percentage = 0.00;
if(currentCountry.equals("Brazil") || currentCountry.equals("Argentina")) {
cb2.removeAllItems();
for(int i = 0; i < choicesSouthAmerica.length; i++) {
cb2.addItem(choicesSouthAmerica[i]);
}
}
else {
cb2.removeAllItems();
for(int i = 0; i < choicesEurope.length; i++) {
cb2.addItem(choicesEurope[i]);
}
}
btn.setEnabled(false);
btn2.setEnabled(true);
if(currentCountry.equals("Brazil") || currentCountry.equals("Argentina")){
percentage = 1/5;
System.out.println(percentage);
}
else{
percentage = 1/8;
System.out.println(percentage);
}
}
}
);
Thank you kindly
you could use the putClientProperty(Object,Object) and getClientProperty(Object) functions as follow :
JButton btn = new JButton("Ok");
btn.putClientProperty("percentage",1.0);//or whatever initial value
btn.addActionListener(arg0 -> {
JButton source = (JButton) arg0.getSource();
double per = (double)source.getClientProperty("percentage");
per = (double)10/8;
source.putClientProperty("percentage",per);
});
double percentage = (double)btn.getClientProperty("percentage");//or use it in any other object that has access to the btn object
Sadly Java doesn't support closures, so you can not modify variables outside the scope of an anonymous class. But you can access final variables, so in principle you can do something like this:
class Percentage {
double p;
}
final Percentage p = new Percentage();
btn.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
// [...]
p.p = 1/5;
// [...]
}
}
);
Then you can access the updated percentage via p.p outside of your anonymous class. (Btw. is it really a "percentage" or in fact a ratio?)
But this doesn't seem very idiomatic for Java, so the clean solution is probably just to make a proper class with a private instance variable and a getter and use this instead of the anonymous class.
I think what you actually need is just a static field (it can have whatever access modifiers you want). So something like this I think should work:
public class Test {
static double d = 0;
public static void main(String[] args) {
JButton b = new JButton("ASDF");
b.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
d = 5;
}
});
}
}

Trouble determining how to make my calculator calculate properly

This is probably the nth time you've received a newbie question regarding calculators, but I just can't figure it out, been working on it for two to three days. The way I have built my calculator at the moment does not suffice and I know I have to start calculating at the time I press the '=' button, but I simply can't figure out how to do so. Due to this reason I have reverted back to my original calculator code, in which it calculates when I press an operation button (like '+') which didn't work, but I was hoping that that would allow me to properly build on it. Here's the code:
package rekenmachine;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.util.*;
public class Rekenmachine extends JFrame
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(300,500);
frame.setLocation(800,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Rekenmachine");
RekenPaneel rekenpaneel = new RekenPaneel();
frame.setContentPane(rekenpaneel);
frame.setVisible(true);
}
private static int getal, totaalGetal;
private boolean optellen, aftrekken, vermenigvuldigen, delen;
public int Optellen(int getal)
{
reset();
optellen = true;
totaalGetal += getal;
getal = 0;
return totaalGetal;
}
public int Aftrekken(int getal)
{
reset();
aftrekken = true;
totaalGetal -= getal;
getal = 0;
return totaalGetal;
}
public int Delen(int getal)
{
reset();
delen = true;
totaalGetal /= getal;
getal = 0;
return totaalGetal;
}
public int Vermenigvuldigen(int getal)
{
reset();
vermenigvuldigen = true;
totaalGetal *= getal;
getal = 0;
return totaalGetal;
}
public int getGetal()
{
return getal;
}
public int getTotaalGetal()
{
return totaalGetal;
}
public void reset()
{
optellen = false;
aftrekken = false;
delen = false;
vermenigvuldigen = false;
getal = 0;
totaalGetal = 0;
}
}
class RekenPaneel extends JPanel
{
JButton knop0, knop1, knop2, knop3, knop4, knop5, knop6, knop7, knop8, knop9,
knopOptel, knopAftrek, knopVermenigvuldigen, knopDelen, knopUitkomst,
knopWissen;
JTextField invoerVak;
JPanel textPaneel, knopPaneel, logoPaneel;
Rekenmachine rekenmachine;
public RekenPaneel()
{
rekenmachine = new Rekenmachine();
setLayout(new BorderLayout());
textPaneel = new JPanel();
knopPaneel = new JPanel();
logoPaneel = new JPanel();
textPaneel.setLayout(new FlowLayout());
knopPaneel.setLayout(new GridLayout(4,4));
logoPaneel.setLayout(new FlowLayout());
Border rand = BorderFactory.createEmptyBorder(10, 10, 10, 10);
knop0 = new JButton("0");
knop0.addActionListener(new knop0Handler());
knop1 = new JButton("1");
knop1.addActionListener(new knop1Handler());
knop2 = new JButton("2");
knop2.addActionListener(new knop2Handler());
knop3 = new JButton("3");
knop3.addActionListener(new knop3Handler());
knop4 = new JButton("4");
knop4.addActionListener(new knop4Handler());
knop5 = new JButton("5");
knop5.addActionListener(new knop5Handler());
knop6 = new JButton("6");
knop6.addActionListener(new knop6Handler());
knop7 = new JButton("7");
knop7.addActionListener(new knop7Handler());
knop8 = new JButton("8");
knop8.addActionListener(new knop8Handler());
knop9 = new JButton("9");
knop9.addActionListener(new knop9Handler());
knopOptel = new JButton("+");
knopOptel.addActionListener(new knopOptelHandler());
knopAftrek = new JButton("-");
knopAftrek.addActionListener(new knopAftrekHandler());
knopVermenigvuldigen = new JButton("*");
knopVermenigvuldigen.addActionListener(new knopVermenigvuldigenHandler());
knopDelen = new JButton("/");
knopDelen.addActionListener(new knopDelenHandler());
knopUitkomst = new JButton("=");
knopUitkomst.addActionListener(new knopUitkomstHandler());
knopWissen = new JButton("C");
knopWissen.addActionListener(new knopWissenHandler());
invoerVak = new JTextField(25);
invoerVak.setHorizontalAlignment(invoerVak.RIGHT);
invoerVak.setEditable(false);
invoerVak.setBackground(Color.WHITE);
textPaneel.add(invoerVak);
knopPaneel.add(knop7);
knopPaneel.add(knop8);
knopPaneel.add(knop9);
knopPaneel.add(knopDelen);
knopPaneel.add(knop4);
knopPaneel.add(knop5);
knopPaneel.add(knop6);
knopPaneel.add(knopVermenigvuldigen);
knopPaneel.add(knop1);
knopPaneel.add(knop2);
knopPaneel.add(knop3);
knopPaneel.add(knopOptel);
knopPaneel.add(knop0);
knopPaneel.add(knopWissen);
knopPaneel.add(knopUitkomst);
knopPaneel.add(knopAftrek);
add(textPaneel, BorderLayout.NORTH);
add(knopPaneel, BorderLayout.CENTER);
add(logoPaneel, BorderLayout.SOUTH);
}
class knop0Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText(invoerVak.getText() + "0");
}
}
class knop1Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText(invoerVak.getText() + "1");
}
}
class knop2Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText(invoerVak.getText() + "2");
}
}
class knop3Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText(invoerVak.getText() + "3");
}
}
class knop4Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText(invoerVak.getText() + "4");
}
}
class knop5Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText(invoerVak.getText() + "5");
}
}
class knop6Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText(invoerVak.getText() + "6");
}
}
class knop7Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText(invoerVak.getText() + "7");
}
}
class knop8Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText(invoerVak.getText() + "8");
}
}
class knop9Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText(invoerVak.getText() + "9");
}
}
class knopOptelHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String invoer = invoerVak.getText();
int invoerGetal = Integer.parseInt(invoer);
rekenmachine.Optellen(invoerGetal);
invoerVak.setText("");
}
}
class knopAftrekHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String invoer = invoerVak.getText();
int invoerGetal = Integer.parseInt(invoer);
rekenmachine.Aftrekken(invoerGetal);
invoerVak.setText("");
}
}
class knopVermenigvuldigenHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String invoer = invoerVak.getText();
int invoerGetal = Integer.parseInt(invoer);
rekenmachine.Vermenigvuldigen(invoerGetal);
invoerVak.setText("");
}
}
class knopDelenHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String invoer = invoerVak.getText();
int invoerGetal = Integer.parseInt(invoer);
rekenmachine.Delen(invoerGetal);
invoerVak.setText("");
}
}
class knopUitkomstHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
invoerVak.setText("" + rekenmachine.getTotaalGetal());
rekenmachine.reset();
}
}
class knopWissenHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
rekenmachine.reset();
invoerVak.setText("");
}
}
}
What it basically does is look like a calculator, all buttons work, yet the way it calculates is way off, if at all. I think what I need to do is save a number, when I press + it should add the next number, if I press - it should substract the next number, if I press * it should multiply by the next number and if I press / it should divide by the next number, then when I press = it should show the result, yet I have no idea how to do that.
Should it be done with an arraylist? If so, how could I properly save the result? I mean, using it with two numbers isn't that hard, you just save two numbers and do something with them, then show the result, but a person doesn't always use just two numbers.
To explain the problem I'm having more clearly: for example, when I enter '50' and then press '+' it SHOULD convert "50" to getal = 50 and start the Optellen method, then totaalGetal should become 50, it then empties the textfield. If I then add '3', it should say 53 when I press '=' yet it still shows 50 if I'm lucky. To solve that I assume I have to make the calculation WHEN I press '=' but I don't know how to save/calculate numbers before having done that.
Can anybody tell me what to do before I've lost all my hair? :P
When you click on the +, you're calling this:
knopOptel.addActionListener((ActionEvent e) ->
{
String invoer = invoerVak.getText();
int invoerGetal = Integer.parseInt(invoer);
rekenmachine.addition(invoerGetal);
invoerVak.setText("");
});
But when you click on +, you're not doing the calculation yet! What you should be doing is:
The user type a number
The user click on + (for example)
In your ActionListener, you read the number on the screen, you store it in getal, you clear the screen, and you set your boolean optel to true
The user types another number
The user click on equal
In your equal Listener, you read the number you read the number on the screen, and depending on the flag (optel in the example), you calculate the result
you display the result
So indeed, the calculation is done when you press equal.
A small code example:
knopOptel.addActionListener((ActionEvent e) ->
{
int invoerGetal = Integer.parseInt(invoerVak.getText()); // get the number
calculate(invoerGetal); //sets totalNumber to what it should be by looking at the flags
invoerVak.setText(totalNumber); // we write the temporary result
additionFlag = true; // next number must be added
});
And your calculate function should just be something like:
private void calculate(int aInvoerGetal) {
if (addition)
totalNumber += aInvoerGetal;
else if (substract)
totalNumber -= aInvoerGetal;
else if (divide)
totalNumber /= aInvoerGetal;
else if (multiply)
totalNumber *= aInvoerGetal;
resetFlags();
}
TO GO FURTHER:
Now, if you want to support multiple caculations (5+5+5+3), it's easy. When you click on +, -, *, /, you first call the equalActionListener.
This way, you get this kind of sequence:
5, + // ==> equal called ==> 5 (because the flags are all false) ==> flag + to true
10, + // ==> equal called ==> 15 because 5 in memory and + flag was on. + flag goes off, then on again (because you pressed + again)
4, = // ==> equal called ==> 19
When developing something, you have to think first how you want to solve a problem. Work from there by designing a solution. If you have a programmable solution, implement it. The UI may come later. That's a core skill that a developer should have.
1) You want to have a calculator that support +, -, / and *. The output should be shown if "=" is clicked.
2) Think with classes. That concept may be new for you, but you will discover later from. Your main class that does the calculations is Rekenmachine. (From a design perspective, it should be a stand alone class, but that's not important now). You need to separate it from your UI layer.
Your class supports the actions that you have implemented with the UI. That's good. But I also see things that shouldn't be there
public int Vermenigvuldigen(int getal)
{
reset(); // reset the calculator ?
vermenigvuldigen = true; // purpose ?
totaalGetal *= getal;
getal = 0; // resetting argument getal ?
return totaalGetal;
}
Here, I'm not sure why you're calling reset() because what it does is
public void reset()
{
optellen = false;
aftrekken = false;
delen = false;
vermenigvuldigen = false;
getal = 0;
totaalGetal = 0;
}
When reading the above method, you see that it resets the value that you tried to add on. Of course your calculation would go wrong because you're erasing previous data... resetting everything back to initial state. I also don't understand the setting to "true" or "false" on the actions. Perhaps for the UI? That is not required.
Make it simple:
When creating Rekenmachine, set the variable totaalGetal to 0 as default. That variable holds the value of your calculations performed so far. That's the start. When you have an addition, use
public void add(int getal) {
totaalGetal+= getal; // means totaalGetal = totaalGetal + getal.
}
Before calling add() you have to parse the string to an integer. This can be done in the button action:
class knop1Handler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
// get input
String input = invoerVak.getText();
// convert
int converted = convertToInt(input);
// instruct myRekenmachine to add the value
myRekenmachine.add(converted);
}
}
Important note ... use concise naming ... "knop1handler" is difficult to read. Use "addButtonHandler" to indicate that this class handles the add button.
convertToInt is a method that reads in a String and returns with an integer. You have to implement that yourself. myRekenmachine is an instance of your Rekenmachine class.
This above is for addition. Implement the same for other operands. If you want to adjust the UI, do that in the handler.
Now, when you press =, just return the totaalGetal value.
PS: Not sure, but ask if you are allowed to write names in English. My native language is Dutch, but during my CS courses, I am allowed to program completely in English. Please try to ask it because English is the main language in IT world if you're aiming for a career in IT.
Wesley, did you think about what you wanted the calculator to do before you started coding? e.g. would it support brackets, sin/cos, memory. Did you think about how logically these functions would work and then think of how they could be implemented in Java? A few flow charts and some pesudocode can go a long way when you're starting out in a new language if only to help you comprehend what it is you are trying to do.
BTW I know it's tempting to start with the GUI code and move into the logic of the application but it is usually better to start with the logic and then move onto the GUI. You can hard code the values for inputs and see if the functionaly behaves as expected and then introduce parameters with values passed in from else where.
EDIT
I think I know why your + key is not working. The reset() method is setting getal and totalGetal to 0 before adding them. 0 + 0 is 0.
knopOptel = new JButton("+");
knopOptel.addActionListener(new knopOptelHandler());
class knopOptelHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String invoer = invoerVak.getText();
int invoerGetal = Integer.parseInt(invoer);
rekenmachine.Optellen(invoerGetal);
invoerVak.setText("");
}
}
public int Optellen(int getal)
{
reset();
public void reset()
{
optellen = false;
aftrekken = false;
delen = false;
vermenigvuldigen = false;
getal = 0;
totaalGetal = 0;
}
optellen = true;
totaalGetal += getal;
getal = 0;
return totaalGetal;
}

JAVA: EventHandler for dynamically created button

I have programatically created input fields on my jframe. Now I want to create a save button that will save ALL the results to a database. I am a beginner with JAVA thus not familiar. I have a entity object for the results, and a controler to save to database. This is not the problem but my problem is writing the event handler.
private void jComboBoxSurveyFocusLost(java.awt.event.FocusEvent evt) {
// TODO add your handling code here:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PTSchemePU");
EntityManager em = emf.createEntityManager();
jPanelTests.setLayout(new GridLayout(0, 1));
Query surveyQ = em.createNamedQuery("Survey.findBySurveyDescription");
surveyQ.setParameter("surveyDescription", jComboBoxSurvey.getSelectedItem().toString());
Survey survey = (Survey) surveyQ.getSingleResult();
int testset_ID = survey.getTestset();
Query testsetQ = em.createNamedQuery("TestsetV.findByTestSet");
testsetQ.setParameter("testsetid", testset_ID);
List<TestsetV> TestSetList = (List<TestsetV>)testsetQ.getResultList();
totalTests = TestSetList.size();
JPanel[] myPanel = new JPanel[totalTests];
JLabel[] myTestID = new JLabel[totalTests];
JTextField [] mytextfield = new JTextField[totalTests];
JComboBox[] myCombo = new JComboBox[totalTests];
JCheckBox[] myNotReturn = new JCheckBox[totalTests];
JCheckBox[] myNotEval = new JCheckBox[totalTests];
JComboBox[] myReason = new JComboBox[totalTests];
JButton[] mySave = new JButton[totalTests];
jLabelTestcount.setText(Integer.toString(totalTests));
jLabelToberesulted.setText(Integer.toString(totalTests));
for (int tst=0; tst< TestSetList.size(); tst++) {
myPanel[tst] = new JPanel();
myTestID[tst] = new JLabel();
mytextfield[tst] = new JTextField();
myNotReturn[tst] = new JCheckBox("Not Returned");
myNotEval[tst] = new JCheckBox("Not Evaluated");
myReason[tst] = new JComboBox();
mySave[tst] = new JButton("Save");
Query qR = em.createNamedQuery("Lookups.findByLookupType");
qR.setParameter("lookupType","REAS");
java.util.List<Lookups> reasonList = (java.util.List<Lookups>)qR.getResultList();
for (int i = 0 ; i < reasonList.size(); i++) {
Lookups lu = reasonList.get(i);
myReason[tst].addItem(lu.getLookupDescription());
}
myPanel[tst].setLayout(new SpringLayout());
int rows =1;
int cols = 5;
myPanel[tst].setSize(10, 10);
myPanel[tst].setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
myPanel[tst].setVisible(true);
jPanelTests.add(myPanel[tst]);
mytextfield[tst].setSize(10, 10);
myNotReturn[tst].setName("No Return");
myNotEval[tst].setName("Not Evauated");
JLabel testName = new JLabel(TestSetList.get(tst).getTestDesctiption());
myPanel[tst].add(new JLabel(Integer.toString(TestSetList.get(tst).getTestsId())));
myPanel[tst].add(testName);
switch (TestSetList.get(tst).getTestSetup()){
case "TEXT" : {
myPanel[tst].add(mytextfield[tst]);
break;
}
case "COMB" : {
Query q = em.createNamedQuery("Lookups.findByLookupType");
q.setParameter("lookupType",TestSetList.get(tst).getLookup() );
java.util.List<Lookups> lookupList = (java.util.List<Lookups>)q.getResultList();
for (int i = 0 ; i < lookupList.size(); i++) {
Lookups lu = lookupList.get(i);
cb.addItem(lu.getLookupCode());
}
myPanel[tst].add(cb);
break;
}
case "SPIN" : {
myPanel[tst].add(sp);
break;
}
} // end switch
myPanel[tst].add(myNotReturn[tst]);
myPanel[tst].add(myNotEval[tst]);
myPanel[tst].add(myReason[tst]);
myPanel[tst].add(mySave[tst]);
SpringUtilities.makeCompactGrid(myPanel[tst], 1, myPanel[tst].getComponentCount(),6,6,6,6);
}
pack();
jPanelTests.setVisible(true);
}
I then created a event handeler when the panel loses focus
myPanel[tst].addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void focusLost(FocusEvent e) {
myResults[tst].setResultValue(mytextfield[tst].getText());
}
});
But now I get a error (local variables refferenced from an inner classmust be final of effectivly final) on the line myResults[tst].setResultValue(mytextfield[tst].getText());
How can I reference to the value entered in the jTextField/JComboBox/jSpinner
Thanks
Your counter variable tst is not final (meaning no final keyword is used), nor effectively final (meaning it is modified), and as such, it cannot be referensed from an inner class - in your case an instance of FocusListener.
You cannot mark tst as final, as you modify it - but you can create a new variable in the body of the loop.
Note that effecively final concept is new to Java8, in earlier versions you had to be explicit and add final keyword to all local variables accessed from inner class.
Study the example below:
public class TestFinalVariables {
public static void main(String[] args) {
String effectivelyFinal = "aaa";
for (int tst=0; tst< 10; ++tst) {
final int j = tst; //explicit final not necessary here
new Runnable() {
#Override
public void run() {
System.out.println(effectivelyFinal);
System.out.println(j);
//System.out.println(tst); Won't compile
}
}.run();
}
}
}

JLabel won't change after setText in Java

I got a JLabel Scoresp1 which I want to change using Scoresp1.setText(mijnScore + "");. But the text on the JLabel stays the same.
I got a class Dobbelsteen which looks like this:
public class Dobbelsteen extends Spel {
...
public void aantalOgen(int aantalogen) {
oudepositie = huidigepositie;
nieuwepositie = (huidigepositie + aantalOgen);
if (nieuwepositie == eindronde) {
System.out.println("Speler Piet heeft de ronde gewonnen!");
updateUI();
}
}
}
Which calls updateUI which is in the class Spel
public class Spel {
...
public void updateUI() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ikWin = true;
while(ikWin){
mijnScore = mijnScore+1;
Scoresp1.setText(mijnScore + "");
System.out.println("mijnScore" + mijnScore);
ikWin = false;
positie = 0;
}
}
});
}
...
}
Scoresp1 is declared as public JLabel Scoresp1;. If I use String l = Scoresp1.getText(); I get the right value, but the JLabel doesn't get updated visually.
I've looked at some of you code, and my first concern (other than an over-use of static variables) is that you're using inheritance inappropriately and because of this are calling methods on the wrong reference.
Many classes inherit from Spel but don't appear that they should be doing this. For instance, your Dobbelsteen class inherits from Spel, and yet it also has a separate Spel instance -- why? What Spel object is currently visible at the time this code is run? I doubt it is the one that Dobbelsteen extends. Because of this, I think that you're trying to changing the JLabel that is held by the the Dobbelsteen class, but it is not the "Spel" object that is currently visualized. To properly change the visualized JLabel, you'll need a valid reference to the currently visualized Spel object that holds it, and call the appropriate public method on that class.
In all, you might want to re-write this project from the ground up, with a goal of separating out your model (the data) from the view (the GUI), and with an eye towards good OOP principles.
Edit 1:
This may only be a bandaid, but what if you got your Spel reference passed to you in Dobbelsteen's constructor, something like this (changes noted with !! comments: //!!):
//!! public class Dobbelsteen extends Spel {
public class Dobbelsteen { //!!
int dobbelsteen;
int nieuwepositie;
int nieuwepositie2;
public static String newPos;
public static String newPos2;
int oudepositie;
int oudepositie2;
int huidigepositie = Spel.positie;
// int huidigepositie2 = Spel.positie2;
int aantalOgen = Spel.aantalogen;
int aantalOgen2 = Spel.aantalogen2;
static boolean heeftgewonnen = false;
// !! Spel spiel = new Spel();
Spel spiel; // !!
// !!
public Dobbelsteen(Spel spiel) {
this.spiel = spiel;
}
public void aantalOgen(int aantalogen) {
oudepositie = huidigepositie;
nieuwepositie = (huidigepositie + aantalOgen);
if (nieuwepositie == Spel.eindronde) { //!!
System.out.println("Speler Piet heeft de ronde gewonnen!");
spiel.updateUI(); //!! ****** here in particular ******
} else if (nieuwepositie > Spel.eindronde) {
Spel.positie = huidigepositie; //!!
spiel.output.setText("Je hebt teveel gegooid"); //!!
spiel.output.setForeground(Color.red); //!!
} else {
Spel.oudpositie = oudepositie; //!!
Spel.positie = nieuwepositie; //!!
newPos = String.valueOf(nieuwepositie);
if (SpelHost.host) {
SpelHost.verstuurPositie("Positie" + newPos);
} else if (SpelClient.client) {
SpelClient.verstuurPositie("Positie" + newPos);
}
}
}
}
And call it like so:
class GooiDobbelsteen extends MouseAdapter {
#Override
public void mouseClicked(MouseEvent e) {
aanBeurt = false;
dobbelsteen = new Random();
aantalogen = dobbelsteen.nextInt(6) + 1;
aantalOog = String.valueOf(aantalogen);
Dobbelsteen dobbel = new Dobbelsteen(Spel.this); // !!
dobbel.aantalOgen(aantalogen);
use
public void updateUI() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ikWin = true;
while(ikWin){
mijnScore = mijnScore+1;
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
Scoresp1.setText(mijnScore + "");
}
});
System.out.println("mijnScore" + mijnScore);
ikWin = false;
positie = 0;
}
}
});
}
to have a test
Add a Scoresp1.repaint() to the end of your while loop.

Categories