【问题标题】:How to pass JTextField from JFrame into another JFrame?如何将 JTextField 从 JFrame 传递到另一个 JFrame?
【发布时间】:2015-06-20 20:13:33
【问题描述】:

我有两个 JFrame(JFrame1 和 JFrame2)以及两个 JTextField1 和 JTextField2。我的问题是当我从 Jframe2 在 JTextField2 上写“Hello world”然后单击 OK 按钮时,我在 Jframe1 类的 JTextField1 上看到“Hello world”。

我该怎么做?如果这是一个新手问题,我很抱歉,但我正在学习..

这是我的代码:

JFrame2:

private JFrame1 jf1;
private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {                                     
    jf1.setjTextField1(this.jTextField2);
} 

【问题讨论】:

  • 您是否需要 JFrame1 的文本字段文本也显示在 JFrame2 的文本字段上?这意味着,您是否需要两个 JFrame 才能看到对方?
  • 你能多贴一些JFrame1和JFrame2的代码
  • 首先定义一个描述您想要公开的功能的接口(例如 setText)。让你的类实现这个接口。将类的引用(实现接口)传递给其他类,这样当ok按钮被触发时,就可以通过接口将String传递给其他类

标签: java swing jtextfield


【解决方案1】:

您在那里所做的实际上是将实际 JTextField 的引用从一帧发送到另一帧。

这可能不是一个好主意,因为两个框架最终会引用相同的视觉组件。

您可能想要将所有可视组件分开,但使第二个文本字段的文本与第一个文本字段中的文本相同。

类似这样的:

private void btn2ActionPerformed(java.awt.event.ActionEvent evt) {                                     
    jf1.getjTextField1().setText(this.jTextField2.getText());
} 

【讨论】:

  • 感谢您的快速回复。我写了它,但它对我不起作用。我不知道为什么。这就是我写的: private void btn2ActionPerformed(java.awt.event.ActionEvent evt) { jf1 = new JFrame1(); jf1.getjTextField1().setText(this.jTextField2.getText()); }
  • 实际上它确实设置了 jTextField1 但我在 GUI 上看不到它的文本。
  • 问题是你在做“jf1 = new JFrame1();”活动内。您可能需要的是已经在一个窗口中创建了两个框架,并让“jf1”引用了第一个框架。初始化窗口时创建两个框架。
  • 你的权利。那么,我必须在哪里写“jf1 = new JFrame1();”?
  • 抱歉我还没做。
【解决方案2】:

您可以使用Observer PatternProducer/Consumer Pattern 来解决问题。

基本思想是,您有一些东西可以生成一个值,并且有一些东西想要被通知或消耗生成的值。

您应该花时间学习的其他原则之一也是Code to interface (not implementation)。这听起来很奇怪,但其想法是减少不必要的对象暴露(意外/受控修改)并解耦代码,因此您可以更改底层实现而不影响任何其他依赖它的代码

鉴于您的问题的性质,观察者模式可能更合适。 Swing 的大部分监听器都是基于相同的原理。

我们首先定义“生成器”将用于提供更改通知的合同...

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

【讨论】:

  • 我喜欢您的解决方案,我相信很多人都会从中受益。但我有一个问题要问你。根据 OP,两个框架都需要能够相互更新。那么在这种情况下,您是否要让两个框架同时实现观察者和可观察者(两个框架都成为生产者和消费者)?因为双方都需要看到对方的更改,并且都需要通知对方的更改。如果我们这样做,设计是否正确?希望你能回复这个..
  • @user3437460 实际上,我建议对第二个窗口使用JDialog,当它关闭时(通过确定按钮),获取要在第二帧上显示的值。但如果需要,双向观察者模式将能够更新两个帧
  • 当有 2 个 JFrame 时,双向观察者模式的代码在 Java 中会是什么样子?如果我对此提出问题,您介意提供解决方案吗?无论如何,谢谢你的回复。很高兴见到你。
  • 嗯,这一切都归结为需求。例如,第二帧我需要一个观察者,它有一个“添加”方法来注册一个观察者,或者你可能有一个控制器,它位于然后管理关系
  • @Miyagi 请注意,我自己推出了 - PropertyChangeListener 只是观察者模式的一种形式 ;) - 答案更多地是作为原则的一个例子
【解决方案3】:

这是我刚刚编写的一个完整的工作示例:

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。反过来也一样。

【讨论】:

  • @Arashm 不客气 ;) 请确保您不接受其他人的回答,否则我的 tick 将被删除。 ;p
  • @arashm 除非另一个答案当然提出了更好的解决方案;)
  • 所以,问题:从 JFrame 扩展,不太推荐;不使用 EDT 初始化 UI,稍后将等待来自操作的更多问题;将整个类暴露给另一个类,其中类的功能不需要完成任务,框架不需要完全了解彼此,因为这会将您的对象暴露给另一个错误/意外使用.一个保护可以执行的功能的接口将是一个更好的解决方案。虽然它可能有效,但这是新开发人员应该学会避免的一系列不良做法
  • eugenioy 的回答确实有效。现在我的问题是我必须在哪里写“jf1 = new JFrame1();”?
  • @MadProgrammer 我在代码中省略了一些东西。事实上,我通常不会从 JFrame 扩展。大多数时候,我从 JPanel 扩展并使用 JFrame 添加它。我认为 OP 应该能够从代码中推断出如何传递特定组件的引用而不是整个 JFrame。也许您也可以发布您的解决方案? :)
猜你喜欢
  • 1970-01-01
  • 2013-12-17
  • 2018-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
相关资源
最近更新 更多