【问题标题】:Event Handling Swing components事件处理 Swing 组件
【发布时间】:2017-03-16 13:22:15
【问题描述】:

我正在尝试一点一点地学习 Java,重新创建一个我用 Python 完成的应用程序——一个库控制软件,非常基础。不过,我在使用事件处理时遇到了问题,主要是因为(我认为)我在对 Swing 了解不多的情况下完全进入了 Swing,但在我去的时候就弄清楚了。

到目前为止,这是我的代码:

public class SEHBV extends JFrame{

    public SEHBV(){

        super("SEHBV Biblio 2.0");
        ImageIcon img = new ImageIcon("books.ico");
        setIconImage(img.getImage());

        JPanel p_ini, locar, devolver, buscar, administrar;
        JLabel l_dia, l_mes, l_ano, loca_cs, loca_cl, loca_prazo, loca_cb, locado_state;
        JTextField dia, mes, ano, loca_cs_tf, loca_cl_tf, loca_prazo_tf, loca_cb_tf, devolve_cod;
        JTextArea loca_prazo_data, loca_oper_res, mostra_multa;
        JButton data, loca_cb_bt, loca_commit, ver_multa;
        JList<String> loca_s_res, loca_cb_res, atrasos, locados;


        p_ini = new JPanel(new GridBagLayout());
        GridBagConstraints i = new GridBagConstraints();
        l_dia = new JLabel("Dia: ");
        l_mes = new JLabel("Mês: ");
        l_ano = new JLabel("Ano: ");
        dia = new JTextField(6);
        mes = new JTextField(6);
        ano = new JTextField(6);
        data = new JButton("Afirmar Data");
        atrasos = new JList<String>();  
        atrasos.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        atrasos.setLayoutOrientation(JList.VERTICAL);
        atrasos.setVisibleRowCount(10);
        JScrollPane scroll_atrasos = new JScrollPane(atrasos);
        atrasos.setBackground(Color.WHITE);
        atrasos.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));

        i.fill = GridBagConstraints.HORIZONTAL;
        i.gridx = 0;
        i.gridy = 0;
        p_ini.add(l_dia, i);
        i.gridx = 1;
        p_ini.add(dia, i);
        i.gridx = 2;
        p_ini.add(l_mes, i);
        i.gridx = 3;
        p_ini.add(mes, i);
        i.gridx = 4;
        p_ini.add(l_ano, i);
        i.gridx = 5;
        p_ini.add(ano, i);
        i.gridx = 6;
        p_ini.add(data, i);
        i.gridy = 1;
        i.gridx = 0;
        i.gridwidth = 7;
        p_ini.add(scroll_atrasos, i);

        //GUI Locação 
        locar = new JPanel(new GridBagLayout());
        GridBagConstraints l = new GridBagConstraints();
        l.gridx = 0;
        l.gridy = 0;
        JPanel loca_socios = new JPanel(new FlowLayout());
        JPanel loca_oper = new JPanel(new GridBagLayout());
        GridBagConstraints o = new GridBagConstraints();
        JPanel loca_busca = new JPanel(new GridBagLayout());
        GridBagConstraints b = new GridBagConstraints();


        locar.add(loca_socios, l); //Busca de Sócios na janela de Locação

        loca_s_res = new JList<String>();
        loca_s_res.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        loca_s_res.setLayoutOrientation(JList.VERTICAL);
        loca_s_res.setModel(Runner.nome_socios);
        loca_s_res.setVisibleRowCount(25);
        JScrollPane scroll_loca_s = new JScrollPane(loca_s_res);
        loca_s_res.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
        loca_socios.add(scroll_loca_s);

        l.gridx = 1;
        locar.add(loca_oper, l); //Locação propriamente dita
        o.weighty = 1;
        o.weightx = 1;
        o.anchor = GridBagConstraints.NORTHWEST;
        o.insets = new Insets(1,1,1,1);
        loca_cs = new JLabel("Código do Sócio: ");
        o.fill = GridBagConstraints.HORIZONTAL;
        o.gridx = 0;
        o.gridy = 0;
        loca_oper.add(loca_cs, o);

        loca_cs_tf = new JTextField(5);
        loca_cs_tf.setEditable(false);
        loca_cs_tf.setBackground(Color.WHITE);
        o.fill = GridBagConstraints.BOTH;
        o.gridx = 1;
        o.gridy = 0;
        loca_oper.add(loca_cs_tf, o);

        loca_cl = new JLabel("Código do Livro: ");
        o.fill = GridBagConstraints.BOTH;
        o.gridx = 0;
        o.gridy = 1;
        loca_oper.add(loca_cl, o);

        loca_cl_tf = new JTextField(5);
        o.fill = GridBagConstraints.BOTH;
        o.gridx = 1;
        o.gridy = 1;
        loca_oper.add(loca_cl_tf, o);

        loca_prazo = new JLabel("Prazo para devolução (em dias): ");
        o.fill = GridBagConstraints.BOTH;
        o.gridx = 0;
        o.gridy = 2;
        loca_oper.add(loca_prazo, o);

        loca_prazo_tf = new JTextField(5);
        o.fill = GridBagConstraints.BOTH;
        o.gridx = 1;
        o.gridy = 2;
        loca_oper.add(loca_prazo_tf, o);

        loca_prazo_data = new JTextArea();
        loca_prazo_data.setBackground(getForeground());
        o.gridx = 0;
        o.gridy = 3;
        o.gridwidth = 3;
        loca_oper.add(loca_prazo_data, o);

        loca_commit = new JButton("Realizar Locação");
        o.fill = GridBagConstraints.BOTH;
        o.gridx = 0;
        o.gridy = 4;
        o.gridwidth = 3;
        loca_oper.add(loca_commit, o);


        loca_oper_res = new JTextArea();
        loca_oper_res.setBackground(getForeground());
        o.gridy = 5;
        loca_oper.add(loca_oper_res, o);

        l.gridx = 2;
        locar.add(loca_busca, l);
        loca_cb = new JLabel("Chave de Busca: ");
        b.fill = GridBagConstraints.HORIZONTAL;
        b.gridx = 0;
        b.gridy = 0;
        loca_busca.add(loca_cb, b);

        loca_cb_tf = new JTextField(20);
        b.fill = GridBagConstraints.HORIZONTAL;
        b.gridx = 1;
        b.gridy = 0;
        loca_busca.add(loca_cb_tf, b);

        loca_cb_bt = new JButton("Busca Rápida");
        b.fill = GridBagConstraints.HORIZONTAL;
        b.gridx = 2;
        b.gridy = 0;
        loca_busca.add(loca_cb_bt, b);

        loca_cb_res = new JList<String>();
        loca_cb_res.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        loca_cb_res.setLayoutOrientation(JList.VERTICAL);
        b.fill = GridBagConstraints.HORIZONTAL;
        loca_cb_res.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
        b.gridx = 0;
        b.gridy = 1;
        b.gridwidth = 3;
        b.gridheight = 2;
        loca_cb_res.setVisibleRowCount(25);
        JScrollPane scroll_loca_cb = new JScrollPane(loca_cb_res);
        loca_cb_res.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
        loca_busca.add(scroll_loca_cb, b);


    // Other Tabs of the GUI


    //GUI Geral
    JTabbedPane tp = new JTabbedPane();

    tp.addTab("Página inicial (Alt+I)", null, p_ini, "pág. inicial");
    tp.addTab("Locação (Alt+L)", locar);
    tp.addTab("Devolução (Alt+D)", devolver);
    tp.addTab("Busca Avançada (Alt+B)", buscar);
    tp.addTab("Administração (Alt+A)", administrar);
    tp.setMnemonicAt(0, KeyEvent.VK_I);
    tp.setMnemonicAt(1, KeyEvent.VK_L);
    tp.setMnemonicAt(2, KeyEvent.VK_D);
    tp.setMnemonicAt(3, KeyEvent.VK_B);
    tp.setMnemonicAt(4, KeyEvent.VK_A);

    add(tp);
}

所以,假设我正在尝试处理对loca_commit JButton 的点击。我正在尝试创建一个事件处理程序 - 根据 Java 教程和其他 StackOverflow 问题/答案 - 但处理程序无法识别 loca_commit。现在我只是想让它工作,然后我会用它来调用一个方法,但如果我不能让它创建一个弹出窗口,那么你明白我的意思。

所以,到目前为止,我的处理程序代码是这样的:

    private class LocaHandler implements ActionListener{
        public void actionPerformed(ActionEvent event){

            String string = "";

            if(event.getSource()==loca_commit)
                string=String.format("Botão Apertado");

        JOptionPane.showMessageDialog(null, string);
        }

你们能在这里阐明一下吗?

【问题讨论】:

  • 顺便说一句,到目前为止,主要只是调整框架的大小并使框架可见,真正的基本。
  • 注意:当试图弄清楚如何向按钮添加动作监听器时,该示例需要一个按钮和一个动作监听器,而不是 4 个按钮、3 个文本区域、一堆标签和文本字段、3 个列表、一个图像图标.. “顺便说一句,目前主要只是调整大小并使框架可见” 所以我们需要在编译和尝试代码之前对其进行更改。为了尽快获得更好的帮助,请发布minimal reproducible exampleShort, Self Contained, Correct Example。它应该包含 main 方法和导入,但尽可能多地保留其他组件。

标签: java swing jbutton actionlistener


【解决方案1】:

核心问题可能是上下文之一,LocaHandler 可能没有任何上下文到 SEHBVloca_commit 按钮,所以你不能引用它(它脱离了上下文)。

有几种方法可以解决这个问题...

你可以...

loca_commit 的引用传递给LocaHandler 的实例,但除非您打算使用LocaHandler 来处理多个操作,否则它确实没有意义,这意味着...

你可以...

LocaHandler 只负责做一件事,无论loca_commit 需要它做什么。这将带您进入Actions API 的领域

怎么会……

你可以...

利用JButtonActionEventactionCommand属性支持

loca_commit = new JButton("Realizar Locação");
loca_commit.setActionCommand("locaCommit");

//...

private class LocaHandler implements ActionListener{
    public void actionPerformed(ActionEvent event){
        String string = "";

        if("locaCommit".equals(event.getActionCommand()))
            string=String.format("Botão Apertado");

        JOptionPane.showMessageDialog(null, string);
}

这意味着您可以使用LocaHandler 的同一实例来处理多个命令(通过扩展if 语句)

我个人的偏好是使用Actions API或者匿名类,专注于处理单一职责的处理程序,如果做得好,会增加类的可重用性

【讨论】:

  • 谢谢,第三种解决方案应该可以了。每个 JPanel(每个选项卡)都执行多个功能,因此最适合我的情况。
【解决方案2】:

使其工作的一种方法是在初始化按钮后将动作侦听器附加到按钮上。在您的情况下,请尝试以下操作:

loca_commit = new JButton("Realizar Locação");
//other code

loca_commit.addActionListener(new ActionListener() {

      @Override
      public void actionPerformed(ActionEvent e) {
             JOptionPane.showMessageDialog(null, "Hello");
      }
});
loca_oper.add(loca_commit, o);

请记住,这只是一种方法。有多种其他方法可以达到相同的效果。

【讨论】:

    猜你喜欢
    • 2012-04-05
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-11
    • 2012-10-03
    相关资源
    最近更新 更多