简体   繁体   English

Java-调用嵌套类中的方法,特别是ActionListener

[英]Java - Calling methods in a nested class, specifically an ActionListener

Edit: Solved, I wasn't using 'validate()' after adding components. 编辑:解决了,添加组件后我没有使用'validate()'。

I have a GUI class structured something like this (this is a very basic representation of my code): 我有一个结构像这样的GUI类(这是我的代码的非常基本的表示形式):

Edit: here's my full code 编辑:这是我的完整代码

package source;

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

public class Gui extends JFrame 
{
    public String[] list1 = {"equation1","equation2","equation3","equation4", "equation5"};
    public JOptionPane opt1;
    private JButton custom;
    private JTextField[] tf;
    public HandlerClass2 itemhandler = new HandlerClass2();
    private JList list;
    private static int index = 0;
    private static int lastlistindex = 0;
    private JPanel buttonpanel;
    private JPanel buttonpanel2[] = new JPanel[3];
    private JPanel listpanel[] = new JPanel[4];
    private JPanel checkpanel;
    private JCheckBox checkboxes[];
    private SpringLayout layout;
    public Container contentPane;
    private JButton but;

public Gui()
{
    super("Physics Helper v0.1");
    setBackground(Color.DARK_GRAY);

    layout = new SpringLayout();

    contentPane = getContentPane();
    contentPane.setLayout(layout);

    displayPortal();
}

public void displayPortal()
{
    Icon a = new ImageIcon(getClass().getResource("button.png"));    
    Icon b = new ImageIcon(getClass().getResource("button2.png")); 
    custom = new JButton("", a);
    custom.setRolloverIcon(b);

    buttonpanel = new JPanel();
    buttonpanel.setBackground(Color.GRAY);
    buttonpanel.add(custom);
    contentPane.add(buttonpanel);

    layout.putConstraint(SpringLayout.WEST, buttonpanel, 5, SpringLayout.WEST, contentPane);
    layout.putConstraint(SpringLayout.EAST, buttonpanel, -5, SpringLayout.EAST, contentPane);
    layout.putConstraint(SpringLayout.NORTH, buttonpanel, 5, SpringLayout.NORTH, contentPane);

    custom.addActionListener(new HandlerClass());

}

public void displayButton(String s)
{
    but = new JButton(s);

    buttonpanel2[index] = new JPanel();
    buttonpanel2[index].setBackground(Color.GRAY);
    buttonpanel2[index].add(but);

    contentPane.add(buttonpanel2[index]);

    layout.putConstraint(SpringLayout.SOUTH, buttonpanel2[index], -5, SpringLayout.SOUTH, contentPane);

    if (index < 1)
    {
        layout.putConstraint(SpringLayout.WEST, buttonpanel2[index], 5, SpringLayout.WEST, contentPane);
    }
    else
    {
        layout.putConstraint(SpringLayout.WEST, buttonpanel2[index], 5, SpringLayout.EAST, buttonpanel2[index - 1]); 
    }

    index++;
}

public void displayList(String[] t)
{
    list = new JList(t);
    list.setVisibleRowCount(8);
    list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    add(new JScrollPane(list));

    listpanel[lastlistindex] = new JPanel();
    listpanel[lastlistindex].setBackground(Color.GRAY);
    listpanel[lastlistindex].add(list);

    contentPane.add(listpanel[lastlistindex]);

    layout.putConstraint(SpringLayout.NORTH, listpanel[lastlistindex], 5, SpringLayout.SOUTH, buttonpanel);

    if (lastlistindex < 1)
    {
        layout.putConstraint(SpringLayout.WEST, listpanel[lastlistindex], 5, SpringLayout.WEST, contentPane);
    }
    else
    {
        layout.putConstraint(SpringLayout.WEST, listpanel[lastlistindex], 5, SpringLayout.EAST, listpanel[lastlistindex - 1]);
    }

    lastlistindex++;
}

public void displayInputValues(String[] p)
{   
    checkboxes = new JCheckBox[p.length];

    GridLayout gridlayout = new GridLayout(p.length, 2);
    tf = new JTextField[p.length];

    checkpanel = new JPanel();
    checkpanel.setBackground(Color.GRAY);
    checkpanel.setLayout(gridlayout);

    for (int b = 0; b < p.length; b++)
    {
        checkboxes[b] = new JCheckBox(p[b]);
        checkpanel.add(checkboxes[b]);

        tf[b] = new JTextField("", 9);
        checkpanel.add(tf[b]);
        tf[b].setFont(new Font("Serif", Font.PLAIN, 14));
    }

    contentPane.add(checkpanel);

    layout.putConstraint(SpringLayout.EAST, checkpanel, -5, SpringLayout.EAST, contentPane);
    layout.putConstraint(SpringLayout.SOUTH, checkpanel, -5, SpringLayout.SOUTH, contentPane);
}

private class HandlerClass implements ActionListener
{

    public void actionPerformed(ActionEvent event)
    {            
        displayButton("Back");
        displayButton("Next");

        displayList(list1);
    }
}    

My main method is contained within another class, and works fine. 我的主要方法包含在另一个类中,并且工作正常。

My question is how can I call the "displayButton" method in the actionPerformed method? 我的问题是如何在actionPerformed方法中调用“ displayButton”方法? I've tried a few tips already, such as calling it with "Gui.this.displayButton("Press me!"). 我已经尝试了一些技巧,例如使用“ Gui.this.displayButton(“ Press me!”)来调用它。

I have tested every other aspect of my code, and this seems to be the only problem. 我已经测试了代码的所有其他方面,这似乎是唯一的问题。

I get no errors when I run the code. 运行代码时没有错误。

If needs be I can post the full class, but I think this problem lies in trying to call these methods. 如果需要,我可以发布完整的类,但是我认为这个问题在于尝试调用这些方法。

What's your opinion? 你怎么看?

Calling the method works fine, nothing fancy needed 调用该方法效果很好,不需要花哨的东西

You need to add an instance of your HandlerClass to a GUI control, such as a JButton , which will trigger the method when clicked. 您需要将HandlerClass的实例添加到GUI控件(例如JButton ,该控件将在单击时触发该方法。 That is the whole point of ActionListeners (and listeners in general). 这就是ActionListeners (和一般的监听器)的重点。 For example: 例如:

myJButton.addActionListener(new HandlerClass());

A working example based on your code: 根据您的代码的工作示例:

public class Gui extends JFrame
{
    public Gui()
    {
        super("Physics Helper v0.1");
        JButton b = new JButton("Press me!");
        b.addActionListener(new HandlerClass());
        add(b);
        pack();
        setVisible(true);
    }

    public void displayButton(String s)
    {
        System.out.println(s);
    }

    private class HandlerClass implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            displayButton("Press me!");
        }
    }

    public static void main(String[] args)
    {
        new Gui();
    }
}

Adding/removing components in a Container at runtime is possible, but not necessarily good practice. 在运行时在容器中添加/删除组件是可能的,但不一定是好的做法。 If you want to display different contents based on user selections in your GUI, consider using a CardLayout layout manager, which handles all the runtime details automatically. 如果要基于GUI中的用户选择显示不同的内容,请考虑使用CardLayout布局管理器,该管理器会自动处理所有运行时详细信息。

Jim S. 吉姆·S。

Your code should work finely. 您的代码应该可以正常工作。 You will have to addActionListener to a component. 您将必须将ActionListener添加到组件。

Else 其他

You could write the displayButton method within the Handler Class. 您可以在Handler类中编写displayButton方法。 Then you would have to simply call the method as it is with access to the previous class's members. 然后,您只需按原样调用方法即可访问上一个类的成员。

The quick and dirty option is to make the displayButton call static. 快速而肮脏的选项是使displayButton调用变为静态。

Then issue is more a design one than anything else. 那么,问题更多的是设计问题。 I'd suggest you ask yourself why you want your action listener to call a method in the owning object. 我建议您自问,为什么要让动作监听器在拥有对象中调用方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM