简体   繁体   English

如何将值从一个JLabel传输到另一个JLabel?

[英]How to transfer a value from one JLabel to another?

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. 我有这个计算器工作,但我无法弄清楚如何在单击“完成”按钮时将结果resultpane的值resultpane到第一个文本框。

I'm new to Java. 我是Java的新手。 I've tried doing it, but I kept getting an error. 我试过这样做,但我一直都是错误的。

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 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;

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) {
            }

            ResultPane resultPane = new ResultPane();

            JFrame frame = new JFrame("Testing");
            frame.setGlassPane(resultPane);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new CalculatorPane(resultPane));
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

public class ResultPane extends JPanel {

    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 setResult(Number number) {
        result.setText("Result: " + NumberFormat.getNumberInstance().format(number));
        result.setSize(result.getPreferredSize());
        setVisible(true);
    }

}

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);

    public CalculatorPane(ResultPane resultPane) {

        setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;

        this.resultPane = resultPane;

        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()));
        buttons.add(new JButton(new SubtractAction()));
        buttons.add(new JButton(new MultiplyAction()));
        buttons.add(new JButton(new DivideAction()));
        buttons.add(new JButton(new ToText1Action()));

        add(buttons, gbc);

    }

    public class AddAction extends AbstractAction {

        public AddAction() {
            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);
                resultPane.setResult(result);
            } catch (NumberFormatException exp) {
            }
        }

    }
    public class SubtractAction extends AbstractAction {

        public SubtractAction() {
            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;
                resultPane.setResult(result);
            } catch (NumberFormatException exp) {
            }
        }

    }
    public class MultiplyAction extends AbstractAction {

        public MultiplyAction() {
            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;
                resultPane.setResult(result);
            } catch (NumberFormatException exp) {
            }
        }

    }
    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());

                double result = num1 / num2;
                resultPane.setResult(result);
            } catch (NumberFormatException exp) {
            }
        }

    }
    public class ToText1Action extends AbstractAction {
        public ToText1Action() {
            putValue(NAME, "Finish");
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            try {

                //i would like to put it here


            } catch (NumberFormatException exp) {
            }
        }
    }
}
}

Give your ResultPane a new public method that allows you to extract the text from its JLabel, something like: 为ResultPane提供一个新的公共方法,允许您从其JLabel中提取文本,如:

  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. 更好的是,只需将最新的结果值存储在一个double变量中,该变量是类的实例字段,比如名为lastResult并设置firstNumberField。

Note that you should not have empty catch blocks. 请注意,您不应该有空的catch块。


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));
     }
  }

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. 作为另一种方法,您可以建立某种模型,这些模型在操作和组件之间共享,这有助于分离UI,因为它的主要链接因素是模型,而不是其他UI元素。

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... 对于ToText1Action ,您还需要将它传递给您想要更新的字段,但由于它主要是一个JTextField ,因此它不应该是坏的......

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. 需要更改ResultsPane和每个操作,以便它们可以使用模型而不是直接使用每个模型。 This means that the ResultsPane will now listen to changes in the model instead of been updated directly 这意味着ResultsPane现在将侦听模型中的更改,而不是直接更新

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 这是观察者模式的一个例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM