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

时间:2014-05-17 16:00:01

标签: java swing jlabel calculator

我有这个计算器正常工作,但是当我点击"完成"时,我无法弄清楚如何将resultpane中的值传到第一个文本框中。按钮。

我是Java的新手。我试过这样做,但我一直都是错误的。

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

2 个答案:

答案 0 :(得分:3)

为您的ResultPane提供一个新的公共方法,允许您从其JLabel中提取文本,如:

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

然后在想要获取该字段的文本时调用它:

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

更好的是,只需将最新的结果值存储在一个double变量中,该变量是类的实例字段,比如称为lastResult,并设置firstNumberField。

请注意,您不应该有空的catch块。


修改

例如:

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

答案 1 :(得分:0)

作为另一种方法,你可以建立某种模型,它在动作和组件之间共享,这有助于分离UI,因为它的主要链接因素是模型,而不是其他UI元素。

对于ToText1Action,您还需要将其传递给您想要更新的字段,但由于它主要是JTextField,因此不应该是错误的...

因此,主要的变化是包含某种模型,它提供了设置结果,获取结果并在模型更改时提供事件通知的方法,因此这些感兴趣的各方可以根据需要自行更新。 ..

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

}

ResultsPane和每个操作都需要更改,以便他们可以使用模型而不是直接使用每个模型。这意味着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) {
                }
            }
        }
    }
}

这是observer pattern

的示例