Update a JTextArea dynamically depending on users JTextField values - java

I have two JTextField which take numbers from users, like this:
nbMuscle = new JTextField();
nbMuscle.setText("2");
and this:
nbFuyard = new JTextField();
nbFuyard.setText("1");
my JTextArea() takes make an addition of both JTextField's values, like this:
nbPersonnages = new JTextArea();
int nombMusc = Integer.valueOf(nbMuscle.getText());
int nombFuy = Integer.valueOf(nbFuyard.getText());
int nbTotal = nombMusc + nombFuy;
nbPersonnages.setText(String.valueOf(nbTotal));
It works like a charm but I have one problem, if the user edit one of the JTextFields, the JTextArea value don't change. I have found on internet some notions like jTextArea.appened(String str) but it doesn't work.
Any idea of what I could do?

You have to add a DocumentListener to the underlying Document of the TextFields to listen to changes made while the program runs.
The easiest way to do this is proboably an anonymous class.
Here is the Code:
nbMuscle = new JTextField();
nbMuscle.setText("2");
nbFuyard = new JTextField();
nbFuyard.setText("1");
nbPersonnages = new JTextArea();
DocumentListener dl = new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
textChanged();
}
#Override
public void insertUpdate(DocumentEvent e) {
textChanged();
}
#Override
public void changedUpdate(DocumentEvent e) {
// This method is not called when the text of the Document changed, but if attributes of the Document changed.
}
private void textChanged() {
int nombMusc = Integer.valueOf(nbMuscle.getText());
int nombFuy = Integer.valueOf(nbFuyard.getText());
int nbTotal = nombMusc + nombFuy;
nbPersonnages.setText(String.valueOf(nbTotal));
}
};
int nombMusc = Integer.valueOf(nbMuscle.getText());
int nombFuy = Integer.valueOf(nbFuyard.getText());
int nbTotal = nombMusc + nombFuy;
nbPersonnages.setText(String.valueOf(nbTotal));
nbMuscle.getDocument().addDocumentListener(dl);
nbFuyard.getDocument().addDocumentListener(dl);

Related

Java: I want to get TextField value when I clicked a button. How to do it?

public Monster createCharacterScene() {
String name;
TextField nameTextField = new TextField();
nameTextField.setLocation(65, 50);
nameTextField.setSize(60, 10);
Button myButton = new Button("OK");
myButton.setLocation(25, 50);
myButton.setSize(30, 40);
add(myButton);
add(nameTextField);
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
name = nameTextField.getText();
}
});
return null;
}
I can't do it like this. They says "local variables referenced from an inner class must be final or effectively final". Is there alternative way to do it?
Thanks a lot.
PS. I using applet.
You cannot read this value directly in createCharacterScene() method. Because it's unknown yet. The only thing you can do is to define a eventHandler, that will be triggered, on key press.
Consumer<String> nameConsumer = text -> { /*You will handle event here*/};
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
nameConsumer.apply(nameTextField.getText());
}
});
The cheaper version would be to use a small workaround for final modifier:
final String[] nameHolder = new String[1];
myButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
nameHolder[0] = nameTextField.getText();
}
});
Here nameHolder will initially hold null, but when someone will trigger the event, it's value will be set, so you need to check if value is set or not.
make namea pseudo-final :
final String[] name = new String[1];
and access it this way :
name[0] = nameTextField.getText();

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

two textfield update each other

I try to convert data but without clicking on a button,
When I enter the data in the 1st textfield nothing happens
JTextField textC = new JTextField() ;
JTextField textF = new JTextField() ;
labelC.setText("Celsius");
labelF.setText("Fahrenheit");
ActionListener textFieldCListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String value = textC.getText();
try {
float valC = new Float(value);
float valF = valC * 1.8f + 32;
textF.setText(Float.toString(valF));
} catch (Exception exp) {
textF.setText("");
textC.setText("");
}
}};
You should add ActionListener to your JTextField object.
textC.addActionListener(textFieldCListener);
See this: What addActionListener does?
Try:
textC.addActionListener(textFieldCListener);

TextField waiting for a user input

I got a JTextfield a GetText method, and an array to store the numbers logged on the Jtextfield.
JTextField tf1 = new JTextField();
frame.add(tf1);
String tfone = tf1.getText();
int one = Integer.parseInt(tfone);
int[][] array = new int[4][5];
array[0][0] = one;
array[0][1] = otherValues...
The problem here is, that code execute all, so no wait for a user input into the JtextField. How can i make the jtextfield wait, until an user log in something. To latter on execute the Integer.Parseint ?
I can no change JtextField by another method cuz I'm working with GUI (Graphic User Environment.)
You may try adding Button and then perform it's ActionListener and then enter the input and pressing the button will load the code of doing the stuff you want.
You can use a DocumentListener:
JTextField tf1 = new JTextField();
tf1.getDocument().addDocumentListener(DocumentListener()
{
#Override
public void changedUpdate(DocumentEvent e)
{
}
#Override
public void insertUpdate(DocumentEvent e)
{
// parse here
}
#Override
public void removeUpdate(DocumentEvent e)
{
// parse here
}
});
Instead of JTextField, you can use JOptionPane to get the user input. It will display a modal form and wait until the user validates.
String tfone = JOptionPane.showInputDialog("Please enter a number");
// Now test the user input
if (tfone != null) {
int one = Integer.parseInt(tfone);
}
Here is the documentation User input with JOptionPane
Here is the code:
JTextField tf1 = new JTextField();
frame.add(tf1);
JButton b = new JButton();
b.setText("Solve");
b.setBounds(30, 140, 110, 30);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
String tfone = tf1.getText();
int one = Integer.parseInt(tfone);
int[][] array = new int[4][5];
array[0][0] = one;
array[0][1] = otherValues...
//Here you can complete the rest of functions
});
frame.add(b);
Once the user press the button the code will end its execution.

How to validate a JTextField?

How to validate a textfield to enter only 4 digits after the decimal point in Swing?
Any validation in Swing can be performed using an InputVerifier.
1. First create your own input verifier:
public class MyInputVerifier extends InputVerifier {
#Override
public boolean verify(JComponent input) {
String text = ((JTextField) input).getText();
try {
BigDecimal value = new BigDecimal(text);
return (value.scale() <= Math.abs(4));
} catch (NumberFormatException e) {
return false;
}
}
}
2. Then assign an instance of that class to your text field. (In fact any JComponent can be verified)
myTextField.setInputVerifier(new MyInputVerifier());
Of course you can also use an anonymous inner class, but if the validator is to be used on other components, too, a normal class is better.
Also have a look at the SDK documentation: JComponent#setInputVerifier.
You could probably accomplish the same with DocumentListener. All you have to do is validate the input string against the desired string pattern. In this case, the pattern seems to be one or more digits, followed by a period, AND exactly 4 digits after the decimal point. The code below demonstrates using DocumentListener to accomplish this:
public class Dummy
{
private static JTextField field = new JTextField(10);
private static JLabel errorMsg = new JLabel("Invalid input");
private static String pattern = "\\d+\\.\\d{4}";
private static JFrame frame = new JFrame();
private static JPanel panel = new JPanel();
public static void main(String[] args)
{
errorMsg.setForeground(Color.RED);
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(5, 0, 0, 5);
c.gridx = 1;
c.gridy = 0;
c.anchor = GridBagConstraints.SOUTH;
panel.add(errorMsg, c);
c.gridx = 1;
c.gridy = 1;
c.anchor = GridBagConstraints.CENTER;
panel.add(field, c);
frame.getContentPane().add(panel);
field.getDocument().addDocumentListener(new DocumentListener()
{
#Override
public void removeUpdate(DocumentEvent e)
{
validateInput();
}
#Override
public void insertUpdate(DocumentEvent e)
{
validateInput();
}
#Override
public void changedUpdate(DocumentEvent e) {} // Not needed for plain-text fields
});
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static void validateInput()
{
String text = field.getText();
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(text);
if (m.matches())
{
errorMsg.setForeground(frame.getBackground());
}
else
{
errorMsg.setForeground(Color.RED);
}
}
}
As long as the text field does not contain a valid input, the error message is shown like the image below.
Once the input is validated, the error message will not be visible.
Of course, you can replace the validation action to whatever you need. For example, you may want to display some popup when a button is clicked if the input is not valid, etc.
I threw this together to show an alternative to answer given already. There might be cases when this solution might be more suitable. There might be cases when the given answer might be more suitable. But one thing is certain, alternatives are always a good thing.

Categories