How to call an action from another class in Java

How can I call an action from another class in Java? I got a CloseTabButton class on the web that allows a simple tab close button on each JTabbedPane, but when the tab is closed I would like the dialog to pop up based on the information (if the file is not saved, ask to save it, etc.) This is the file :

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

class CloseTabButton extends JPanel implements ActionListener {
    private JTabbedPane pane;
    public CloseTabButton(JTabbedPane pane, int index) {
        this.pane = pane;
        setOpaque(false);

        // CloseIcon class just had a button with an x painted on it
        Icon closeIcon = new CloseIcon();
        JButton close = new JButton(closeIcon);

        close.setPreferredSize(new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight()));
        close.addActionListener(this);

        add(new JLabel(pane.getTitleAt(index), pane.getIconAt(index), JLabel.LEFT));
        add(close);

        pane.setTabComponentAt(index, this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        int i = pane.indexOfTabComponent(this);

        String fileName = pane.getToolTipTextAt(i);

        // Where I want to ask if user wants to save, etc.
        if (fileName == "Untitled") {
            // Do stuff
        }

        pane.remove(i); // Removes the tab

        // If tab count < 1, then disable the save and save as buttons on menu
        if (pane.getTabCount() < 1) {
            JFrame frame = (JFrame) pane.getParent().getParent().getParent().getParent().getParent(); // Yes, there is that many in my code to get the parent JFrame

            int menuCount = frame.getJMenuBar().getMenuCount();

            for (int a = 0; a < menuCount; a++) {
                int itemCount = frame.getJMenuBar().getMenu(a).getItemCount();

                for (int b = 0; b < itemCount; b++) {
                    Component component = frame.getJMenuBar().getMenu(a).getMenuComponent(b);

                    if (!(component instanceof JSeparator)) {
                        // Not a seperator
                        String itemName = frame.getJMenuBar().getMenu(a).getItem(b).getAccessibleContext().getAccessibleName();
                        if (itemName == "Save As..") {
                            frame.getJMenuBar().getMenu(a).getItem(b).setEnabled(false);
                        }
                    }
                }
            }
        }
    }
}

      

In my main class, I have the listed actions:

static Action Close = new AbstractAction("Close") {
    public void actionPerformed(ActionEvent e) {
        closeCurrentWindow(); // function that will close tab
    }
}

      

The other menu items are actions as well, and as you can see, what I am currently doing in the CloseTabButton class is rather complicated and most likely the wrong way to code it. Is there a much easier way to do what I am doing?

+3


source to share


1 answer


The first thing I can do is provide ActionListener

support CloseTabButton

, for example ...

public class CloseTabButton extends JPanel {

    private JTabbedPane pane;

    public CloseTabButton(JTabbedPane pane, int index) {
        this.pane = pane;
        setOpaque(false);

        // CloseIcon class just had a button with an x painted on it
        Icon closeIcon = new CloseIcon();
        JButton close = new JButton(closeIcon);

        close.setPreferredSize(new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight()));
        close.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                fireActionPerformed();
            }

        });

        add(new JLabel(pane.getTitleAt(index), pane.getIconAt(index), JLabel.LEFT));
        add(close);

        pane.setTabComponentAt(index, this);
    }

    public void addActionListener(ActionListener listener) {
        listenerList.add(ActionListener.class, listener);
    }

    public void removeActionListener(ActionListener listener) {
        listenerList.remove(ActionListener.class, listener);
    }

    protected void fireActionPerformed() {
        ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
        ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "You could provide you own action command for each tab here");
        for (ActionListener listener : listeners) {
            listener.actionPerformed(evt);
        }
    }

}

      

Basically, this now allows you to register your own ActionListener

inCloseTabButton

Further, it is fileName == "Untitled"

, not like you are comparing String

in Java, you should use something more similar to"Untitled".equals(fileName)

If you are based on the actual Action

s you can just disable yourself Action

. It takes a little work, but much less "guessing" work than you currently do.

Basically, you have to monitor yourself JTabbedPane

, track changes to the selected tab and update the states themselvesAction

You can do several ways here, for example, pass a link JTabbedPane

to Action

so that they can do their own monitoring (but I would use some kind of management interface that could more easily provide information in Action

and separate the code and dependency from JTabbedPane

directly, then you can use JInternalFrame

instead this).



You might have a "menu manager" doing a similar job, tracking changes in the document container and changing the state of the menu Action

based on the current state as an example

Update

If you are using an API Action

(which I would recommend) then you could just do something like ...

public class CloseTabButton extends JPanel {

    private JTabbedPane pane;

    public CloseTabButton(JTabbedPane pane, Action action, int index) {
        this.pane = pane;
        setOpaque(false);

        // CloseIcon class just had a button with an x painted on it
        Icon closeIcon = new CloseIcon();
        JButton close = new JButton(action);
        close.setIcon(closeIcon);
        close.setPreferredSize(new Dimension(closeIcon.getIconWidth(), closeIcon.getIconHeight()));

        add(new JLabel(pane.getTitleAt(index), pane.getIconAt(index), JLabel.LEFT));
        add(close);

        pane.setTabComponentAt(index, this);
    }

}

      

When going in Action

for a close operation, use the same action for JMenuItem

and JTabbedPane

.

The "main problem" is how you will identify the "current" tab and document in the same way.

0


source







All Articles