Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 动作初始化中的差异_Java_Swing_Event Handling_Action - Fatal编程技术网

Java 动作初始化中的差异

Java 动作初始化中的差异,java,swing,event-handling,action,Java,Swing,Event Handling,Action,我试图创建一个程序,其中Action类是一个类的内部类,但其对象的初始化发生在另一个类中,但我总是遇到异常。下面我将介绍我的问题的简化模型: 有一个类用于构建GUI并包含内部操作类: import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; public class So

我试图创建一个程序,其中Action类是一个类的内部类,但其对象的初始化发生在另一个类中,但我总是遇到异常。下面我将介绍我的问题的简化模型:

有一个类用于构建GUI并包含内部操作类:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

public class SomeClass {
    JTextArea area;
    public static void main(String[] args){
        SomeClass outerAction = new SomeClass();
        outerAction.go();
    }
    public void go(){
    JFrame frame = new JFrame();
    area = new JTextArea(5,10);
    JToolBar toolBar = new JToolBar(SwingConstants.HORIZONTAL);
    CreateAction createAction = new CreateAction();
    JButton button1 = new JButton(innerGetAction());
    JButton button2 = new JButton(createAction.otherGetAction());
    toolBar.add(button1);
    toolBar.add(button2);

    frame.getContentPane().add(BorderLayout.PAGE_START,toolBar);
    frame.getContentPane().add(BorderLayout.CENTER,area);
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
}
public Action innerGetAction(){
    Action action = new SomeAction("DO","Do sth",KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
    return action;
}
    public class SomeAction extends AbstractAction{
        public SomeAction(String name, String desc, KeyStroke key){
            super(name);
            putValue(SHORT_DESCRIPTION,desc);
            putValue(ACCELERATOR_KEY,key);
        }
        public void actionPerformed(ActionEvent e) {
            area.setText("Done");
        }
    }
}
有两个具有相同操作的JButton,但是第一个的初始化发生在SomeClass中,另一个发生在单独的CreateActionClass中:

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

public class CreateAction {
    public static Action otherGetAction(){
        Action action = new SomeClass().new SomeAction("DO","Do sth",KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
        return action;
    }
}
一个按钮工作正常,另一个按钮例外。我不明白为什么

你能告诉我:

  • 为什么CreateAction类中初始化的操作没有来自SomeClass的acces to字段? 如果getAction是某个类的方法,一切正常,它可以修改JTextArea,但是当它是CreateAction的方法时,会出现java.lang.NullPointerException。有什么区别
  • 在不同的类中初始化Action对象,而不是在其Action类和构造函数中进行初始化,这有意义吗
  • 请原谅我可怜的例子

    堆栈跟踪:

    线程“AWT-EventQueue-0”java.lang.NullPointerException中出现异常 在SomeClass$SomeAction.actionPerformed(SomeClass.java:40) 在javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) 位于javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346) 在javax.swing.DefaultButtonModel.fireActionPerformed上(DefaultButtonModel.java:402) 在javax.swing.DefaultButtonModel.setPressed中(DefaultButtonModel.java:259) 在javax.swing.plaf.basic.BasicButtonListener.MouseRelease(BasicButtonListener.java:252) 在java.awt.AWTEventMulticaster.mousererelease(AWTEventMulticaster.java:289) 位于java.awt.Component.ProcessMouseeEvent(Component.java:6525) 位于javax.swing.JComponent.ProcessMouseeEvent(JComponent.java:3321) 位于java.awt.Component.processEvent(Component.java:6290) 位于java.awt.Container.processEvent(Container.java:2234) 位于java.awt.Component.dispatchEventImpl(Component.java:4881) 位于java.awt.Container.dispatchEventImpl(Container.java:2292) 位于java.awt.Component.dispatchEvent(Component.java:4703) 位于java.awt.LightweightDispatcher.RetargetMouseeEvent(Container.java:4898) 位于java.awt.LightweightDispatcher.ProcessMouseeEvent(Container.java:4533) 位于java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462) 位于java.awt.Container.dispatchEventImpl(Container.java:2278) 位于java.awt.Window.dispatchEventImpl(Window.java:2739) 位于java.awt.Component.dispatchEvent(Component.java:4703) 位于java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746) 在java.awt.EventQueue.access$400(EventQueue.java:97) 位于java.awt.EventQueue$3.run(EventQueue.java:697) 位于java.awt.EventQueue$3.run(EventQueue.java:691) 位于java.security.AccessController.doPrivileged(本机方法) 位于java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75) 位于java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86) 在java.awt.EventQueue$4.run(EventQueue.java:719) 在java.awt.EventQueue$4.run(EventQueue.java:717) 位于java.security.AccessController.doPrivileged(本机方法) 位于java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75) 位于java.awt.EventQueue.dispatchEvent(EventQueue.java:716) 位于java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) 在java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)中 位于java.awt.EventDispatchThread.PumpeEventsforHierarchy(EventDispatchThread.java:105) 位于java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) 位于java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) 在java.awt.EventDispatchThread.run(EventDispatchThread.java:82)


    您将获得NullPointerException,因为您使用了错误的SomeClass在此处创建操作:

    Action action = new SomeClass().new SomeAction("DO", "Do sth",
            KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
    
    新SomeClass()
    不是显示的SomeClass

    而是考虑在可视化对象中传递。< /P>

    public static Action otherGetAction(SomeClass someClass) {
      return someClass.new SomeAction("DO", "Do sth",
            KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK));
    }
    

    如果要在GUI之外进行设置,请考虑将操作从GUI中分离出来。例如:

    import java.awt.event.ActionEvent;
    import javax.swing.*;
    
    public class Test2 extends JPanel implements Fooable {
       private JTextField field = new JTextField(10);
       private JTextArea textarea = new JTextArea(20, 30);
       private JButton button = new JButton();
    
       public Test2() {
          textarea.setFocusable(false);
          JScrollPane scrollPane = new JScrollPane(textarea);
          scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    
          add(field);
          add(scrollPane);
    
          add(button);
       }
    
       public void setActions(Action action) {
          button.setAction(action);
          field.setAction(action);
       }
    
       @Override
       public String getFieldText() {
          field.selectAll();
          return field.getText();
       }
    
       @Override
       public void appendText(String text) {
          textarea.append(text + "\n");
       }
    
    
       private static void createAndShowGui() {
          Test2 mainPanel = new Test2();
          Action myAction = new MyAction("Press Me", KeyEvent.VK_P, mainPanel);
          mainPanel.setActions(myAction);
    
          JFrame frame = new JFrame("Test2");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(mainPanel);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    
    }
    
    interface Fooable {
       String getFieldText();
       void appendText(String text);
    }
    
    class MyAction extends AbstractAction {
       private Fooable fooable;
    
       public MyAction(String name, int mnemonic, Fooable fooable) {
          super(name);
          putValue(MNEMONIC_KEY, mnemonic);
          this.fooable = fooable;
       }
    
       @Override
       public void actionPerformed(ActionEvent e) {
          if (fooable != null) {
             fooable.appendText(fooable.getFieldText());
          }
       }
    }
    

    请参见编辑以回答问题。