【问题标题】:Using an inner class actionListener in another class在另一个类中使用内部类 actionListener
【发布时间】:2014-11-23 19:24:14
【问题描述】:

所以我使用链表创建了这个队列,这是一个进入队列的 Job 对象。我只使用这 2 个类文件使程序工作,但现在我试图让它与 GUI 一起工作。

我希望能够使用 Queue 和 Job 文件从我的 GUI 主方法运行我的程序。我创建的 GUI 有 8 个按钮和一个用于输出的 JTextArea。我希望能够通过单击按钮来执行每个功能(入队、显示队列长度等)。

我的查询结束了

PS。省略了原始的 main 方法以保持重点。

这是我进入队列的 Job 对象,这里是一般的东西...省略了 getter/setter:

public class Job 
{

String ID; //(A unique number to identify each print job)
String userID; //(The login of the user that sent the document to print)
String documentName; //(The name of the document being printed)
int fileSize; //(Size of the document being printed in Kb’s)

public Job(String p, String u, String e, int f) 
{ //local variables n,t,e only used in this method
    printID = p;
    userID = u;
    documentName = e;
            fileSize = f;
}

这是带有构造函数和方法的 Queue 类...这些都可以正常工作。

public class Queue<Item> implements Iterable<Item> 
{
private int N;         // number of elements on queue
private Node first;    // beginning of queue
private Node last;     // end of queue



// helper linked list class
private class Node 
{
    private Item item;
    private Node next;
}

/**
 * Initialises an empty queue.
 */
public Queue() 
{
    first = null;
    last  = null;
    N = 0;
  //  assert check();
}

//is the list empty?
public boolean isEmpty() 
{
    return first == null;
}

//gives number of elements in the queue
public int length() 
{
    return N;     
}


 //looks at first item, if it is empty then return error. If it has something then return
 the   content of the element.
 public Item peek() 
 {
    if (isEmpty()) throw new NoSuchElementException("Nothing in queue");
    return first.item; 
 }

//add an item
 public void enqueue(Item item) 
{
    Node oldlast = last;  //move the current last to a placeholder
    last = new Node();  //create a new node inside of last
    last.item = item; //place the item i passed to the method call to the new last's item area
    last.next = null; //set the end of the queue
    if (isEmpty())   //checks the rest of the queue
        first = last;  //if empty creates a queue of 1 element length
    else           
        oldlast.next = last; //if not empty then previous last will point to this new one
    N++; //increment the number of elements being tracked.

}

 //remove an item
 public Item dequeue() 
 {
    if (isEmpty()) throw new NoSuchElementException("Nothing in queue");
    Item item = first.item;
    first = first.next;
    N--;
    if (isEmpty()) last = null;   // to avoid loitering

    return item;
}

这是我的图形用户界面:

public class GUI {   

  public static void main(String[] args) 
  {        
    Queue s = new Queue();

    JFrame frame = new JFrame("test");
    frame.setVisible(true);
    frame.setSize(500,500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



    JPanel panel = new JPanel(new GridBagLayout());
    frame.getContentPane().add(panel, BorderLayout.NORTH);

    GridBagConstraints c = new GridBagConstraints();

    JButton button1 = new JButton("Enqueue a print job");
    c.gridx = 0;
    c.gridy = 0;
    c.insets = new Insets(10,10,10,10);
    panel.add(button1, c);
    button1.addActionListener(new Enqueue(){});

    JButton button2 = new JButton("Dequeue a print job");
    c.gridx = 0;
    c.gridy = 1;
    panel.add(button2, c);
    button2.addActionListener(new Dequeue(){});

    JButton button3 = new JButton("is the queue empty?");
    c.gridx = 1;
    c.gridy = 0;
    panel.add(button3, c);
    button3.addActionListener(new empty(){});

    JButton button4 = new JButton("Print first in queue");
    c.gridx = 1;
    c.gridy = 1;
    panel.add(button4, c);
    button4.addActionListener(new first(){});

    JButton button5 = new JButton("Length of queue");
    c.gridx = 0;
    c.gridy = 2;
    panel.add(button5, c);
    button5.addActionListener(new length(){});

    JButton button6 = new JButton("Print entire queue");
    c.gridx = 1;
    c.gridy = 2;
    panel.add(button6, c); 
    button6.addActionListener(new printAll() {});

    JTextArea jTextArea = new JTextArea();


    c.gridx = 4;
    c.gridy = 4;
    frame.add( jTextArea, BorderLayout.SOUTH);

这是有问题的内部类(在 GUI 文件中):我在这里做错了什么?我尝试过引用“s”队列,但是对于这个单独的类,队列在主类之外不存在;这意味着我无法对其执行功能。

 static class length implements ActionListener
 {
 public void actionPerformed (ActionEvent e) 
    { 
         System.out.println("The length of the queue is: " + s.length() +"\n");
    }
 }

当我知道如何处理这个时,我会制作更多的 actionListener。

附言。如果您知道如何从我在 GUI 文件的 main 方法中创建的 actionListener 写入 JTextArea,而不是使用 Sys out,那也会对我有所帮助!

这是我第一次尝试使用 GUI,所以任何见解都会很棒。谢谢:)

【问题讨论】:

  • 我在 GUI 中看不到任何内部类 - 只有 PrintQueue 中的一个内部类。
  • 类名大写。这是 Java 程序员普遍遵守的约定。不要违反它。
  • alfasin - 也许我对术语感到困惑,最后一个代码块就在 GUI 代码块的末尾,同一个类文件。 ncmathsadist - 好的会考虑到这一点,我通常会在最后清理它

标签: java object user-interface queue actionlistener


【解决方案1】:

你声明:

PrintQueue s = new PrintQueue();

main() 方法内 - 这意味着它只能在 main() 内(方法范围)使用。 如果你想在方法之外使用它,你必须将它声明为类成员并通过“get()”方法公开它。

例如:

public class GUI { 

  static PrintQueue s = null;  

  public static void main(String[] args) {        
    s = new PrintQueue();
    ...
  }

  public PrintQueue getS() {return s;}

然后你就可以使用它了:

public void actionPerformed (ActionEvent e) { 
     System.out.println("The length of the queue is: " + s.length() +"\n"); //from the same class
}

或从课外使用:

GUI gui = new Gui();
PrintQueue s = gui.getS();

评论
我不确定 main() 是否是实例化 PrintQueue 的正确位置 - 可能是这样,但也可能是构造函数是更好的主意。

【讨论】:

  • public static void main(String[] args) { s = new PrintQueue();我已经写了你对这封信所说的一切,但这一点给了我错误:不能从静态上下文中引用非静态变量。我在 actionPerformed 的 sys out 行上也遇到了同样的错误。感谢您的帮助,了解更多
  • @Lurx 如果你想在main() 中初始化它,你必须将参数声明为“静态”。我确定了答案,但更重要的是我的最后一条评论!
【解决方案2】:

我认为以下代码将是添加内部类 ActionListener 的合法示例。我是在我的 IDE 之外编写的,并且经常出错,所以你必须在你的 IDE 中检查它。

在声明中

   final PrintQueue s = new PrintQueue();

在构造函数中

   button1.addActionListener(new ActionCommand()
   {
      public void actionPerformed (ActionEvent e) 
      { 
          System.out.println("The length of the queue is: " + s.length() +"\n");
      }    

   });

要点:

  • 新的 ActionCommand 没有名称,它是匿名的,

  • 内部类中引用的任何变量都必须是final

  • 匿名内部类是一个实际的类,而不是一个类的方法,

  • 内部类应该有一个 actionPerformed 方法作为其定义的一部分。

如果您需要区分几个不同的 JButton,有两种常用的编程方法。

(1) 为 JButton 添加一个“setActionCommand”方法并为该按钮提供一个标识字符串。然后您的所有按钮都可以调用实现 ActionListener 的单个类的新实例(例如您的 Length 类),并且 ActionCommand 字符串可以从 ActionEvent 参数 e 派生并用于分支到代码对应的按钮。

(2) 为每个按钮创建一个单独的内部类 ActionListener 并为该按钮自定义 actionPerformed 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-17
    • 1970-01-01
    • 2017-01-26
    • 2015-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多