简体   繁体   中英

JTextField in a loop of slider listener

I'm beginner in java programing and I encounter a problem. My aim is to relate slider, which give me number of figure's vertices, with simultaneously creating JFieldText fields of coordinates as it is on picture: 在此处输入图片说明

My attempts led me to the problem where I'm creating those fields but there are to many cols despite of taking 2 in GridLayout and when I'm decreasing the value of vertices, fields doesn't. Here is my sample of code:

    int vertices = 3;
    slider.addChangeListener(new SpinerListener());

    class SpinerListener implements ChangeListener {
       public void stateChanged(ChangeEvent arg0) {
            vertices = slider.getValue();
            right.setLayout(new GridLayout(vertices, 2));//right is my panel        
            for (int i = 0; i < vertices*2; i++) {
                fields[i] = new JTextField("Field " + i);
                right.add(fields[i]);
            }
            right.removeAll();
       }

    }

You could...

Use some kind of List - which provides a concept of dynamically sizeable container of objects, instead of using an array. With this, you could then determine if you need to add or remove items from the List depending on the new value of the JSlider .

private List<JTextField[]> fields = new ArrayList<>(3);

//....

class SpinerListener implements ChangeListener {

    public void stateChanged(ChangeEvent arg0) {
        vertices = slider.getValue();

        if (vertices < fields.size()) {
            List<JTextField[]> oldFields = fields.subList(vertices + 1, fields.size());
            for (JTextField[] pairs : oldFields) {
                for (JTextField field : pairs) {
                    right.remove(field);
                }
            }
            fields.removeAll(oldFields);
            right.revalidate();
            right.repaint();
        } else if (vertices > fields.size()) {
            int count = (vertices - fields.size());
            System.out.println("Add " + count + " new fields");
            for (int index = 0; index < count; index++) {
                JTextField[] pairs = new JTextField[2];
                pairs[0] = new JTextField(4);
                pairs[1] = new JTextField(4);

                for (JTextField field : pairs) {
                    right.add(field);
                }

                fields.add(pairs);
            }
            right.revalidate();
            right.repaint();
        }
    }

}

So, it's pretty basic, it simply compares the number of field pairs to the desired amount and grows or shrinks the List accordingly.

As to the GridLayout , you actually only need to set it once...

right = new JPanel(new GridLayout(0, 2));

From the JavaDocs


rows - the rows, with the value zero meaning any number of rows.
cols - the columns, with the value zero meaning any number of columns.

But, personally, I'd be tempted to use a GridBagLayout , but that's me

And because I had to test the logic...

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JSlider slider;
        private int vertices = 3;
        private List<JTextField[]> fields = new ArrayList<>(3);

        private JPanel right;

        public TestPane() {
            setLayout(new BorderLayout());
            right = new JPanel(new GridLayout(0, 2));
            add(new JScrollPane(right));

            slider = new JSlider();
            slider.addChangeListener(new SpinerListener());
            slider.setValue(vertices);

            add(slider, BorderLayout.NORTH);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        class SpinerListener implements ChangeListener {

            public void stateChanged(ChangeEvent arg0) {
                vertices = slider.getValue();

                if (vertices < fields.size()) {
                    List<JTextField[]> oldFields = fields.subList(vertices + 1, fields.size());
                    for (JTextField[] pairs : oldFields) {
                        for (JTextField field : pairs) {
                            right.remove(field);
                        }
                    }
                    fields.removeAll(oldFields);
                    right.revalidate();
                    right.repaint();
                } else if (vertices > fields.size()) {
                    int count = (vertices - fields.size());
                    System.out.println("Add " + count + " new fields");
                    for (int index = 0; index < count; index++) {
                        JTextField[] pairs = new JTextField[2];
                        pairs[0] = new JTextField(4);
                        pairs[1] = new JTextField(4);

                        for (JTextField field : pairs) {
                            right.add(field);
                        }

                        fields.add(pairs);
                    }
                    right.revalidate();
                    right.repaint();
                }
            }

        }
    }
}

Or you could...

Use a JTable , which may be simpler and easier to manage - See How to use tables for more details

If you must use JTextFields, then remove all the JTextFields first in the listener before re-adding the new JTextFields. You can use GridLayout(0, 2) for all since this means 2 columns and variable rows.

Possibly better: use a JTable and simply change the number of rows.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM