【问题标题】:Netbeans: Update textfield on button eventNetbeans:更新按钮事件的文本字段
【发布时间】:2015-09-03 10:44:48
【问题描述】:

我正在尝试在 netbeans 中制作一个基本的角色创建规划器,以尝试学习 Java,如果我的问题有点愚蠢,请原谅我。

我创建了一个文本字段,每次更改相关统计信息时都需要使用公式进行更新。

在这个例子中,运气和魅力属性会影响易货技能。因此,当我更改其中任何一个统计数据时,我需要再次运行公式以更新易货技能。

目前该公式在创建对象时运行,而不是在更新另一个统计信息时运行。

这是我当前的(相关)代码:

package AppPackage;

import javax.swing.JOptionPane;


public class StartGUI extends javax.swing.JFrame {


    public StartGUI() {
        initComponents();
    }


    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        BarterPts = new javax.swing.JTextField();
        Chr = new javax.swing.JTextField();
        ChrPlus = new javax.swing.JButton();
        Luck = new javax.swing.JTextField();


        BarterPts.setEditable(false);
        BarterPts.setText("0");
        BarterPts.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                BarterPtsActionPerformed(evt);
            }
        });
        getContentPane().add(BarterPts, new org.netbeans.lib.awtextra.AbsoluteConstraints(470, 110, 30, -1));
        int a = Integer.parseInt(Chr.getText()),l = Integer.parseInt(Luck.getText()),barter;
        barter = (2 + (a*2) + (l/2) );
        BarterPts.setText(String.valueOf(barter));


    //plus button to add to the Charisma stat.
    private void ChrPlusActionPerformed(java.awt.event.ActionEvent evt) {                                        
        int a = Integer.parseInt(Chr.getText()),i,l = Integer.parseInt(SLeft.getText());
        if (a == 10) {
            //print error
            JOptionPane.showMessageDialog(null, "The Charisma value cannot exceed 10.", "Error", JOptionPane.ERROR_MESSAGE);
        }
        else if (l == 0) {
            JOptionPane.showMessageDialog(null, "You have no special points remaining.", "Error", JOptionPane.ERROR_MESSAGE);
        }
        else{
            l=--l;
            SLeft.setText(String.valueOf(l));
            i=++a;
            Chr.setText(String.valueOf(i));
    }                                       
    }

    private void BarterPtsActionPerformed(java.awt.event.ActionEvent evt) {                                          

    }       

下面有变量声明,但我没有包含它们。

【问题讨论】:

  • 好的,你的问题是?或者更具体地说,您遇到的问题是?
  • 你真正需要的是某种模型,它可以管理状态,当一个状态更新时,它可以根据模型的规则更新其他状态,甚至提供一些统计数据已更改的通知类型
  • 变量名不能以大写字母开头!!!

标签: java swing netbeans jbutton jtextfield


【解决方案1】:

因此,从您最初的问题来看,您似乎期望基于按钮单击来更新文本字段。

目前,您已将 ActionListener 注册到您的文本字段。相反,您的 ActionListener 应该注册到您的按钮。

ChrPlus.addActionListener(final ActionEvent theEvent) {
     BarterPts.setText(//New text here based off a function);
}

将监听器注册到按钮将强制执行预期的点击行为。

【讨论】:

    【解决方案2】:

    作为学习练习,现在可能是了解Model-View-Controller 的好时机。 Swing 使用一种 MVC 形式,它更像 M-VC,其中视图和控制器的绑定比纯 MVC 实现更紧密。

    这里的重点是,您要将模型(数据和规则)与视图(/控制器)分开。视图/控制器成为您可以“操纵”模型的一种方式,但由于它是分离的,您可以更改模型及其工作方式而无需更改视图

    您应该学习的另一个原则是编程到接口、实现的概念(请参阅Program to an Interface, FoolProgram to an interface, not an implementation 了解一些初学者)

    基本上,这会进一步解耦您的代码,这意味着您的部分代码不会对其他部分的状态或其功能做出假设,并且允许您更改物理实现(规则)而无需更改一大堆容纳它的代码。

    我可能做的第一件事是创建一个interface,它描述了我希望任何人都可以从我的角色表中进行的非常基本的操作

    public interface CharacterSheet {
    
        public int getLuck();
        public int getCharisma();
        public int getBarter();
    
    }
    

    因为我特别偏执,我不明白为什么“每个人”都应该能够在他们想要的时候更改字符表,相反,我通过另一个界面限制了这一点。想想看,一旦生成了角色,你就不能在稍后的某个时间(比如在任务完成之后)更改统计数据,然后你可能想要使用一些“经验”规则/算法来分发和更新统计数据,但是那是我;)

    public interface MutableCharacterSheet extends CharacterSheet {
    
        public void setLuck(int value);
        public void setCharisma(int value);
    
        public void addPropertyChangeListener(PropertyChangeListener listener);
        public void removePropertyChangeListener(PropertyChangeListener listener);
    
    }
    

    好的,现在我们有了更新字符表的方法。这个interface 还包括一个Observer Pattern,它可以让您检测到何时对字符表进行了更改,以便您采取适当的措施。

    现在,我们需要一个实现。通常,我可能会创建一个或多个 abstract 实现来提供基本/通用功能,例如对 PropertyChangeListener 的支持,但在这种情况下,我将直接使用默认实现......

    public class DefaultCharacterSheet implements MutableCharacterSheet {
    
        private PropertyChangeSupport propertyChangeSupport;
        private int luck;
        private int charisma;
        private int barter;
    
        public DefaultCharacterSheet() {
            propertyChangeSupport = new PropertyChangeSupport(this);
        }
    
        @Override
        public int getLuck() {
            return luck;
        }
    
        @Override
        public void setLuck(int value) {
            if (luck != value) {
                int old = luck;
                this.luck = value;
                propertyChangeSupport.firePropertyChange("luck", old, luck);
                updateBarter();
            }
        }
    
        @Override
        public int getCharisma() {
            return charisma;
        }
    
        @Override
        public void setCharisma(int value) {
            if (charisma != value) {
                int old = charisma;
                this.charisma = value;
                propertyChangeSupport.firePropertyChange("charisma", old, charisma);
                updateBarter();
            }
        }
    
        protected void updateBarter() {
            int luck = getLuck();
            int charisma = getCharisma();
            int old = barter;
            // Or what ever formula you want to use
            barter = (int) ((luck / 2d) * charisma);
            propertyChangeSupport.firePropertyChange("barter", old, barter);
        }
    
        @Override
        public int getBarter() {
            return barter;
        }
    
        @Override
        public void addPropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.addPropertyChangeListener(listener);
        }
    
        @Override
        public void removePropertyChangeListener(PropertyChangeListener listener) {
            propertyChangeSupport.removePropertyChangeListener(listener);
        }
    
    }
    

    现在,这可能“看起来”很奇怪。我已经实现了MutableCharacterSheet,但是如果我不想让代码修改字符表怎么办?这就是 OO 的魅力所在。

    不应该修改工作表的部分代码应该只支持CharacterSheet接口,这意味着我可以将DefaultCharacterSheet的实例传递给他们,但他们只会看到并能够做任何接口@ 987654340@ 允许他们这样做,Polymorphism baby!

    现在,我们需要某种方式将其显示给用户并允许他们与之交互...

    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.beans.PropertyChangeSupport;
    import java.text.NumberFormat;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JSpinner;
    import javax.swing.JTextField;
    import javax.swing.SpinnerNumberModel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    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() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    MutableCharacterSheet characterSheet = new DefaultCharacterSheet();
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new CharacterSheetPane(characterSheet));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class CharacterSheetPane extends JPanel {
    
            private JSpinner luckField;
            private JSpinner charismaField;
            private JTextField barterField;
    
            private MutableCharacterSheet characterSheet;
    
            public CharacterSheetPane(MutableCharacterSheet sheet) {
    
                this.characterSheet = sheet;
                characterSheet.addPropertyChangeListener(new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        if ("barter".equals(evt.getPropertyName())) {
                            int value = (int) evt.getNewValue();
                            barterField.setText(NumberFormat.getNumberInstance().format(value));
                        }
                    }
                });
    
                luckField = new JSpinner(new SpinnerNumberModel(0, 0, 10, 1));
                charismaField = new JSpinner(new SpinnerNumberModel(0, 0, 10, 1));
                barterField = new JTextField(5);
                barterField.setEditable(false);
    
                luckField.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        characterSheet.setLuck((int) luckField.getValue());
                    }
                });
                charismaField.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        characterSheet.setCharisma((int) charismaField.getValue());
                    }
                });
    
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                gbc.insets = new Insets(2, 2, 2, 2);
    
                gbc.anchor = GridBagConstraints.EAST;
                add(new JLabel("Luck: "), gbc);
                gbc.anchor = GridBagConstraints.WEST;
                gbc.gridx++;
                add(luckField, gbc);
    
                gbc.anchor = GridBagConstraints.EAST;
                gbc.gridx = 0;
                gbc.gridy++;
                add(new JLabel("Charisma: "), gbc);
                gbc.anchor = GridBagConstraints.WEST;
                gbc.gridx++;
                add(charismaField, gbc);
    
                gbc.anchor = GridBagConstraints.EAST;
                gbc.gridx = 0;
                gbc.gridy++;
                add(new JLabel("Barter: "), gbc);
                gbc.anchor = GridBagConstraints.WEST;
                gbc.gridx++;
                add(barterField, gbc);
            }
    
        }
    
    }
    

    因此,随着luck 和charisma 字段的更改,我们更新模型,模型实习生更新barter 值,这会触发PropertyChangeEvent,这允许我们更新易货字段

    这似乎需要很多东西,但如果你能理解这些基本原则,那将需要很长的路要走。

    看看:

    有关我在 UI 代码中所做的一些事情的更多信息。我强烈建议您尽快停止使用表单编辑器并开始手动编写 UI。您将更深入地了解布局管理器如何工作以及如何协同工作、创建复杂的 UI,以及何时以及如何分离代码以降低复杂性并增加重用。这也将帮助您了解表单编辑器何时有用,何时无用;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 1970-01-01
      相关资源
      最近更新 更多