Hot questions for Using JTextField in arrays

Question:

I have simple form, and two Arrays, JLabels and JTextFeilds:

ArrayList<JLabel> jlabels = new ArrayList<JLabel>();
ArrayList<JTextField> textFields = new ArrayList<JTextField>();

I wand to add it to Frame and pack this elements correctly (please see image).

Please look at a piece of my code:

public class ProductForm extends JFrame {

private JPanel contentPane; 

public ProductForm() {

    initComponents();
    actions();      
}

public void actions() {
    setTitle("Product selection");

    setSize(600, 350);
    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setVisible(true);
}

private void initComponents() {
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);

    ArrayList<JLabel> jlabels = new ArrayList<JLabel>();
    ArrayList<JTextField> textFields = new ArrayList<JTextField>();

    //for (int a = 0; a < product.list.size(); a++) {
    for (int a = 0; a < 7; a++) {  // let say 7 for example
    jlabels.add(new javax.swing.JLabel()); 
    textFields.add(new javax.swing.JTextField());       
        for (JLabel j:jlabels) {
            contentPane.add(j);
        }
        for (JTextField f:textFields) {
            contentPane.add(f);
        }
    }             

    pack();
}

As a result, I have this content: please see image below

Please help me how to pack this elements correctly. Should I initialize it in some way?

Thank you for any help.


Answer:

You should use a proper layout. I suggest using a GridLayout.

Add this line in your initComponents() method:

contentPane.setLayout(new GridLayout(7,2)); // 7 rows, 2 columns

And change you loop to the following:

for (int a = 0; a < 7; a++) {
    jlabels.add(new javax.swing.JLabel()); 
    textFields.add(new javax.swing.JTextField());
}             

for (int i=0; i<7; i++) {
    contentPane.add(jlabels.get(i));
    contentPane.add(textFields.get(i));
}

Question:

I'm trying to build a GUI for a random name generator I built, at present I'm trying to get it to print out the names when I press a button.

However instead of a list of names all I get is "[]". I don't know much about GUI programming so I'm not sure whats going wrong here.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.nio.file.*;
import java.util.*;


public class Applet1 extends javax.swing.JApplet {

public static List<String> list = new ArrayList<String>();

public static void init(String args[])throws IOException{

      List<String> prefix = Files.readAllLines(Paths.get("prefix.txt"));
      List<String> suffix = Files.readAllLines(Paths.get("suffix.txt"));
      Random randomizer = new Random();


      String prefix2 = prefix.get(randomizer.nextInt(prefix.size()));
      String suffix2 = suffix.get(randomizer.nextInt(suffix.size()));                         
      Random ran = new Random();
      int C = ran.nextInt(5);

        for(int A=0;A <= 5;A++){
            if( C == 0 )
                list.add(prefix2 + " ");                
            else if( C>0 && C<3 )
                list.add(prefix2 + suffix2+ " ");                   
            else if( C>2 && C<6 )
                list.add(prefix2 + " " + prefix2 + suffix2+ " ");}}


public void init() {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting     code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the     default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(Applet1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(Applet1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(Applet1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                java.util.logging.Logger.getLogger(Applet1.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the applet */
    try {
        java.awt.EventQueue.invokeAndWait(new Runnable() {
            public void run() {
                initComponents();
            }
        });
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

/**
 * This method is called from within the init() method to initialize the
 * form. WARNING: Do NOT modify this code. The content of this method is
 * always regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jComboBox1 = new javax.swing.JComboBox<>();
    jButton1 = new javax.swing.JButton();
    jLabel1 = new javax.swing.JLabel();
    jTextField1 = new javax.swing.JTextField();

    setMinimumSize(new java.awt.Dimension(498, 517));

    jComboBox1.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "1", "5", "10", "15" }));

    jButton1.setText("Press");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });

    jLabel1.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
    jLabel1.setText("Select number of names and press button to Generate");

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 345, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 359, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(jButton1)
                    .addGap(18, 18, 18)
                    .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)))
            .addContainerGap(121, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jButton1)
                .addComponent(jComboBox1,     javax.swing.GroupLayout.PREFERRED_SIZE, 21,     javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGap(18, 18, 18)
            .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 389, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(33, Short.MAX_VALUE))
    );
}// </editor-fold>                        

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    jTextField1.setText(list.toString());
}                                        


// Variables declaration - do not modify                     
private javax.swing.JButton jButton1;
private javax.swing.JComboBox<String> jComboBox1;
private javax.swing.JLabel jLabel1;
private javax.swing.JTextField jTextField1;
// End of variables declaration



}

As far as I can tell either I've broken the code somewhere or TextField can't handle String Arrays.


Answer:

This method is never called:

public static void init(String args[])throws IOException{ 

As a result, the list remains empty.

Other tips/notes/questions:

  1. An applet's size is set in the HTML, so the setting of any size (minimum, size or maximum) should never be called in code.

    setMinimumSize(new java.awt.Dimension(498, 517));
    
  2. Why code an applet? If it is due to the teacher specifying it, please refer them to Why CS teachers should stop teaching Java applets.

  3. See Java Plugin support deprecated and Moving to a Plugin-Free Web.
  4. From the look of the GUI at the size of the text field, it seems it actually needs to be a multi-line text area (JTextArea).

Question:

I have an array of JTextField and when a JTextField is modified I want to have the name of the JTextField and the text.

while ((line = bufferedReader.readLine()) != null) { // 1 by 1 line of file
    if (f == 6) {
        g++;
        f = 0;
    }
    tableauDonnee[g][f] = line;
    fields[g][f] = new JTextField(tableauDonnee[g][f]);
    fields[g][f].setName(String.valueOf(g + etf));
    fields[g][f].setBounds(positionY, positionX, 160, 40);
    pan.add(fields[g][f]);
    positionY = positionY + 180;
    f++;

I can do that before add JTextField to panel

fields[g][f].addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent event) {
        textfield = fields[g][f].getText();
        nameTextfield = fields[g][f].getName();
    }
});

But it will not work because values of g and f are not good.

I'm stuck and don't know what to do.


Answer:

You can get the source of the event (ie, the text field where you pressed the Enter key) from the ActionEvent:

public void actionPerformed(ActionEvent event) 
{
    JTextField textField = (JTextField)event.getSource();
    ...
}

Also, why are you use a 2D array of text fields.

I would suggest a JTable would be the better components to use. Read the section from the Swing tutorial on How to Use Tables for more information.

Question:

I am making an assignment and I have to follow a template given to me to finish this application. I am given 2 arrays, one is JTextField[], the other one is JSlider[].

And this is where it reports the error:

for (ix = 0; ix < cc.length; ++ix)
  {
    gbc.gridy = ix;
    gbc.gridx = 0;
   JLabel label = new JLabel(cc[ix]);
   panel.add(label, gbc);


    /* create a slider, set its options, and add it to the panel */
    csld[ix] = new JSlider(0, 255);


       csld[ix].addChangeListener(new javax.swing.event.ChangeListener() {
        public void stateChanged(ChangeEvent e) {

              txt[ix].setText(Integer.toString(e.getSource())); //ERROR

        }
    });

    panel.add(csld[ix], gbc);

    gbc.gridx = 2;
    /* create a JTextField, set its options, and add it to the panel */

    txt[ix] = new JTextField();

    txt[ix].setText(Integer.toString(csld[ix].getValue()));
    System.out.println(Integer.toString(csld[ix].getValue()));
    panel.add(txt[ix], gbc);

    /* add a change listener  */

    txt[ix].addKeyListener(new KeyAdapter() {
       @Override
       public void keyReleased(KeyEvent e) {

           JTextField jtf = (JTextField)e.getSource();
           String typed = jtf.getText();

                if(!typed.matches("\\d+") || typed.length() > 3) {
                    return;
                }
                int value = Integer.parseInt(typed);
                csld[ix].setValue(value); //ERROR


       }
    });`

I am not sure why this error is being shown and no other StackOverflow answers have helped me diagnose it. I'll post the relevant code here:

//imports

public class AssignRGBSliders implements Runnable
{
  static int width = 320;
  static int height = 128;
  static String title = "RGB Sliders";
  static int FIELD_WIDTH = 3;
  static int RED = 0;
  static int GREEN = 1;
  static int BLUE = 2;
  static int MIN = 0;
  static int MAX = 1;
  static String[] cc = {"Red", "Green", "Blue"};
  static int[][] RGB_MNMX = {{0, 255}, {0, 255}, {0, 255}};

  JFrame application;
  JTextField[] txt;
  JSlider[] csld;
  JPanel colorPanel;
  int[] curColor = {0, 0, 0};

public void run()
{
  JPanel panel, panel2;
  int ix;
  GridBagConstraints gbc = new GridBagConstraints();
  gbc.anchor = GridBagConstraints.FIRST_LINE_START;
  application = new JFrame();
  application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  application.setTitle(title);
  panel = new JPanel();
  panel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
  panel.setLayout(new GridBagLayout());
  application.add(panel);

   csld = new JSlider[cc.length];
   txt = new JTextField[cc.length];

  for (ix = 0; ix < cc.length; ++ix)
  {
    gbc.gridy = ix;
    gbc.gridx = 0;
   JLabel label = new JLabel(cc[ix]);
   panel.add(label, gbc);

    gbc.gridx = 1;
    /* create a slider, set its options, and add it to the panel */
    csld[ix] = new JSlider(0, 255);


       csld[ix].addChangeListener(new javax.swing.event.ChangeListener() {
        public void stateChanged(ChangeEvent e) {
             JSlider slider = (JSlider)e.getSource();
            txt[ix].setText(Integer.toString(e.getSource()));

        }
    });

    panel.add(csld[ix], gbc);

    gbc.gridx = 2;
    /* create a JTextField, set its options, and add it to the panel */



    txt[ix] = new JTextField();

    txt[ix].setText(Integer.toString(csld[ix].getValue()));
    System.out.println(Integer.toString(csld[ix].getValue()));
    panel.add(txt[ix], gbc);

    /* add a change listener  */

    txt[ix].addKeyListener(new KeyAdapter() {
       @Override
       public void keyReleased(KeyEvent e) {

           JTextField jtf = (JTextField)e.getSource();
           String typed = jtf.getText();

                if(!typed.matches("\\d+") || typed.length() > 3) {
                    return;
                }
                int value = Integer.parseInt(typed);
                csld[ix].setValue(value);


       }
    });



       /* slider.addChangeListener(new javax.swing.event.ChangeListener() {
        public void stateChanged(ChangeEvent e) {
            jtf.setText(Integer.toString(slider.getValue()));


        }
    }); */


  }
  colorPanel = new ColorPanel();
  colorPanel.setPreferredSize(new Dimension(width / 2, height / 2));
  ++gbc.gridy;
  gbc.gridx = 0;
  gbc.gridwidth = 3;
  panel.add(colorPanel, gbc);
  application.setSize(width, height);
  application.setLocationRelativeTo(null);
  application.pack();
  application.setVisible(true);
}
public static void main(String[] args)
{
  AssignRGBSliders dp = new AssignRGBSliders();
  SwingUtilities.invokeLater(dp);
}
class SliderChange implements ChangeListener
{


  /* instance variables */


    /* constructor */
public SliderChange() {


}
    /* implement the interface */
  public void stateChanged(ChangeEvent e) {
      JSlider source = (JSlider) e.getSource();
      System.out.println("Sukurac: " + source);

  }
}
class ColorPanel extends JPanel {

  public void paint(Graphics gr) {
     super.paint(gr);
     gr.setColor(new Color(csld[0].getValue(), csld[1].getValue(), csld[2].getValue()));
     System.out.println(csld[0].getValue() + " " + csld[1].getValue() + " " + csld[2].getValue());
     gr.fillRect(0, 0, this.getWidth(), this.getHeight());
  }
}
}

Thank you in advance!


Answer:

ix is a local variable from within the context you're trying to use it, the compiler cannot determine what it's value will be at some point in the future, even if it could, it'd probably be something like cc.length - 1

My general suggestion would be to use a HashMap to map the JTextField to the JSlider

Map<JSlider, JTextField> fieldMap;
//...
fieldMap = new HashMap<>();
//...
JSlider slider = new JSlider(0, 255);
JTextField field = new JTextField(10);
fieldMap.put(slider, field);

slider.addChangeListener(new javax.swing.event.ChangeListener() {
    public void stateChanged(ChangeEvent e) {
        JSlider slider = (JSlider) e.getSource();
        JTextField field = fieldMap.get(slider);
        field.setText(Integer.toString(slider.getValue()));
    }
});

We haven't learnt/aren't allowed to use Map/HashMap

Well, in that case I'd suggest using a List of some kind instead, as it provides useful functionality to ascertain the indexOf elements

List<JTextField> fieldList;
List<JSlider> sliderList;
//...
JSlider slider = new JSlider(0, 255);
JTextField field = new JTextField(10);
fieldList.add(field);
sliderList.add(slider);

slider.addChangeListener(new javax.swing.event.ChangeListener() {
    public void stateChanged(ChangeEvent e) {
        JSlider slider = (JSlider) e.getSource();
        int index = sliderList.indexOf(slider);
        JTextField field = fieldList.get(index);
        field.setText(Integer.toString(slider.getValue()));
    }
});

The problem with this is it's easy for the Lists to come out of sync, so I prefer Map for this kind of thing

We haven't learnt/aren't allowed to use List/ArrayList

Oookaay. We do it the hard way.

Basically, you have a reference to the JSlider which triggered the event, we need to know it's index in the csld so we can look up the corresponding JTextField...

csld[ix].addChangeListener(new javax.swing.event.ChangeListener() {
    public void stateChanged(ChangeEvent e) {
        JSlider slider = (JSlider) e.getSource();
        for (int index = 0; index < csld.length; index++) {
            if (csld[index] == slider) {
                txt[index].setText(Integer.toString(slider.getValue()));
                break;
            }
        }

    }
});

Question:

I have a panel that contains different components (JLabel, JButton, JTextComponent, etc). I want to get the list of JTextField in this way:

ArrayList<JTextField> arrayTf = new ArrayList();
Component[] arrayComponent = this.getComponents();
for (Component c : arrayComponent )
{   
    if (c instanceof JTextField ) {
        arrayTf.add(c);
    }
}

But I'm not sure that's the right way . Please tell me this is the right way ? Or is there an easier way? Thank U.


Answer:

Your code is the simplest way.

However, if you want to get fancy then you can use Darryl's Swing Utils. The basic code would be:

List<JTextField> components = SwingUtils.getDescendantsOfType(JTextField.class, this, false);

The benefit of this class is that it is reusable. So you could easily get all the JButtons in one line without writing more code. Also, this code allows you to get components on the specified panel or the panel and all nested panels. There are a few other features as well.

Question:

I have two arrays of JTextField and I want to store it into another array.

JTextField[] proText, atText; 


int[] burst, arrive;

I have tried the usual way of the passing the value of the array

while(true){
            if(atText[lowerBound].getText() != " " && proText[lowerBound].getText() != " "){
                bt = proText[lowerBound].getText();
                at = atText[lowerBound].getText();
                burst[lowerBound] = Integer.parseInt(bt);
                arrive[lowerBound] =Integer.parseInt(at);
                break;
            }else 
                break;
    }

***the 'lowerBound' is being incremented when I click the button.

BTW this is dynamic, in which it adds another JTextField when I am clicking the button. The problem here is that only the last number is displayed and the rest are zero. Is there another way to get the value of JTextField?


Answer:

I read your code, the problem is simple, each time you hit one of the buttons, you re-init your arrays. Of cours the previous values will be lost.

A quick fix is to copy the values first and then store the new value in your actionPerformed method

int[] atTemp = new int[arrsize];
int[] btTemp = new int[arrsize];
for (int i = 0; i < arrsize - 1; i++) {
    atTemp[i] = at[i];
    btTemp[i] = bt[i];
}
at = atTemp;
bt = btTemp;

But if you don't know the size of your arrays then use ArrayList, then you don't have to re-init your array each time you hit the buttons.

Question:


Answer:

In java Strings are compared with equals and not ==. The reason is, strings are objects and not primitives. See What is the difference between == vs equals() in Java? for more information about == and equals()

So the if expression is wrong:

username.getText().equals(dbUser.get(i)) && password.getText().equals( dbPassword.get(i))

Question:

So I'm trying to create a large number of JTextFields and use them as nodes in a binary tree program I'm trying to make. Is there a way to create an array of JTextFields, something like:

JTextField nodes[]=new JTextField[30];

If so, how do I define or give every one of them different properties or the property I want them to have?

Thanks!


Answer:

JTextField[] fields = new JTextField[30];
for(int i = 0; i<fields.length; i++){
    fields = new JTextField();
}

//then you can access them and modify them as normal.
fields[3].setColumns(5);
fields[3].setText("apples");