如何将 JTextField 从 JFrame 传递到另一个 JFrame?
How to pass JTextField from JFrame into another JFrame?
我有两个 JFrame(JFrame1 和 JFrame2)以及两个 JTextField1 和 JTextField2。我的问题是,当我从 Jframe2 在 JTextField2 上写 "Hello world ",然后单击“确定”按钮时,我在 Jframe1 class 上的 JTextField1 上看到 "Hello world "。
我该怎么做?如果这是一个新手问题,我很抱歉,但我正在学习..
这是我的代码:
JFrame2:
private JFrame1 jf1;
private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {
jf1.setjTextField1(this.jTextField2);
}
您在那里所做的实际上是将对实际 JTextField 的引用从一帧发送到另一帧。
这可能不是一个好主意,因为两个框架最终会引用相同的视觉组件。
您可能想要的是将所有可视组件分开,但使第二个文本字段的文本与第一个文本字段中的文本相同。
像这样:
private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {
jf1.getjTextField1().setText(this.jTextField2.getText());
}
这是我刚刚编写出来的一个完整的工作示例:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class FrameRunner
{
public static void main(String[] args){
MyFrame f1 = new MyFrame("Frame 1");
MyFrame f2 = new MyFrame("Frame 2");
f1.addRef(f2);
f2.addRef(f1);
}
}
class MyFrame extends JFrame{
JTextField txt = new JTextField(8);
JButton btn = new JButton("Send");
MyFrame f = null;
public MyFrame(String title){
super(title);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new FlowLayout());
setPreferredSize(new Dimension(400, 300));
setVisible(true);
add(btn);
add(txt);
pack();
setLocationRelativeTo(null);
init();
}
public void addRef(MyFrame f){
this.f = f;
}
public void init(){
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
f.update(txt.getText());
}
});
}
public void update(String str){
txt.setText(str);
}
}
为了让代码简短易懂。很多东西我没有按照约定做,没有把代码模块化。但这应该让您很好地了解如何传递另一个 JFrame
的引用。
此代码显示了 Frame1
如何引用 Frame2
的示例。然而 Frame2
也有对 Frame1
的引用。
您在 JFrame1
中输入的任何内容都可以发送到 JFrame2's
textfield
。反之亦然。
您可以使用 Observer Pattern or Producer/Consumer Pattern 来解决问题。
基本的想法是,你有一些东西可以生成一个值,还有一些东西想要被通知或消费生成的值。
您应该花时间学习的其他原则之一也是 Code to interface (not implementation)。这听起来很奇怪,但它的想法是减少不必要的对象暴露(unintended/controlled 修改)并解耦代码,因此您可以更改底层实现而不影响依赖它的任何其他代码
鉴于您问题的性质,观察者模式可能更合适。大多数 Swing 的监听器都是基于相同的原理。
我们首先定义 "generator" 将用于提供更改通知的合同...
public interface TextGeneratorObserver {
public void textGenerated(String text);
}
很简单。这意味着我们可以安全地向生成器提供实现此 interface
的任何对象的实例,并且知道它不会对我们的对象做任何事情,因为它唯一知道的是 textGenerated
方法.
接下来,我们需要一些东西来生成我们正在等待的输出...
public class GeneratorPane extends JPanel {
private TextGeneratorObserver observer;
private JTextField field;
private JButton button;
public GeneratorPane(TextGeneratorObserver observer) {
this.observer = observer;
field = new JTextField(10);
button = new JButton("OK");
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
observer.textGenerated(field.getText());
}
};
button.addActionListener(listener);
field.addActionListener(listener);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(2, 2, 2, 2);
add(field, gbc);
add(button, gbc);
}
}
这只是一个简单的 JPanel
,但它需要您将 TextGeneratorObserver
的实例传递给它。当按钮(或字段)触发ActionListener
时,ActionListener
调用textGenerated
通知观察者文本已生成或更改
现在,我们需要有人观察它...
public class ObserverPanel extends JPanel implements TextGeneratorObserver {
private JLabel label;
public ObserverPanel() {
label = new JLabel("...");
add(label);
}
@Override
public void textGenerated(String text) {
label.setText(text);
}
}
这是一个简单的 JPanel
,它实现 TextGeneratorObserver
interface
并使用新文本
更新它的 JLabel
然后,我们只需要一起探测它
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();
}
ObserverPanel op = new ObserverPanel();
op.setBorder(new CompoundBorder(new LineBorder(Color.RED), new EmptyBorder(10, 10, 10, 10)));
GeneratorPane pp = new GeneratorPane(op);
pp.setBorder(new CompoundBorder(new LineBorder(Color.GREEN), new EmptyBorder(10, 10, 10, 10)));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 1));
frame.add(pp);
frame.add(op);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
我有两个 JFrame(JFrame1 和 JFrame2)以及两个 JTextField1 和 JTextField2。我的问题是,当我从 Jframe2 在 JTextField2 上写 "Hello world ",然后单击“确定”按钮时,我在 Jframe1 class 上的 JTextField1 上看到 "Hello world "。
我该怎么做?如果这是一个新手问题,我很抱歉,但我正在学习..
这是我的代码:
JFrame2:
private JFrame1 jf1;
private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {
jf1.setjTextField1(this.jTextField2);
}
您在那里所做的实际上是将对实际 JTextField 的引用从一帧发送到另一帧。
这可能不是一个好主意,因为两个框架最终会引用相同的视觉组件。
您可能想要的是将所有可视组件分开,但使第二个文本字段的文本与第一个文本字段中的文本相同。
像这样:
private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {
jf1.getjTextField1().setText(this.jTextField2.getText());
}
这是我刚刚编写出来的一个完整的工作示例:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
class FrameRunner
{
public static void main(String[] args){
MyFrame f1 = new MyFrame("Frame 1");
MyFrame f2 = new MyFrame("Frame 2");
f1.addRef(f2);
f2.addRef(f1);
}
}
class MyFrame extends JFrame{
JTextField txt = new JTextField(8);
JButton btn = new JButton("Send");
MyFrame f = null;
public MyFrame(String title){
super(title);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new FlowLayout());
setPreferredSize(new Dimension(400, 300));
setVisible(true);
add(btn);
add(txt);
pack();
setLocationRelativeTo(null);
init();
}
public void addRef(MyFrame f){
this.f = f;
}
public void init(){
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
f.update(txt.getText());
}
});
}
public void update(String str){
txt.setText(str);
}
}
为了让代码简短易懂。很多东西我没有按照约定做,没有把代码模块化。但这应该让您很好地了解如何传递另一个 JFrame
的引用。
此代码显示了 Frame1
如何引用 Frame2
的示例。然而 Frame2
也有对 Frame1
的引用。
您在 JFrame1
中输入的任何内容都可以发送到 JFrame2's
textfield
。反之亦然。
您可以使用 Observer Pattern or Producer/Consumer Pattern 来解决问题。
基本的想法是,你有一些东西可以生成一个值,还有一些东西想要被通知或消费生成的值。
您应该花时间学习的其他原则之一也是 Code to interface (not implementation)。这听起来很奇怪,但它的想法是减少不必要的对象暴露(unintended/controlled 修改)并解耦代码,因此您可以更改底层实现而不影响依赖它的任何其他代码
鉴于您问题的性质,观察者模式可能更合适。大多数 Swing 的监听器都是基于相同的原理。
我们首先定义 "generator" 将用于提供更改通知的合同...
public interface TextGeneratorObserver {
public void textGenerated(String text);
}
很简单。这意味着我们可以安全地向生成器提供实现此 interface
的任何对象的实例,并且知道它不会对我们的对象做任何事情,因为它唯一知道的是 textGenerated
方法.
接下来,我们需要一些东西来生成我们正在等待的输出...
public class GeneratorPane extends JPanel {
private TextGeneratorObserver observer;
private JTextField field;
private JButton button;
public GeneratorPane(TextGeneratorObserver observer) {
this.observer = observer;
field = new JTextField(10);
button = new JButton("OK");
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
observer.textGenerated(field.getText());
}
};
button.addActionListener(listener);
field.addActionListener(listener);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = GridBagConstraints.REMAINDER;
gbc.insets = new Insets(2, 2, 2, 2);
add(field, gbc);
add(button, gbc);
}
}
这只是一个简单的 JPanel
,但它需要您将 TextGeneratorObserver
的实例传递给它。当按钮(或字段)触发ActionListener
时,ActionListener
调用textGenerated
通知观察者文本已生成或更改
现在,我们需要有人观察它...
public class ObserverPanel extends JPanel implements TextGeneratorObserver {
private JLabel label;
public ObserverPanel() {
label = new JLabel("...");
add(label);
}
@Override
public void textGenerated(String text) {
label.setText(text);
}
}
这是一个简单的 JPanel
,它实现 TextGeneratorObserver
interface
并使用新文本
JLabel
然后,我们只需要一起探测它
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();
}
ObserverPanel op = new ObserverPanel();
op.setBorder(new CompoundBorder(new LineBorder(Color.RED), new EmptyBorder(10, 10, 10, 10)));
GeneratorPane pp = new GeneratorPane(op);
pp.setBorder(new CompoundBorder(new LineBorder(Color.GREEN), new EmptyBorder(10, 10, 10, 10)));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 1));
frame.add(pp);
frame.add(op);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}