Hot questions for Using JTextField in for loop

Question:


Answer:

I'm just guessing here, but it looks as if all those JTextFields have been generated for you by an IDE using some graphical drag'n'drop editor(?)

If not, then the answer to your question is, don't write your code that way!

If you did use an IDE to create your UI, every time you drop a JTextField onto your Swing application the IDE is writing some code for you that generates a JTextField Object.

In the NetBeans IDE it does something like this:

// Variables declaration - do not modify                     
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
//etc...
// End of variables declaration     

and elsewhere in a folded section of code marked "Generated Code" there'll be something like:

jTextField1 = new javax.swing.JTextField();
jTextField2 = new javax.swing.JTextField();

jTextField1.setText("jTextField1");
jTextField2.setText("jTextField2");

// plus some layout code that positions your controls...

The GUI isn't smart enough to know that all those JTextFields are somehow related and you would like to conveniently be able to loop through them. If you write the code yourself, instead of dragging and dropping the controls it's as easy as:

private JTextField[] jTextFields = new JTextField[35]; 

// initialise and set properties for all those JTextFields...
jTextFields[0] = new JTextField();
/// etc ...

Where 35 would be the number of JTextFields you need.

Alternatively, you could still use your IDE to create your GUI with drag'n'drop like you're used to doing and then put references to ALL those IDE generated controls into an array for easy iteration later:

private JTextField[] jTextFields = new JTextField[35];
jTextFields[0] = jTextField1;
jTextFields[1] = jTextField2;
// etc...

If you would rather use an ArrayList or similar container that is just as simple:

private List<JTextField> jTextFields = new ArrayList<>();
jTextFields.add( jTextField1 );
jTextFields.add( jTextField2 );
// etc...

In the case of Netbeans, the IDE defies all programming conventions and starts numbering controls at 1 instead of 0, so watch out for off-by-one errors when you're putting jTextField1 into jTextFields[0] and so on. Better still, give all your controls meaningful names!

I guess the bottom line is don't be afraid to write the code yourself rather than getting your IDE to generate it for you, and there's also no harm in putting your objects into containers if that is convenient to you.

Here's the relevant FAQ entry for NetBeans regarding arrays of GUI Controls that explains that you need to code it by hand.

If you're using another IDE, please refer to the relevant documentation to see if the IDE supports a way of creating Arrays or Collections of controls or whether or not you have to write the code yourself.

Question:

I have a JFrame in which the user shall enter 2 numbers and the powers of that number should be displayed step-by-step.

This is what I have so far:

This is what it should look like:

The problem is this line:

txt3.setText(output);

because it just writes one line on the JFrame.

How can I add the output on the JFrame like in the image above?

Here's the code:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class PotenzFrame extends JFrame {

    private Toolkit toolkit;

    public PotenzFrame() {
        setSize(620, 500);

        toolkit = getToolkit();
        Dimension size = toolkit.getScreenSize();
        setLocation((size.width - getWidth())/2, (size.height -getHeight())/2);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        getContentPane().add(panel);

        panel.setLayout(null);

        JLabel label = new JLabel("Potenzen");
        // label.setPreferredSize(new Dimension(50, 50));
        label.setBounds(80,0,80,80);

        JLabel lbl1 = new JLabel("zahl");
        lbl1.setBounds(30,70,80,30);

        JLabel lbl2 = new JLabel("ende");
        lbl2.setBounds(30,120,110,30);

        JLabel lbl3 = new JLabel("Potenzen:");
        lbl3.setBounds(300,150,80,30);

        final JTextField txt1 = new JTextField(5);
        txt1.setBounds(145,70,50,30);
        txt1.setText("0");
        final JTextField txt2 = new JTextField(5);
        txt2.setBounds(145,120,50,30);
        txt2.setText("0");
        final JTextField txt3 = new JTextField(5);
        txt3.setBounds(300,200,200,200);

        JButton comp = new JButton("Potenzen berechnen");
        comp.setBounds(20, 400, 200, 30);
        comp.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                int a1 = Integer.parseInt(txt1.getText());
                int a2 = Integer.parseInt(txt2.getText());
                String output;
                int multiplied;

                for(int i = 1; i <= a2; i++){
                    multiplied = (int) Math.pow(a1, i);
                    output = a1 + " hoch " + i + " ist " + multiplied;
                    txt3.setText(output);
                    System.out.println(output);
                }
            }
        });

        panel.add(label);
        panel.add(lbl1);
        panel.add(lbl2);
        panel.add(lbl3);
        panel.add(txt1);
        panel.add(txt2);
        panel.add(txt3);
        panel.add(comp);
    }

    public static void main(String[] args) {
        PotenzFrame buttons = new PotenzFrame();
        buttons.setVisible(true);
    }
}

I tried the following, but it didn't work either:

for(int i = 1; i <= a2; i++){
    multiplied = (int) Math.pow(a1, i);
    output = a1 + " hoch " + i + " ist " + multiplied;
    JTextField txt = new JTextField(i+4);
    txt.setText(output);
    panel.add(txt);
    System.out.println(output);
}

Answer:

Change your JTextField to a JTextArea to be able to have multiple lines of text, rather then just one line of text.

final JTextArea txt3 = new JTextArea();
txt3.setBounds(300,200,200,200);

Then in your loop, change txt3.setText(output) to txt3.append(output + "\n").

for(int i = 1; i <= a2; i++){
    multiplied = (int) Math.pow(a1, i);
    output = a1 + " hoch " + i + " ist " + multiplied;
    txt3.append(output + "\n");
    System.out.println(output);
}

append() adds text onto your TextArea rather then replacing the text with setText() and "\n" is adding a new line after you append the text.

Question:

I have the following list of items in volstextfield which I then pass onto createGUI. I want to create a list of JTextFields with the names vol1HH1,vol1HH2. I get an error Incompatible types: JTextField cannot be converted to volstextfield, please can someone help?

public enum volstextfield {
    vol1HH1, vol1HH2
}

public void createGUI() {
    for (volstextfield direction : EnumSet.allOf(volstextfield.class)) {
        System.out.println(direction);
        direction = new JTextField(5); //i get an error here incompatible types: JTextField cannot be converted to volstextfield
    }
}

Answer:

Your direction variable is of enum type. You cannot assign JTextField to enum. Try like

JTextField textfield = new JTextField(direction.getName());

Or use

JTextField textfield = new JTextField();
textfield.setName(direction.getName());

Question:

I want to display the missing file names in a text field.

How to store and display the for loop contents in a JTextField?

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JFileChooser;
import javax.swing.JTextField;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

public class CheckFiles extends JPanel {

    public String FILENAME = "f:\\branch_report.txt";
    protected ArrayList listFromFile;
    protected ArrayList listFromDir = new ArrayList();

    protected void getListFromFile() {
        listFromFile = new ArrayList();
        BufferedReader is;
        try {
            is = new BufferedReader(new FileReader(FILENAME));
            String line;
            while ((line = is.readLine()) != null) {
                listFromFile.add(line);
            }
        } catch (FileNotFoundException e) {
            System.err.println("Can't open file list file.");
            return;
        } catch (IOException e) {
            System.err.println("Error reading file list");
            return;
        }
    }

    public void getListFromDirectory() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
        fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            File selectedFile = fileChooser.getSelectedFile();
            System.out.println("Selected file: " + selectedFile.getAbsolutePath());
            listFromDir = new ArrayList();
            String[] l = new java.io.File(selectedFile.getAbsolutePath()).list();
            for (int i = 0; i < l.length; i++) {
                listFromDir.add(l[i]);
            }
        } else {
            JOptionPane.showMessageDialog(null, "No files selected");
        }
    }

    public void reportMissingFiles() {
        for (int i = 0; i < listFromFile.size(); i++) {
            if (!listFromDir.contains(listFromFile.get(i))) {
                JOptionPane.showMessageDialog(null, listFromFile.get(i), "File not found", JOptionPane.ERROR_MESSAGE);  // want to display the missing files in text field
            }
        }
        JFrame frame = new JFrame("Files Not Found");
//frame.getContentPane().add(frame,"Center");
        frame.setSize(800, 600);
        frame.setVisible(true);
        JTextField text = new JTextField();
        text.getSelectedFile().getName();
        frame.add(text);
        text.setVisible(true);
//final JLabel label = new JLabel();
//frame.add(label);
//label.setVisible(true);
    }

    public static void main(String[] argv) {
        CheckFiles cf = new CheckFiles();
        System.out.println("CheckFiles starting.");
        cf.getListFromFile();
        cf.getListFromDirectory();
        cf.reportMissingFiles();
        System.out.println("CheckFiles done.");
    }
}

Answer:

You can replace reportMissingFiles() with below implementation:

public void reportMissingFiles() {
        // Set for containing missing files.
        Set<String> notFoundFileSet = new HashSet<>();
        for (int i = 0; i < listFromFile.size(); i++) {
            if (!listFromDir.contains(listFromFile.get(i))) {
                JOptionPane.showMessageDialog(null, listFromFile.get(i),
                        "File not found", JOptionPane.ERROR_MESSAGE);
                // add missing files in set
                notFoundFileSet.add(listFromFile.get(i).toString());
            }
        }
        JFrame frame = new JFrame("Files Not Found");
        frame.setSize(800, 600);
        frame.setVisible(true);
        JTextField text = new JTextField();
        // Stringify Set of missing file 
        text.setText(notFoundFileSet.toString());
        frame.add(text);
        text.setVisible(true);
    }

I have used Set<String> for containig missing files and the added string version of that Set to JTextField. You can simply use StringBuilder as well to format file names according to your need.

Note: Always prefer Generics in your code, eg instead of using ArrayList listFromFile you should have used ArrayList<String> listFromFile to make your program type safe.

Question:

My first question here. Already got a lot of help but now I don't know how to do.

My code:

package view;

import javax.swing.*;

public class OptionPlayerNames {

JPanel playerPanel = new JPanel();
JTextField playerNames = new JTextField();

public OptionPlayerNames() {
    for (int i = 0; i < 8; i++) {

// JTextField playerNames = new JTextField();

playerPanel.add(new JLabel("Player " + (i + 1))); playerPanel.add(playerNames); } playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.Y_AXIS)); playerPanel.add(Box.createHorizontalStrut(5)); } public JPanel getPanel(){ return playerPanel; } public String getPlayerNames() { return playerNames.getText(); }

I want to have 8 Jlabels with just under it 8 JTextFields for user input. Then get the text of the textfields. Now I get only 1 text from 1 textField. Off course I only add 1 field.

When I put the JTextField under the for loop I get what I want but how to I get the text from all the JTextFields then? playerNames is then not known in the getter.

Thank you for your help.


Answer:

You can do as follows, creating a Listof JTextField:

JPanel playerPanel = new JPanel();
List<JTextField> playerNames = new ArrayList<JTextField>();

public OptionPlayerNames() {
    for (int i = 0; i < 8; i++) {
        JTextField playerName = new JTextField();

        playerPanel.add(new JLabel("Player " + (i + 1)));
        playerPanel.add(playerName);

        playerNames.add(playerName);
    }
    playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.Y_AXIS));
    playerPanel.add(Box.createHorizontalStrut(5));
}

public JPanel getPanel() {
    return playerPanel;
}

public String getPlayerNames() {
    String output = "";
    // Compound you exit from the playerNames List
    // Or better, return a List of String
    return output;
}