[英]How to transfer a value from one JLabel to another?
我有這個計算器工作,但我無法弄清楚如何在單擊“完成”按鈕時將結果resultpane
的值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) {
}
}
}
}
}
為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));
}
}
作為另一種方法,您可以建立某種模型,這些模型在操作和組件之間共享,這有助於分離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) {
}
}
}
}
}
這是觀察者模式的一個例子
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.