【问题标题】:Is it a good way to use PropertyChangeListener interface?使用 PropertyChangeListener 接口是不是一个好方法?
【发布时间】:2013-11-29 01:44:19
【问题描述】:

我对 fireIndexedPropertyChange() 方法的深层含义和使用存在疑问,该方法触发将被 propertyChange() 侦听器拦截和处理的事件我在另一个类中声明。

例如,在一个使用 JButton 实现登录 GUI(显示登录表单)的类中,当用户单击我的按钮时,我会执行此方法:

@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    System.out.println("Button cliccked");

    Main listener = new Main();                         // I intantiate a new Main object to have the PropertyChangeListener
    this.addPropertyChangeListener(listener);           // I add the PropertyChange Listener to this LoginFrame object

    /* I fire a PropertyChange: the event start and will be handled by the propper propertyChange() method definied in the
     * listener class: 
     * 
     * @param "loginButtonClicked" 
     * */
    firePropertyChange("loginResult", false, loginResult);   


}

因此,当尚未登录的用户单击我的按钮时,将执行此方法并触发新的 PropertyChange 事件。

我的 PropertyChange 事件本身包含以下信息:

  1. propertyName 是可以更改的属性的名称(在我的示例中名为 loginResult,因为我有一个名为 的布尔变量loginResult,如果用户点击按钮可以登录,则为true,否则为false

  2. old value 是可以更改的属性的旧值(在我的示例中为 false,因为如果用户看到登录窗口,则意味着它没有登录并且loginResul=false

  3. 新值:在这种情况下,它是 loginResult 变量的内容(如果用户正在系统中登录,则为 true)

所以这个 PropertyChange 事件将被我的 propertyChange() 方法(在侦听器类中声明)拦截,该方法根据这些参数处理它:例如在下面方式:

** 如果propertyName 是loginResult 并且如果新值为true,则不再显示登录窗口,而是显示主应用程序窗口**

我的推理是否正确,这可能是使用 PropertyChangeListener 接口的好方法吗?

Tnx

安德烈亚

【问题讨论】:

  • 您到底想达到什么目的?每次单击按钮时创建一个新的 Main 并添加一个新的侦听器看起来完全错误,但我不确定你想做什么。登录成功是否显示主框架?
  • 作为一般性注释,以便我们集中在一个共同的词汇上,java 中的事件不是被拦截的;这意味着在听众得到它们之后它们会去其他地方。您可以使用“已收到”或“已处理”。我不知道这是否是其他语言的正确术语,但我从未在 java 中听说过它
  • @JBNizet 是的,如果登录成功,我想显示主框架。你完全正确:每次用户单击按钮时创建一个新的 Main 对象是非常愚蠢的事情......所以现在我将它创建一次作为没有 LoginFrame 构造函数的静态变量......所以我认为它更好

标签: java swing user-interface propertychangelistener propertychangesupport


【解决方案1】:

您可以这样使用它,它会起作用。但我认为您的问题更多是关于语义,而不仅仅是它是否有效。该接口的包是java.beans,它将它放在bean 的上下文中。如果您在 bean 上下文中使用它,即您的事件发布者是 bean,那么我认为接口的“深层含义”与您的使用一致。 javadoc 说

每当 bean 更改“绑定”属性时,都会触发“PropertyChange”事件。

如果您认为 bean 不适合,请创建您自己的

【讨论】:

    【解决方案2】:

    没有理由使用事件来实现您的用例。你过度设计简单的东西。代码应如下所示:

    @Override
    public void actionPerformed(ActionEvent e) {
        String login = loginTextField.getText();
        char[] password = passwordField.getPassword();
        boolean loginSuccessful = authenticationService.authenticate(login, password);
        if (loginSuccessful) {
            Main main = new Main();
            main.setVisible(true);
            this.setVisible(false);
        }
        else {
            displayErrorMessage("Login failed");
        }
    }
    

    【讨论】:

    • 这是对的,但我认为我不能这样做,因为:1) Main 不是一个实现 Swing GUI 的类,而是一个声明并创建了我的 GUI 对象的类,并且听众。所以我必须使用事件来:在 Main 类中执行一个侦听器方法,这个方法必须在 LoginFrame 对象上 setVisible(false) 和在我的主 GUI 对象上 setVisible(true)(创建到 Main 类中)跨度>
    • 不,没有理由这样做。如果 Main 不是 JFrame,但有显示 JFrame 的方法,则调用此方法:Main main = new Main(); main.createAndDisplayFrame();
    • 这是一篇旧文章,但人们可能仍在阅读它,所以要明确一点:这是你能做的最糟糕的方法。如果身份验证很耗时(因为它是联网的),那么您的窗口将挂在那里。你不应该在 GUI 线程中做任何东西,除了 GUI 的东西。使用 PropertyChangeListener。
    • @Chlorek 使用 PropertyChangeListener 不会神奇地在单独的线程中执行身份验证服务调用。 如果身份验证太长而无法在 UI 线程中处理,那么是的,当然最好在单独的线程中进行。但 PropertyChangeListener 与此无关。你需要一个 SwingWorker。
    • 好吧,PropertyChangeListener 不会“神奇地”在另一个线程中执行您的网络代码,但是如果您有另一个带有网络代码的线程,那么它可以安全地调用属性更改,并且 GUI 线程会收到通知。
    猜你喜欢
    • 1970-01-01
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2019-02-19
    • 2022-01-19
    • 2013-03-01
    • 2015-01-04
    相关资源
    最近更新 更多