【问题标题】:JTextField in a loop of slider listener滑块侦听器循环中的 JTextField
【发布时间】:2018-03-15 19:55:25
【问题描述】:

我是 Java 编程的初学者,但遇到了一个问题。我的目标是关联滑块,它给了我图形的顶点数量,同时创建图片上的坐标的 JFieldText 字段:

我的尝试导致了我创建这些字段的问题,但是尽管在 GridLayout 中取 2 并且当我减少顶点的值时,字段却没有。这是我的代码示例:

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

    }

【问题讨论】:

  • 使用 JTable 并更改行数
  • 是否可以像使用 JTextFields 一样在运行程序时更改 JTables 中的值?我的项目也需要它。
  • 是的,当然可以。一种方法是调用模型的getRowCount(...)方法

标签: java swing user-interface listener


【解决方案1】:

你可以...

使用某种List - 它提供了动态大小的对象容器的概念,而不是使用数组。这样,您就可以根据JSlider 的新值确定是否需要在List 中添加或删除项目。

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

}

所以,它非常基本,它只是将字段对的数量与所需数量进行比较,并相应地增加或缩小 List。

至于GridLayout,其实只需要设置一次...

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

来自JavaDocs

参数:
rows - 行数,值为零的意思 任意数量的行。
cols - 列,值为零 表示任意数量的列。

但是,就我个人而言,我很想使用GridBagLayout,但这就是我

因为我必须测试逻辑......

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

        }
    }
}

或者你可以...

使用JTable,这可能更简单、更易于管理 - 有关详细信息,请参阅How to use tables

【讨论】:

    【解决方案2】:

    如果您必须使用 JTextFields,则在重新添加新的 JTextFields 之前,首先删除侦听器中的所有 JTextFields。您可以使用GridLayout(0, 2),因为这意味着 2 列和可变行。

    可能更好:使用 JTable 并简单地更改行数。

    【讨论】:

    • 好的,gridLayout 帮了我很多,但我仍然无法删除 JTextFields,我不知道该怎么做,或者我不明白你想告诉我什么。你能扩展一下吗?
    猜你喜欢
    • 2018-12-21
    • 2013-03-23
    • 2021-05-23
    • 2015-05-10
    • 2011-04-26
    • 2020-07-30
    • 1970-01-01
    相关资源
    最近更新 更多