首页 > 解决方案 > 如何找到匿名jtextfield的文本

问题描述

所以我正在制作一个带有 gui 的商店系统。我有一个菜单项,当我按下它时,它会打开另一个 jframe 以输入 jtextfield 中出售的每个项目的数量,如下所示:

JPanel salesPanel = new JPanel();
setSize(new Dimension(520,270));
setResizable(false);
setLocation(200,200);
        
title = new JLabel("<html><u><b>Fill in the number of products sold.</b></u></html>");
        
salesPanel.setSize(new Dimension(230,30*sw.getProductList().size()));
salesPanel.setLayout(new GridLayout(sw.getProductList().size()+1,3));
...
sw.getProductList().forEach(n ->{
    salesPanel.add(new JLabel(Integer.toString(n.getProductID())+":"));
    salesPanel.add(new JLabel(Integer.toString(n.getQuantity())));
    salesPanel.add(new JLabel(n.getName()));
    salesPanel.add(new JTextField());
});

这就是它的外观。

这就是它的样子

请注意,这sw是主类的对象,它具有ArrayList包含每个产品信息的产品类型。

有什么方法可以让我从这些JTextFields 中发短信吗?如果不是我可以做到这一点的另一种方式。

编辑:在主 ShopWindow 类中,我有一个 ArrayList

private ArrayList<Product> productList = new ArrayList<Product>();

类产品:

public class Product {
    private int productID;
    private String name;
    private double price;
    private int quantity;
    private boolean isPerishable;
    private double totalProdValue;
    ...getters and setters for each field

标签: javaswingactionlistener

解决方案


这是一个模拟解决方案(仅用于展示如何使用动作监听器更新数量标签和清除字段)

public class MockFrame {

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        JPanel framePanel = new JPanel();
        ProductPanel bananaPanel = new ProductPanel("268", "25", "Bananas");
        ProductPanel sugarPanel = new ProductPanel("321", "200", "Sugar");
        
        JPanel buttonPanel = new JPanel();
        JButton update = new JButton("Update");
        JButton cancel = new JButton("Cancel");
        
        buttonPanel.setSize(400, 30);
        update.setSize(50, 20);
        cancel.setSize(50, 20);
        buttonPanel.add(update);
        buttonPanel.add(cancel);
        
        update.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                bananaPanel.setNewQty();
                sugarPanel.setNewQty();
            }
        });

        cancel.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                bananaPanel.clearField();
                sugarPanel.clearField();
            }
        });
        
        frame.setSize(400, 400);
        framePanel.setLayout(new BoxLayout(framePanel, BoxLayout.PAGE_AXIS));
        framePanel.add(bananaPanel);
        framePanel.add(sugarPanel);
        framePanel.add(buttonPanel);
        frame.add(framePanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }

    private static class ProductPanel extends JPanel {
        private JLabel productId = new JLabel();
        private JLabel qty = new JLabel();
        private JLabel name = new JLabel();
        private JTextField field = new JTextField();
        
        public ProductPanel(String id, String amount, String itemName) {
            this.setSize(400, 30);
            this.field.setSize(100, 20);
            this.field.setColumns(5);
            
            productId.setText(id);
            qty.setText(amount);
            name.setText(itemName);
            
            this.add(productId);
            this.add(qty);
            this.add(name);
            this.add(field);
        }

        public void clearField() {
            field.setText("");
        }
        
        public void setNewQty() {
            String newQty = field.getText();
            if (newQty != null && !newQty.isBlank()) {
                qty.setText(newQty);
            }
        }
    }
}

这个模拟解决方案的要点:

  1. 使用 aJPanel封装产品线项目。如果您需要删除和/或添加产品行,这将更容易。
  2. 产品面板包含更新数量或清除框架按钮可调用的字段的方法(取决于单击的按钮)。
  3. 设计简单 - 为产品创建通用面板消除重复代码。

显然,您必须对其进行修改,以便使用正确的布局管理器或使用绝对定位来根据自己的喜好正确对齐组件。此外,您需要为表头创建一个面板并添加剩余的产品。此外,您可能希望将其分解为公共类,甚至可能为您的框架创建一个单独的类。

动作监听器也可以有一个“for-each”循环来更新每个ProductPanel,而不是单独对每个面板进行硬编码。这应该看起来像这样:

        public void actionPerformed(ActionEvent e) {
            JPanel panel = (JPanel)((JButton) e.getSource()).getParent().getParent();
            Component[] components = panel.getComponents();
            for (Component c : components) {
                if (c instanceof ProductPanel) {
                    ((ProductPanel)c).setNewQty();
                }
            }
        }
    });

显然,您的解决方案将取决于您决定如何将组件封装在容器中。对于这个模拟,产品面板位于框架面板内,其中包含放置按钮的面板。因此,我需要为更新和取消按钮获取“祖父”容器,以利用调用适当的方法以更动态的方式进行更新和清除。

最后,您可能想要做一些更优雅的事情来创建您的产品面板。例如,您可能想要添加一些工厂方法来创建您的产品面板,而不是像我的模拟解决方案那样使用硬编码的产品面板。无论如何,我想我展示了您正在寻找的解决方案。

更新:如果您不遵循 Andrew Thompson 的建议,即不使用文本字段作为数值,则面板的getNewQty方法将需要验证获得的文本以确保它包含有效的数值(这是他的观点)。我强烈建议你听从他的建议。


推荐阅读