How to transfer a value from one JLabel to another?

后端 未结 2 1081
终归单人心
终归单人心 2021-01-14 08:39

I have this calculator working, but I can\'t figure out how to get the value in the resultpane to the first textbox when you click the \"finish\" button.

相关标签:
2条回答
  • 2021-01-14 08:56

    Give your ResultPane a new public method that allows you to extract the text from its JLabel, something like:

      public String getResultText() {
         return result.getText();
      }
    

    And then call it when you want to get the text of that field:

      public class ToText1Action extends AbstractAction {
         public ToText1Action() {
            putValue(NAME, "Finish");
         }
    
         @Override
         public void actionPerformed(ActionEvent e) {
             String resultText = resultPane.getResultText();
             double number = // extract number from resultText
             firstNumberField.setText(number);
         }
      }
    

    Better still, simply store the latest result value in a double variable that is an instance field of the class, say called lastResult and set the firstNumberField with that.

    Note that you should not have empty catch blocks.


    Edit

    For example:

    public class CalculatorPane extends JPanel {
      private final ResultPane resultPane;
      private final JLabel firstNumberLabel = new JLabel("First Number:");
      private final JLabel secondNumberLabel = new JLabel("Second Number:");
      private final JTextField firstNumberField = new JTextField(5);
      private final JTextField secondNumberField = new JTextField(5);
    
      private double result = 0.0;   // ****** declared here
    
      // ***** etc..... *****
    
      public class DivideAction extends AbstractAction {
    
         public DivideAction() {
            putValue(NAME, "/");
         }
    
         @Override
         public void actionPerformed(ActionEvent e) {
            try {
               double num1 = Double.parseDouble(firstNumberField.getText());
               double num2 = Double.parseDouble(secondNumberField.getText());
    
               result = num1 / num2; // ****** note variable not declared
               resultPane.setResult(result);
            } catch (NumberFormatException exp) {
               // show error message
               // set text fields to "0"
            }
         }
    
      }
    
      public class ToText1Action extends AbstractAction {
         public ToText1Action() {
            super("Finish");
            putValue(MNEMONIC_KEY, KeyEvent.VK_F);
         }
    
         @Override
         public void actionPerformed(ActionEvent e) {
            firstNumberField.setText(String.format("%.2f", result));
         }
      }
    
    0 讨论(0)
  • 2021-01-14 09:00

    As another approach, you could establish some kind of model, which is shared between the actions and the components, this helps de-couple of the UI as it's main linking factor is the model, not other UI elements.

    For the ToText1Action, you will also need to pass it the field you want updated, but since it's primarily a JTextField, it shouldn't be to bad...

    So, the primary change is the inclusion of some kind of model, which provides means to set the result, get the result and provide event notification when the model changes, so those interested parties can update themselves as required, for example...

    public interface ResultsModel {
    
        public void setResult(double value);
        public double getResult();
    
        public void addChangeListener(ChangeListener listener);
        public void removeChangeListener(ChangeListener listener);
    
    }
    
    public class DefaultResultsModel implements ResultsModel {
    
        private List<ChangeListener> changeListeners;
        private double result;
    
        public DefaultResultsModel() {
            changeListeners = new ArrayList<>(25);
        }
    
        public double getResult() {
            return result;
        }
    
        public void setResult(double value) {
            if (value != result) {
                this.result = value;
                fireStateChanged();
            }
        }
    
        protected void fireStateChanged() {
            if (!changeListeners.isEmpty()) {
                ChangeEvent evt = new ChangeEvent(this);
                for (ChangeListener listener : changeListeners) {
                    listener.stateChanged(evt);
                }
            }
        }
    
        @Override
        public void addChangeListener(ChangeListener listener) {
            changeListeners.add(listener);
        }
    
        @Override
        public void removeChangeListener(ChangeListener listener) {
            changeListeners.remove(listener);
        }
    
    }
    

    The ResultsPane and each action will need to be changed so that they can work with the model instead of directly with each. This means that the ResultsPane will now listen to changes in the model instead of been updated directly

    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Point;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.text.NumberFormat;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.AbstractAction;
    import static javax.swing.Action.NAME;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    
    public class TestCalculator {
    
        public static void main(String[] args) {
            new TestCalculator();
        }
    
        public TestCalculator() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    ResultsModel model = new DefaultResultsModel();
                    ResultPane resultPane = new ResultPane();
                    resultPane.setModel(model);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setGlassPane(resultPane);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new BorderLayout());
                    frame.add(new CalculatorPane(model));
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public interface ResultsModel {
    
            public void setResult(double value);
            public double getResult();
    
            public void addChangeListener(ChangeListener listener);
            public void removeChangeListener(ChangeListener listener);
    
        }
    
        public class DefaultResultsModel implements ResultsModel {
    
            private List<ChangeListener> changeListeners;
            private double result;
    
            public DefaultResultsModel() {
                changeListeners = new ArrayList<>(25);
            }
    
            @Override
            public double getResult() {
                return result;
            }
    
            @Override
            public void setResult(double value) {
                if (value != result) {
                    this.result = value;
                    fireStateChanged();
                }
            }
    
            protected void fireStateChanged() {
                if (!changeListeners.isEmpty()) {
                    ChangeEvent evt = new ChangeEvent(this);
                    for (ChangeListener listener : changeListeners) {
                        listener.stateChanged(evt);
                    }
                }
            }
    
            @Override
            public void addChangeListener(ChangeListener listener) {
                changeListeners.add(listener);
            }
    
            @Override
            public void removeChangeListener(ChangeListener listener) {
                changeListeners.remove(listener);
            }
    
        }
    
        public class ResultPane extends JPanel implements ChangeListener {
    
            private ResultsModel model;
    
            private JLabel result;
            private Timer timer;
    
            private int xDelta = (Math.random() > 0.5) ? 1 : -1;
            private int yDelta = (Math.random() > 0.5) ? 1 : -1;
    
        public ResultPane() {
                setOpaque(false);
                setLayout(null);
                result = new JLabel();
                Font font = result.getFont();
                font = font.deriveFont(Font.BOLD, 26f);
                result.setFont(font);
                add(result);
                timer = new Timer(40, new ActionListener() {
    
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        Point point = result.getLocation();
                        point.x += xDelta;
                        point.y += yDelta;
                        if (point.x < 0) {
                            point.x = 0;
                            xDelta *= -1;
                        } else if (point.x + result.getWidth() > getWidth()) {
                            point.x = getWidth() - result.getWidth();
                            xDelta *= -1;
                        }
                        if (point.y < 0) {
                            point.y = 0;
                            yDelta *= -1;
                        } else if (point.y + result.getHeight() > getHeight()) {
                            point.y = getHeight() - result.getHeight();
                            yDelta *= -1;
                        }
                        result.setLocation(point);
                        repaint();
                    }
    
                });
                timer.start();
            }
    
            public void setModel(ResultsModel value) {
                if (value != model) {
                    if (model != null) {
                        model.removeChangeListener(this);
                    }
                    model = value;
                    if (model != null) {
                        model.addChangeListener(this);
                    }
                }
            }
    
            public ResultsModel getModel() {
                return model;
            }
    
            @Override
            public void stateChanged(ChangeEvent e) {
                double number = getModel().getResult();
                result.setText("Result: " + NumberFormat.getNumberInstance().format(number));
                result.setSize(result.getPreferredSize());
                setVisible(true);
            }
    
        }
    
        public class CalculatorPane extends JPanel {
    
            private final JLabel firstNumberLabel = new JLabel("First Number:");
            private final JLabel secondNumberLabel = new JLabel("Second Number:");
    
            private final JTextField firstNumberField = new JTextField(5);
            private final JTextField secondNumberField = new JTextField(5);
    
            public CalculatorPane(ResultsModel model) {
    
                setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridwidth = GridBagConstraints.REMAINDER;
    
                JPanel fields = new JPanel();
                fields.add(firstNumberLabel);
                fields.add(firstNumberField);
                fields.add(secondNumberLabel);
                fields.add(secondNumberField);
    
                add(fields, gbc);
    
                JPanel buttons = new JPanel();
                buttons.add(new JButton(new AddAction(model)));
                buttons.add(new JButton(new SubtractAction(model)));
                buttons.add(new JButton(new MultiplyAction(model)));
                buttons.add(new JButton(new DivideAction(model)));
                buttons.add(new JButton(new ToText1Action(firstNumberField, model)));
    
                add(buttons, gbc);
    
            }
    
            public abstract class AbstractResultsAction extends AbstractAction {
    
                private ResultsModel model;
    
                public AbstractResultsAction(ResultsModel model) {
                    this.model = model;
                }
    
                public ResultsModel getModel() {
                    return model;
                }
    
            }
    
            public class AddAction extends AbstractResultsAction {
    
                public AddAction(ResultsModel model) {
                    super(model);
                    putValue(NAME, "+");
                }
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        double num1 = Double.parseDouble(firstNumberField.getText());
                        double num2 = Double.parseDouble(secondNumberField.getText());
    
                        double result = num1 + num2;
    
                        //num1.setResult(firstNumberField);
                        getModel().setResult(result);
                    } catch (NumberFormatException exp) {
                    }
                }
    
            }
    
            public class SubtractAction extends AbstractResultsAction {
    
                public SubtractAction(ResultsModel model) {
                    super(model);
                    putValue(NAME, "-");
                }
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        double num1 = Double.parseDouble(firstNumberField.getText());
                        double num2 = Double.parseDouble(secondNumberField.getText());
    
                        double result = num1 - num2;
                        getModel().setResult(result);
                    } catch (NumberFormatException exp) {
                    }
                }
    
            }
    
            public class MultiplyAction extends AbstractResultsAction {
    
                public MultiplyAction(ResultsModel model) {
                    super(model);
                    putValue(NAME, "x");
                }
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        double num1 = Double.parseDouble(firstNumberField.getText());
                        double num2 = Double.parseDouble(secondNumberField.getText());
    
                        double result = num1 * num2;
                        getModel().setResult(result);
                    } catch (NumberFormatException exp) {
                    }
                }
    
            }
    
            public class DivideAction extends AbstractResultsAction {
    
                public DivideAction(ResultsModel model) {
                    super(model);
                    putValue(NAME, "/");
                }
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        double num1 = Double.parseDouble(firstNumberField.getText());
                        double num2 = Double.parseDouble(secondNumberField.getText());
    
                        double result = num1 / num2;
                        getModel().setResult(result);
                    } catch (NumberFormatException exp) {
                    }
                }
    
            }
    
            public class ToText1Action extends AbstractResultsAction {
    
                private JTextField field;
    
                public ToText1Action(JTextField field, ResultsModel model) {
                    super(model);
                    putValue(NAME, "Finish");
                    this.field = field;
                }
    
                public JTextField getField() {
                    return field;
                }
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        double result = getModel().getResult();
                        getField().setText(NumberFormat.getNumberInstance().format(result));
                        //i would like to put it here
                    } catch (NumberFormatException exp) {
                    }
                }
            }
        }
    }
    

    This is an example of the observer pattern

    0 讨论(0)
提交回复
热议问题