【问题标题】:JFrame - ActionListenerJFrame - 动作监听器
【发布时间】:2013-10-08 23:04:21
【问题描述】:

我正在构建一个使用 JFrame 的程序。我想要的最终结果是实现一个 ActionListener,它会在用户单击按钮时删除标签。例如:当用户单击 JButton 时,从框架中删除 5 个标签之一。当他们再次单击该按钮时,剩余的 4 个标签中的一个将被删除……依此类推,直到剩下 0 个标签。从技术上讲,我让程序按要求工作,但是,我试图查看是否有一种方法可以通过循环来实现 ActionListener 事件,而不是为每个单独的标签列出一个 if 语句。非常感谢!

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

//calls for public class to inherit features of JFrame within Java
public class NoPurchaseReason extends JFrame implements ActionListener {

private int removeText = 0;

JButton btn = new JButton("Select");

JLabel lbl = new JLabel("Found better price");
JLabel lbl1 = new JLabel("Not as shown on website");
JLabel lbl2 = new JLabel("Wrong product");
JLabel lbl3 = new JLabel("Damaged upon delivery");
JLabel lbl4 = new JLabel("None of the above");

public static void main(String[] args) {
    JFrame f = new NoPurchaseReason("Please tell us why you wish to return your purchase.");
    f.setBounds(300, 100, 500, 500);
    f.setVisible(true);
    f.setBackground(Color.blue);
}

public NoPurchaseReason(String title) {
    super(title);
    setLayout(null);
    lbl.setBounds(40, 40, 600, 40);
    btn.setBounds(320, 10, 80, 20);
    lbl.setBounds(100, 40, 100, 20);
    lbl1.setBounds(100, 70, 100, 20);
    lbl2.setBounds(100, 100, 150, 20);
    lbl3.setBounds(100, 130, 100, 20);
    lbl4.setBounds(100, 160, 100, 20);

    add(btn);
    add(lbl);
    add(lbl);
    add(lbl1);
    add(lbl2);
    add(lbl3);
    add(lbl4);
    btn.addActionListener(this);
}

public void actionPerformed(ActionEvent e) {
    removeText++;
    if (removeText == 1) {
        lbl.setVisible(false);
        lbl1.setBounds(100, 40, 100, 20);
        lbl2.setBounds(100, 70, 100, 20);
        lbl3.setBounds(100, 100, 150, 20);
        lbl4.setBounds(100, 130, 100, 20);
    }
    if (removeText == 2) {
        lbl1.setVisible(false);
        lbl2.setBounds(100, 40, 100, 20);
        lbl3.setBounds(100, 70, 150, 20);
        lbl4.setBounds(100, 100, 100, 20);
    }
    if (removeText == 3) {
        lbl2.setVisible(false);
        lbl3.setBounds(100, 40, 150, 20);
        lbl4.setBounds(100, 70, 100, 20);
    }
    if (removeText == 4) {
        lbl3.setVisible(false);
        lbl4.setBounds(100, 40, 100, 20);
    }
    if (removeText == 5) {
        lbl4.setVisible(false);
    }
}

}

【问题讨论】:

    标签: java swing jframe jbutton actionlistener


    【解决方案1】:

    从长远来看,学习如何正确使用layout managers将为您省去很多麻烦。

    您还会发现人们会告诉您遵守single responsibility principle,并避免创建违反此原则的类(例如,扩展 JFrame 和实现 ActionListener)。

    您还会听到人们告诉您更喜欢使用操作而不是操作侦听器(也就是说,如果您需要在多个组件之间共享功能)。

    一种简单的方法是将整个面板专门用于保存您的标签,然后简单地删除面板中的第一个标签,直到没有更多标签为止。这是一个例子:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    class LabelDemo
    {
        public static void main(String[] args) {
            String[] labels = {
                    "Found better price",
                    "Not as shown on website",
                    "Wrong product",
                    "Damaged upon delivery",
                    "None of the above"
            };
            final JFrame frame = new JFrame();
            final JPanel panel = new JPanel();
            panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
            for (String s: labels) {
                panel.add(new JLabel(s));
            }
            frame.add(panel);
            JButton button = new JButton("Select");
            button.addActionListener(new ActionListener() {
                @Override public void actionPerformed(ActionEvent e) {
                    if (panel.getComponentCount() > 0)
                        panel.remove(0);
                    frame.repaint();
                }
            });
            frame.add(button, BorderLayout.NORTH);
            frame.pack();
            frame.setVisible(true);
        }
    }
    

    此外,您可能只是有一个我不知道的特定目标,但老实说,在这种情况下,列表似乎会更好。这也是一个例子:

    String[] labels = {
            "Found better price",
            "Not as shown on website",
            "Wrong product",
            "Damaged upon delivery",
            "None of the above"
    };
    JList<String> list = new JList<>(labels);
    int option = JOptionPane.showConfirmDialog(null, list, 
            "Please tell us why you wish to return your purchase.", 
            JOptionPane.OK_CANCEL_OPTION);
    if (option == JOptionPane.OK_OPTION) {
        String selectedValue = list.getSelectedValue();
        System.out.println(selectedValue); // Do something with it.
    }
    

    【讨论】:

    • 非常感谢您提供的示例!这比我的代码简洁多了。我似乎遇到的唯一麻烦是当我尝试实现您提供的第一个示例时,我继续收到以下错误:令牌“setLayout”上的语法错误,=此令牌之后的预期----不太确定为什么这是怎么回事?
    • 这些例子需要直接粘贴到方法中,而不是类中(我在main方法中写得很快)。只有声明可以存在于方法之外,在这种情况下,错误发生在setLayout,因为它不是声明,而是方法调用,因此它必须进入某个方法内部。当我编写它们时,我并没有真正使用您的代码作为基础,所以它并不是那么“面向对象”——对此感到抱歉。我在第一个示例中添加了额外的代码,以说明我在说什么。
    • 太完美了!出于某种原因,我以为我将 setLayout 放在我的方法中,但显然我没有。我非常感谢您的所有帮助。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2013-12-24
    • 2011-09-26
    • 2013-12-06
    • 1970-01-01
    相关资源
    最近更新 更多