【问题标题】:Editing JLabel from JTextField in another class在另一个类中从 JTextField 编辑 JLabel
【发布时间】:2016-04-19 19:38:12
【问题描述】:

我环顾四周,但似乎没有任何帮助。基本上我正在编写一个带有 gui 的多线程聊天程序。用户在 Login 类的文本字段中输入他的名字,然后点击登录按钮,该按钮将他引导到 ClientGUI 类。在客户端 GUI 类中,顶部有一个 JLabel,上面写着

“欢迎来到聊天系统(用户名)”

。因此,登录类中文本字段中的用户输入应该出现在“欢迎使用 ChatSystem”之后的 JLabel 中,但我不知道为什么它不起作用。这是我的代码:

登录类:

loginB = new JButton("Login");
main.add(loginB);
loginB.addActionListener(new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        ClientGUI clientgui = new ClientGUI();
        clientgui.setVisible(true);
    }
}

ClientGUI 类:

public ClientGUI(){
    Login login = new Login();
    String username = login.usernameTF.getText();
    welcome = new JLabel("Welcome to ChatSystem "+username, SwingConstants.CENTER);

}

我知道用户名实际上应该是 JLabel 而不是字符串,但我已经尝试了很多方法来做到这一点,但我似乎无法理解这一点。

【问题讨论】:

    标签: java swing jlabel jtextfield


    【解决方案1】:

    那是行不通的,因为 login.usernameTF.getText();其实是ClientGUI构造函数中新创建的对象...

    我建议做的是重载构造函数并将名称作为参数传递......

    示例:

     loginB.addActionListener(new ActionListener(){
         @Override
         public void actionPerformed(ActionEvent e) {
         ClientGUI clientgui = new ClientGUI(getTheNameAndpassItHere);
         clientgui.setVisible(true);
                }
            }
    

    然后是 ClientGUI 类:

    public ClientGUI(String username){
    
        //Login login = new Login();
       // String username = login.usernameTF.getText();
    
        welcome = new JLabel("Welcome to ChatSystem "+username, SwingConstants.CENTER);
    
    }
    

    【讨论】:

    • 谢谢,它似乎有效,但如果你能向我解释为什么在构造函数中创建一个新对象并不能解决问题,那将会很有帮助
    • 不是因为在构造函数内部,而是因为您正在创建一个新的登录名,并且所有日期都是新的,与您之前的登录名无关
    • 好的,我现在明白了,谢谢。当我像这样设置可见的框架时,在 ClientGUI 的主要方法中,我遇到了另一个问题:“new ClientGUI(username).setVisible(true);”我收到一个错误,它说用户名无法解析为变量。你知道如何解决这个问题吗?抱歉,我知道这一定是个愚蠢的问题,但我是 Java 新手
    • 用户名是字符串吗??如果是,在哪里定义?
    • 用户名是在构造函数之外定义的字符串。在构造函数内部,我调用 this.username = username 来匹配用户名的构造函数参数。然后它告诉我它在哪里说“new ClientGUI(username).setVisible(true);”在用户名下将其更改为静态。根据过去的经验,我被告知永远不要将变量更改为静态变量,除非我明白为什么要这样做
    【解决方案2】:

    基本上,您应该使用Observer Pattern,它允许ClientGUI 在发生变化时向相关方生成事件。

    这会解耦您的代码并防止 ClientGUI 做它不应该做的事情(例如删除标签或其父组件)

    如果它们满足您的需求,您可以使用一些内置的侦听器,但对于这样的事情,我更喜欢使用我自己的

    public class LoginEvent extends EventObject {
    
        private Throwable cause;
        private String userName;
    
        public LoginEvent(Object source) {
            super(source);
        }
    
        public Throwable getCause() {
            return cause;
        }
    
        public String getUserName() {
            return userName;
        }
    
    }
    
    public interface LoginListener extends EventListener {
        public void loginFailed(LoginEvent evt);
        public void loginSuccessful(LoginEvent evt);
    }
    

    然后您可以将侦听器的实例添加到ClientGUI...

    loginB.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            ClientGUI clientgui = new ClientGUI(getTheNameAndpassItHere);
            clientgui.addLoginListener(new LoginListener() {
                @Override
                public void loginFailed(LoginEvent evt) {
                    Throwable cause = evt.getCause();
                    // Show error message
                }
    
                @Override
                public void loginSuccessful(LoginEvent evt) {
                    String name = evt.getUserName();
                    // Update UI
                }
            });
            clientgui.setVisible(true);
        }
    }
    

    或类似的东西

    【讨论】:

    • 获取文本并将其传递给 ClientGUI 似乎可行,但我也对其他方法感兴趣。我读了一些关于观察者模式的文章,看看它们是如何工作的,但似乎不太了解(我是一个相当新的程序员)。您能否解释一下您的方法与仅获取文本并将其传递给构造函数(如果有)相比有什么优势?
    • 如果您将标签添加到ClientGUIClientGUI 将; 1- 总是需要JLabel,所以突然间如果你想更新 UI 的其他方面,你突然需要向它传递更多的对象。如果您不想用 JLabel 更新 UI,可能会发生什么情况?您将两者紧密耦合在一起,这使得扩展或修改变得困难; 2- 以这种方式更新 UI 并不是ClientGUI 真正的责任; 3- ClientGUI 不能对你的 UI 做你不想要的事情。例如,没有什么能阻止它移除标签
    • 嗯,但您不是也通过 ClientGUI 构造函数传递名称吗?
    • 不,您正在传递一份“合同”,它限制了 ClientGUI 对您的了解以及它可以做什么,将响应事件的责任以及您对事件的处理方式转交给了观察者和解耦代码,因为你可以传递你想要的观察者的任何实现,它不会改变ClientGUI的功能
    • 这样想,如果你给我一个 JLabel,我可以做一些你不希望或不想要的讨厌的事情,改变颜色,改变字体,将文本设置为我想要的任何东西想要,但我也可以访问父容器,我可以删除或添加其他组件,更改容器的布局和其他属性,但我也可以访问窗口并可以关闭它,所有这些都没有你能够阻止我
    【解决方案3】:

    默认情况下,swings 组件是私有的,您只需几步即可将它们公开 1.转到组件的属性,然后到代码选项卡 2.你会发现变量修饰符是私有的,如果你愿意的话,它们也可以是公开的,也可以是静态的。

    您现在可以使用相同代码的组件

    【讨论】:

    • 我不认为更改变量的保护值是最好的方法,但也许可以向变量添加访问器和修改器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-24
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 1970-01-01
    • 2015-08-03
    • 2015-03-11
    相关资源
    最近更新 更多