【问题标题】:return a variable value to main on button click在按钮单击时将变量值返回给 main
【发布时间】:2012-08-24 08:59:49
【问题描述】:

我希望每次单击按钮时 main 都应打印 hello(在弹出对话框中)。所以我设计了以下程序,但它似乎不起作用。该程序编译并执行得很好,但是当我单击按钮时,我看不到任何对话框弹出。我已经放置了布尔变量 (button_clicked) 的 getter 和 setter,其值正在 main() 块中进行测试。 知道的请帮忙..

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

class abc extends JFrame implements ActionListener{

boolean button_clicked = false;
JButton b1;

abc(){
    this.setSize (400, 400);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.createUI();
}

void createUI(){
    this.setLayout(null);
    b1 = new JButton("x");
    b1.setSize(110,30);
    b1.setLocation(10,210);
    this.add(b1);

    b1.addActionListener(this);
}

public boolean isButton_clicked() {
    return button_clicked;
}

public void setButton_clicked(boolean button_clicked) {
    this.button_clicked = button_clicked;
}


public void actionPerformed(ActionEvent arg0) {
    button_clicked = true;

    //I don't want to print the dialogue box from here..
    //I want to keep everything under main()'s control.
}

}


public class tempMain extends JFrame {

public static void main(String[] args) {
    abc temp = new abc();
    temp.setVisible(true);
    while(true){
        if(temp.isButton_clicked())
            JOptionPane.showMessageDialog(null, "Hello");
    }
}

}

【问题讨论】:

  • 你不应该使用这样的while循环。这有很多设计缺陷。您的 While 循环将 1 占用 CPU,因为它从不休眠。如果您必须使用这样的while循环,那么至少在一个新线程中创建它并在每次迭代后使线程休眠。然而,这仍然是一个糟糕的设计。
  • 为什么你的代码中有 cmets?如果你要坚持为你的程序设计一个糟糕的设计,至少要证明它的理由。
  • @Hovercraft:我猜这个评论是在请求 modeless 对话并播放PropertyChangeListener 卡片。
  • @trash:你的猜测和其他人一样好,因为原始发帖人似乎不想透露他请求背后的动机。
  • 请学习java命名约定并遵守它们。在您学习的过程中:永远不要手动调整/定位组件,这是合适的 LayoutManager 的专属任务。

标签: java swing jframe jbutton propertychangelistener


【解决方案1】:

JOptionPane.showMessageDialog()调用移到actionPerformed()方法下,删除while()事物在main方法下。

【讨论】:

  • 代码中有一条特定的注释说明此解决方案不可取。我不知道为什么,但程序员不想这样做。
  • @rlinden:原始发帖人需要证明他糟糕的设计决定的理由。在他这样做之前,Dan 的建议是最好的。
  • @HovercraftFullOfEels:问题是上面的代码 sn-p 是大型程序的一部分,其中 abc 类将被重新用于许多其他类似的未来应用程序。在实际代码中,有一个特定的类处理对话框的打印并保持面向对象的完整性,我需要将控制权传递给一个完全不同的类中的函数。 abc 类只处理程序的 GUI 部分,其余功能被调制到代码的不同模块。希望你明白我的意思。只是在寻找解决方法..
  • @Vivek:您需要就您的确切要求提供更具体的信息。否则,如果您在此处使用无限循环,我们将无法给出除此之外的具体建议。
  • @HovercraftFullOfEels:嗯,实际上这是一个很长的代码。顺便说一句,我摆脱了无限循环。谢谢你。我想要的是,一旦有人点击按钮,另一个类中的某些功能就会得到提示,并基于文本字段中的值(假设有用户输入值的文本字段),执行一些业务逻辑并给出输出因此..不希望一切都在 actionPerformed() 下发生。我将在上面的评论中阅读您的垃圾狗发布的 MVC 示例。再次感谢您。
【解决方案2】:

您可能想了解"How to Write an Action Listener",以帮助您在代码中实现ActionListner

您的代码的基本思想是:

  • 声明一个事件处理类
  • 使用您的JButton 将事件处理程序类的实例注册为侦听器
  • 在侦听器接口中包含实现方法的代码。在您的情况下,您将覆盖actionPerformed() 并在那里编写您的逻辑以显示一个对话框。 "How to Make Dialogs" 将是另一个对您有用的教程。

【讨论】:

  • 问题是上面的代码 sn-p 是一个巨大的程序的一部分,其中 abc 类将被重新用于许多其他类似的未来应用程序。在实际代码中,有一个特定的类处理对话框的打印并保持面向对象的完整性,我需要将控制权传递给一个完全不同的类中的函数。 abc 类只处理程序的 GUI 部分,其余功能被调制到代码的不同模块。希望你明白我的意思。只是在寻找解决方法..
  • @VivekSethi:所以你基本上希望当用户点击JButton时,控制权转移到另一个对象。您的 abc 类是否会引用该单独类的实例?如果是,那么您可以覆盖actionPerformed() 并调用其他类的适当方法
【解决方案3】:

正如@Quinman 所指出的,您的代码设计确实存在缺陷。我了解您不希望出于某些我不理解的个人原因将 JOptionPane 置于 actionperformed 方法下。基于这个前提,我认为最好的解决方案是创建一个回调,即让你的 JFrame 知道主类并在单击按钮时调用它。

可以使这种机制独立于主类。请查看Observer design pattern 以了解如何执行此操作。

您的代码还有另一个缺陷 - 单击按钮时,我会收到无限的 Hello 消息。为了避免这种情况,您应该将 button_clicked 变量设置为 false。我只提到作为一般提示,因为事实上你真的应该摆脱你的时间造成的忙碌等待。

【讨论】:

  • 第二个缺陷很容易纠正。不过谢谢..我的应用程序确实需要我永远等待用户输入(最终会在 while(true){} 下而不是对话框行下)。但我喜欢观察者设计模式。会维基它。谢谢你..
【解决方案4】:

您可能正在寻找一个 无模式 对话框。在这个example 中,名为Observer 的主面板在对话框中侦听ObservedPanel。通过使用PropertyChangeListener,对对话框所做的任何更改都会立即反映在主面板中。

【讨论】:

  • 我认为你是对的,这或只是一个听众模式通常是他正在寻找的。 1+
【解决方案5】:

正如许多人已经指出的那样,您的方法和设计存在缺陷。已经处理过了,我就不多说了,建议大家试试……

abc temp = new abc();
temp.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent evt) {
        JOptionPane.showMessageDialog(null, "Look Ma, I'm in Main...");
    }
});
temp.setVisible(true);

在你的 abc 课堂上......

class abc JFrame implements {
    // build your class as normal

    public void addActionListener(ActionListener listener) {
        b1.addActionListener(listener);
    }    
}

【讨论】:

  • 请你也解释一下这个修改实际上是如何将控制权传递给main的?临时对象是否在这里控制事件侦听器?
  • 是和不是。事件监听器在 main 中,但我们在 temp 中提供了对它的引用。单击按钮时,侦听器在 main 的上下文中被 otified
【解决方案6】:

从您提供的 cmets 来看,您希望将 abc 类(名称很差,不符合 Java 命名标准)用于几个不同的目的,因此您不想包含代码当您按下abc 类中的按钮时执行。

对此有多种解决方案(其中第一个是我的首选)

  • abc 类的构造函数中传递Action,并将Action 耦合到JButton。这样,构造abc 实例的类负责按下按钮时的行为
  • 使abc 抽象并让您的ActionListener 调用该抽象方法。然后,您可以在每次需要不同行为时对此类进行具体实现。

关于您的代码的进一步说明:

  • 摆脱 while( true ) 循环
  • 摆脱null 布局,改用LayoutManager
  • 应在 Event Dispatch Thread 上创建和访问 Swing 组件。有关更多信息,请参阅 Concurrency in Swing 教程

【讨论】:

  • 谢谢.. 我认为第一个应该可以解决问题。如果您可以提供任何相关的示例代码..任何链接..??
  • @VivekSethi 见the Action tutorial
猜你喜欢
  • 2016-07-10
  • 2020-04-25
  • 1970-01-01
  • 1970-01-01
  • 2020-01-20
  • 2016-01-11
  • 2019-04-09
相关资源
最近更新 更多