Java 使用JOptionPane中的文本字段面板,DocumentListener?-初学者

Java 使用JOptionPane中的文本字段面板,DocumentListener?-初学者,java,swing,panel,textfield,joptionpane,Java,Swing,Panel,Textfield,Joptionpane,编辑以添加setName函数: 我已经使用stackoverflow帮助学习java一年多了,在大学里只花了大约6个小时的CS。你们是最棒的!所以,开始吧 我的问题是我有一个包含多个文本字段的JOptionPane。从这些字段检索文本的所有示例仅显示一个textField。我可以为每个文本字段创建一个单独的DocumentListener,分别处理每个框,但似乎应该有一种方法来创建一个DocumentListener,可以说: 如果(名称框已更改) 编辑名称 else if(数据箱已更改) 编辑

编辑以添加setName函数:

我已经使用stackoverflow帮助学习java一年多了,在大学里只花了大约6个小时的CS。你们是最棒的!所以,开始吧

我的问题是我有一个包含多个文本字段的JOptionPane。从这些字段检索文本的所有示例仅显示一个textField。我可以为每个文本字段创建一个单独的DocumentListener,分别处理每个框,但似乎应该有一种方法来创建一个DocumentListener,可以说:

如果(名称框已更改)

编辑名称

else if(数据箱已更改)

编辑数据

等等

以下是我的源代码:

    public class HumanPlayer extends Player
    {
    /**
     * Constructor for objects of class HumanPlayer
     */
    public HumanPlayer()
    {
        setName("Human " + getOrder());
    }


    @Override
    public void chooseSoldiers()
    {
        JLabel nameLabel = new JLabel("Enter name: " );
        //humans.setPreferredSize(new Dimension(100,50));


        final JTextField nameBox = new JTextField();
        final JTextField infantryBox = new JTextField();
        final JTextField scoutBox = new JTextField();
        final JTextField sniperBox = new JTextField();
        JLabel infLabel = new JLabel("Infantry: " );
        JLabel scLabel = new JLabel("Scouts: " );
        JLabel snLabel = new JLabel("Snipers: " );

        JPanel soldierPanel = new JPanel();
        soldierPanel.setLayout(new GridLayout(4,2,5, 8));
        soldierPanel.add(nameLabel);
        soldierPanel.add(nameBox);
        soldierPanel.add(infLabel);
        soldierPanel.add(infantryBox);
        soldierPanel.add(scLabel);
        soldierPanel.add(scoutBox);
        soldierPanel.add(snLabel);
        soldierPanel.add(sniperBox);

        nameBox.getDocument().addDocumentListener(new NameListener());
        infantryBox.getDocument().addDocumentListener(new NameListener());
        scoutBox.getDocument().addDocumentListener(new NameListener());
        sniperBox.getDocument().addDocumentListener(new NameListener());

        int ok = JOptionPane.showOptionDialog(null, soldierPanel,  
                "Player " + getOrder(), JOptionPane.CANCEL_OPTION,  
            JOptionPane.QUESTION_MESSAGE, null, null, null);        
       }

    public class NameListener implements DocumentListener
    {

        @Override
        public void changedUpdate(DocumentEvent e) {}
        @Override
        public void insertUpdate(DocumentEvent e) {
            try {
                   setName(e.getDocument().getText(0,e.getDocument().getLength()));
            } catch (BadLocationException e1) {e1.printStackTrace();}

        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            try {
                setName(e.getDocument().getText(0,e.getDocument().getLength()));
            } catch (BadLocationException e1) {e1.printStackTrace();
                }               
           }
    }
}
单独文件:

public abstract class Player
{
....
private String name;
 ....

public void setName(String _name)
{
    name = _name;
}

如果我理解正确,您希望使用一个文档侦听器,并让它响应所有
jtextfield
数据更改事件。不幸的是,
DocumentListener
的事件源是使用
addDocumentListener
函数注册到的
文档,而不是文本组件。因此,我们的想法是使用:

  • 文档的
    putProperty(“所有者”,txtfield)
    :跟踪此
    文档的所有者文本字段
  • 在文档更改事件中,使用
    getProperty(“所有者”)
    获取事件源的所有者:文档实例
  • PropertyChangeListener
    分配给每个文本字段,以将此属性设置为其自己的文档:因为如果将新文档的设置为我们正在使用的
    TextComponent
    ,则无法预测 仔细检查以下代码片段:

        class MyDocumentListener implements DocumentListener{
    
           public void updateComponent(DocumentEvent e)
           {
                boolean valid = checkDataValidity(e.getDocument());
                JTextField txtField = (JTextField) e.getDocument().getProperty("owner");
    
               if(!valid)
                 txtField.setEnabled(false);
               else  txtField.setEnabled(true);
           }
    
             @Override
             public void insertUpdate(DocumentEvent e) {updateComponent(e);}
    
             @Override
             public void removeUpdate(DocumentEvent e) {updateComponent(e);}
    
             @Override
             public void changedUpdate(DocumentEvent e) {}
         }
    
        class MyPropChangeListener implements PropertyChangeListener{
    
           DocumentListener documentListenr;
    
           public MyPropChangeListener(DocumentListener documentListener) {
                 this.documentListenr = documentListener;
           }
    
           @Override
           public void propertyChange(PropertyChangeEvent evt) {
               System.out.println("chaning document!!");
               JTextField txtFeild =  (JTextField)evt.getSource();
               txtFeild.getDocument().putProperty("owner", txtFeild);
               txtFeild.getDocument().addDocumentListener(documentListenr);
            }
         }
       //..............
    
       MyPropChangeListener propChangeListener = new MyPropChangeListener(new MyDocumentListener());
    
        jTextField1.addPropertyChangeListener("document", propChangeListener);
        jTextField1.setDocument(new PlainDocument());
    
        jTextField2.addPropertyChangeListener("document", propChangeListener);
        jTextField2.setDocument(new PlainDocument());
    

    您能否演示如何使用
    setName(text)
    函数?使用if/else结构不是一个好的设计。我真的不明白这个问题,所以我不能提出替代方案。但是单个DocumentListener比使用if/else更好。感谢您的快速响应!实际上,我刚刚用JTextField的putProperty和getProperty方法修复了它。我需要能够根据编辑的框选择要编辑的数据。使用单个DocumentListener是解决这个问题的标准方法吗?使用putProperty,我可以为每个textField的文档分配属性,然后从DocumentListener的事件中获取该属性。再次感谢你的帮助。在body中添加了setName(字符串s)的代码非常有用,你一针见血!就在你发布之前,我已经实现了一个草率的版本,但是保证我在正确的轨道上还有很长的路要走!再次感谢。我会投赞成票,但我必须有代表。我会给你一个+1。继续前进。您将来将有很多机会对答案进行投票;)