public void commitChanges() {
   act.setAppliesTo(getApplies());
   if (relativeBox != null) act.setRelative(relativeBox.isSelected());
   if (notBox != null) act.setNot(notBox.isSelected());
   switch (act.getLibAction().interfaceKind) {
     case LibAction.INTERFACE_CODE:
       act.getArguments().get(0).setVal(code.getTextCompat());
       break;
     default:
       for (ArgumentComponent a : argComp) a.commit();
   }
 }
  // Must be delegated through ActionFrame(Action)
  private ActionFrame(Action a, LibAction la) {
    super(la.description, false);
    if (la.parent == null) setTitle(Messages.getString("Action.UNKNOWN")); // $NON-NLS-1$
    if (la.actImage != null)
      setFrameIcon(new ImageIcon(la.actImage.getScaledInstance(16, 16, Image.SCALE_SMOOTH)));
    String s;
    ResourceReference<GmObject> at = a.getAppliesTo();
    if (at == GmObject.OBJECT_SELF) s = Messages.getString("ActionFrame.SELF"); // $NON-NLS-1$
    else s = Messages.getString("ActionFrame.OTHER"); // $NON-NLS-1$
    appliesObject = new ResourceMenu<GmObject>(Resource.Kind.OBJECT, s, false, 100);
    appliesObject.setEnabled(GmObject.refAsInt(at) >= 0);
    appliesObject.setOpaque(false);
    appliesObject.setSelected(at);
    act = a;

    appliesPanel = new JPanel();
    appliesPanel.setOpaque(false);
    appliesPanel.setLayout(new GridBagLayout());

    GridBagConstraints gbc;
    applies = new IndexButtonGroup(3, true, false);
    JRadioButton button = new JRadioButton(Messages.getString("ActionFrame.SELF")); // $NON-NLS-1$
    button.setOpaque(false);
    applies.add(button, -1);
    gbc = new GridBagConstraints();
    gbc.gridy = 0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    appliesPanel.add(button, gbc);
    button = new JRadioButton(Messages.getString("ActionFrame.OTHER")); // $NON-NLS-1$
    button.setOpaque(false);
    applies.add(button, -2);
    gbc = new GridBagConstraints();
    gbc.gridy = 0;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    appliesPanel.add(button, gbc);
    button = new JRadioButton(Messages.getString("ActionFrame.OBJECT")); // $NON-NLS-1$
    button.setHorizontalAlignment(JRadioButton.LEFT);
    button.setOpaque(false);
    button.addChangeListener(
        new ChangeListener() {
          public void stateChanged(ChangeEvent e) {
            boolean sel = ((JRadioButton) e.getSource()).isSelected();
            appliesObject.setEnabled(sel);
          }
        });
    applies.add(button, 0);
    gbc = new GridBagConstraints();
    gbc.gridy = 1;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    appliesPanel.add(button, gbc);
    gbc = new GridBagConstraints();
    gbc.gridy = 1;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.weightx = 1.0;
    gbc.insets = new Insets(0, 2, 0, 6);
    appliesPanel.add(appliesObject, gbc);
    applies.setValue(Math.min(GmObject.refAsInt(at), 0));

    if (la.interfaceKind == LibAction.INTERFACE_CODE) {
      setSize(600, 400);
      setClosable(true);
      setMaximizable(true);
      setResizable(true);
      setIconifiable(true);

      tool = new JToolBar();
      tool.setFloatable(false);
      tool.setAlignmentX(0);
      save = new JButton(LGM.getIconForKey("ActionFrame.SAVE")); // $NON-NLS-1$
      save.addActionListener(this);
      //			add(save);
      tool.add(save);
      tool.addSeparator();

      code = new GMLTextArea(a.getArguments().get(0).getVal());
      code.addEditorButtons(tool);

      tool.addSeparator();
      tool.add(new JLabel(Messages.getString("ActionFrame.APPLIES"))); // $NON-NLS-1$
      tool.add(appliesPanel);

      status = new JPanel(new FlowLayout());
      status.setLayout(new BoxLayout(status, BoxLayout.X_AXIS));
      status.setMaximumSize(new Dimension(Integer.MAX_VALUE, 11));
      final JLabel caretPos =
          new JLabel((code.getCaretLine() + 1) + ":" + (code.getCaretColumn() + 1));
      status.add(caretPos);
      code.addCaretListener(
          new CaretListener() {
            public void caretUpdate(CaretEvent e) {
              caretPos.setText((code.getCaretLine() + 1) + ":" + (code.getCaretColumn() + 1));
            }
          });

      add(tool, BorderLayout.NORTH);
      add(code, BorderLayout.CENTER);
      add(status, BorderLayout.SOUTH);

      setFocusTraversalPolicy(new TextAreaFocusTraversalPolicy(code));
      appliesPanel.setLayout(new BoxLayout(appliesPanel, BoxLayout.LINE_AXIS));
    } else makeArgumentPane(a, la);
    pack();
    repaint();
    SubframeInformer.fireSubframeAppear(this);
  }
  private void makeArgumentPane(Action a, LibAction la) {
    setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
    JLabel lab;
    JPanel pane;
    pane = new JPanel();
    pane.setBorder(new EmptyBorder(6, 6, 0, 6));
    pane.setLayout(new BorderLayout());
    add(pane);
    if (la.actImage != null) {
      lab = new JLabel(new ImageIcon(la.actImage));
      lab.setBorder(new EmptyBorder(16, 16, 16, 20));
      pane.add(lab, BorderLayout.LINE_START);
    }

    String s = Messages.getString("ActionFrame.APPLIES"); // $NON-NLS-1$
    appliesPanel.setBorder(BorderFactory.createTitledBorder(s));
    pane.add(appliesPanel);
    if (!la.canApplyTo) appliesPanel.setVisible(false);

    List<Argument> args = a.getArguments();
    argComp = new ArgumentComponent[args.size()];
    if (args.size() > 0) {
      pane = new JPanel();
      pane.setBorder(
          BorderFactory.createCompoundBorder(
              new EmptyBorder(6, 8, 0, 8), BorderFactory.createTitledBorder("")));
      GroupLayout kvLayout = new GroupLayout(pane);
      GroupLayout.SequentialGroup hGroup, vGroup;
      GroupLayout.ParallelGroup keyGroup, valueGroup;
      hGroup = kvLayout.createSequentialGroup();
      vGroup = kvLayout.createSequentialGroup();
      keyGroup = kvLayout.createParallelGroup(Alignment.TRAILING);
      valueGroup = kvLayout.createParallelGroup();

      hGroup.addGap(4);
      hGroup.addGroup(keyGroup);
      hGroup.addGap(6);
      hGroup.addGroup(valueGroup);
      hGroup.addGap(4);

      kvLayout.setHorizontalGroup(hGroup);
      kvLayout.setVerticalGroup(vGroup);

      pane.setLayout(kvLayout);
      add(pane);

      vGroup.addGap(4);
      for (int n = 0; n < args.size(); n++) {
        argComp[n] = new ArgumentComponent(args.get(n), a.getLibAction().libArguments[n]);
        if (la.parent == null)
          lab = new JLabel(Messages.format("ActionFrame.UNKNOWN", n)); // $NON-NLS-1$
        else {
          LibArgument larg = la.libArguments[n];
          lab = new JLabel(larg.caption);
        }
        Alignment al;
        if (n == 0 && act.getLibAction().interfaceKind == LibAction.INTERFACE_ARROWS) {
          argComp[n].setEditor(new ArrowsEditor(argComp[n].getArgument().getVal()));
          al = Alignment.CENTER;
        } else {
          Component c = argComp[n].getEditor();
          c.setMaximumSize(new Dimension(240, 20));
          c.setPreferredSize(new Dimension(200, 20));
          c.setMinimumSize(new Dimension(160, 20));
          al = Alignment.BASELINE;
        }
        keyGroup.addComponent(lab);
        valueGroup.addComponent(argComp[n].getEditor());
        if (n > 0) vGroup.addGap(6);
        GroupLayout.ParallelGroup argGroup = kvLayout.createParallelGroup(al);
        argGroup.addComponent(lab).addComponent(argComp[n].getEditor());
        vGroup.addGroup(argGroup);
      }
      vGroup.addGap(4);
    }
    pane = new JPanel();
    pane.setLayout(new FlowLayout(FlowLayout.TRAILING));
    add(pane);
    if (la.allowRelative) {
      relativeBox = new JCheckBox(Messages.getString("ActionFrame.RELATIVE")); // $NON-NLS-1$
      relativeBox.setSelected(act.isRelative());
      pane.add(relativeBox);
    }
    if (la.question) {
      notBox = new JCheckBox(Messages.getString("ActionFrame.NOT")); // $NON-NLS-1$
      notBox.setSelected(act.isNot());
      pane.add(notBox);
    }

    pane = new JPanel();
    pane.setLayout(new GridLayout(1, 2, 8, 0));
    pane.setBorder(new EmptyBorder(0, 8, 8, 8));
    add(pane);
    s = Messages.getString("ActionFrame.SAVE"); // $NON-NLS-1$
    save = new JButton(s, LGM.getIconForKey("ActionFrame.SAVE")); // $NON-NLS-1$
    save.addActionListener(this);
    pane.add(save);
    s = Messages.getString("ActionFrame.DISCARD"); // $NON-NLS-1$
    discard = new JButton(s, LGM.getIconForKey("ActionFrame.DISCARD")); // $NON-NLS-1$
    discard.addActionListener(this);
    pane.add(discard);
  }