Netbeans:更新按钮事件的文本字段

时间:2015-06-18 00:04:42

标签: java swing netbeans jbutton jtextfield

我试图在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) {                                          

    }       

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

2 个答案:

答案 0 :(得分:1)

因此,从您的原始问题看,您希望基于按钮点击更新文本字段。

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

git branch --no-merged

将监听器注册到按钮将强制按预期执行单击操作。

答案 1 :(得分:1)

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

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

您应该学习的另一个原则是编程接口和实现的概念(对于一些初学者,请参阅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的实例,但是他们只能看到并能够做什么接口CharacterSheet允许他们这样做,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);
        }

    }

}

因此,随着运气和魅力字段的更改,我们更新模型,模型实习生更新barter值,触发PropertyChangeEvent,这样我们就可以更新易货字段

这可能看起来很多,但如果你能理解这些基本原则,那将需要很长的时间。

看看:

有关我在UI代码中完成的一些事情的更多信息。在您最早的说服力,我强烈建议您停止使用表单编辑器并开始手动编写UI。您将更好地了解布局管理器的工作方式和可以协同工作,创建复杂的UI,以及何时以及如何分离代码以降低复杂性和增加重复使用。这也有助于您了解表单编辑器何时有用以及何时不可用;)