【问题标题】:Loop through nested field in JPanel循环遍历 JPanel 中的嵌套字段
【发布时间】:2020-01-20 21:50:42
【问题描述】:

我已经制作了 2 个类,第一个是制作 JTextFields,第二个是把这些 JTextFields 注入到 JPanel 中。我正在尝试将 .setText 设置为每个 JTextField 但很简单

    for (Field f: fields) {
    f.setValue("my text");
    }

不起作用 - 它仅将文本设置为一个 JPanel 中的 JTextFields。由于每个 JTextField 都有唯一的 fieldID,您能告诉我如何为它们设置文本(setValue)吗?这些值需要在循环之外设置,使用 ActionListener。

public class Field {

    JTextField field = new JTextField();
    static int fieldID = 0;
    private String text;
    public Field() {
        fieldID++;
    }

    public String getValue() {
        return field.getText();
    }

    public void setValue(String text) {
        field.setText(text);
    }
} 

public class Frame extends JFrame {

public Frame() {
    Field[] fields = new Field[9];
    JPanel[] corePane = new JPanel[9];
    JPanel frontPane = new JPanel();
    frontPane.setLayout(new GridLayout(3, 3));

    for (int i = 0; i < corePane.length; i++) {
        corePane[i] = new JPanel();
        for (int j = 0; j < 9; j++) {
            fields[j] = new Field();
            corePane[i].add(fields[j].field);
        }
        corePane[i].setLayout(new GridLayout(3, 3));
        frontPane.add(corePane[i]);
    }

    setLayout(new BorderLayout());
    setSize(300, 300);
    getContentPane().add(frontPane, BorderLayout.CENTER);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
}

public static void main(String args[]) {
    SwingUtilities.invokeLater(Frame::new);
}
}

【问题讨论】:

  • 所以,您的fields 可能需要是一个二维数组,例如Field[][] fields = new Field[9][9];。这样,您可以访问给定面板(第一维)的字段(第二维),即fields[pane][field]。显然,在您的for-loop 中,您需要正确初始化字段的数组,例如fields[I] = new Field[9];
  • 似乎文本字段应该被一个JTable 替换(但是关于它们的目的没有足够的细节让我确定)。一般提示: 1) 为了尽快获得更好的帮助,edit 添加minimal reproducible exampleShort, Self Contained, Correct Example。 2)public class Frame extends JFrame { 这里没有很好的案例来扩展JFrame。只需使用一个实例。

标签: java swing loops constructor


【解决方案1】:

所以,你的fields 可能需要是一个二维数组,例如

Field[][] fields = new Field[9][9];

这样,您可以访问给定面板(第一维)的字段(第二维),即fields[pane][field]

显然,在您的for-loop 中,您需要正确初始化字段的数组,例如fields[i] = new Field[9]

这可能会使您的代码看起来更像...

public class Field {

    JTextField field = new JTextField();
    static int fieldID = 0;
    private String text;

    public Field() {
        fieldID++;
    }

    public String getValue() {
        return field.getText();
    }

    public void setValue(String text) {
        field.setText(text);
    }
}

public class Frame extends JFrame {

    public Frame() {
        Field[][] fields = new Field[9][9];
        JPanel[] corePane = new JPanel[9];
        JPanel frontPane = new JPanel();
        frontPane.setLayout(new GridLayout(3, 3));

        for (int i = 0; i < corePane.length; i++) {
            corePane[i] = new JPanel();
            fields[i] = new Field[9];
            for (int j = 0; j < 9; j++) {
                fields[i][j] = new Field();
                corePane[i].add(fields[i][j].field);
            }
            corePane[i].setLayout(new GridLayout(3, 3));
            frontPane.add(corePane[i]);
        }

        setLayout(new BorderLayout());
        setSize(300, 300);
        getContentPane().add(frontPane, BorderLayout.CENTER);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(Frame::new);
    }
}

现在,static的一句话

static int fieldID = 0;

意味着Field 的每个实例都将具有相同的fieldID,无论您将其更改为什么。对我来说(根据你所说的),以这种方式使用static 是没有意义的

有替代方案,可能会提供更好和更可重用的解决方案

【讨论】:

    【解决方案2】:

    作为@MadProgrammer 解决方案的替代方案,我可以为您提供一些有用的方法,可以帮助您解决这些任务而无需声明任何数组。

    /**
     * Searches for all children of the given component which are instances of the given class.
     *
     * @param aRoot start object for search. May not be null.
     * @param aClass class to search. May not be null.
     * @param <E> class of component.
     * @return list of all children of the given component which are instances of the given class. Never null.
     */
    public static <E> List<E> getAllChildrenOfClass(Container aRoot, Class<E> aClass) {
        return getAllChildrenOfClass(aRoot, aClass, e -> true);
    }
    
    /**
     * Searches for all children of the given component which are instances of the given class and satisfies the given condition.
     *
     * @param aRoot start object for search. May not be null.
     * @param aClass class to search. May not be null.
     * @param condition condition to be satisfied. May not be null.
     * @param <E> class of component.
     * @return list of all children of the given component which are instances of the given class. Never null.
     */
    public static <E> List<E> getAllChildrenOfClass(Container aRoot, Class<E> aClass, Predicate<E> condition) {
        final List<E> result = new ArrayList<>();
        final Component[] children = aRoot.getComponents();
        for (final Component c : children) {
            if (aClass.isInstance(c) && condition.test(aClass.cast(c))) {
                result.add(aClass.cast(c));
            }
            if (c instanceof Container) {
                result.addAll(getAllChildrenOfClass((Container) c, aClass, condition));
            }
        }
        return result;
    }
    

    现在您可以为所有文本字段设置文本。

    getAllChildrenOfClass(getContentPane(), JTextField.class).forEach(tf -> tf.setText("My text"));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-08-17
      • 2021-11-20
      • 2014-06-29
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多