杰瑞科技汇

Java中Action重复定义会导致什么问题?

Of course! The phrase "Java action action" is a bit ambiguous, but it's likely referring to one of two very common concepts in Java development:

Java中Action重复定义会导致什么问题?-图1
(图片来源网络,侵删)
  1. The Action Interface: A fundamental part of the older Abstract Window Toolkit (AWT) and Swing GUI toolkits.
  2. The @Action Annotation: A key part of the modern JavaBeans Binding (JSR 295) and JavaFX frameworks.

Let's break down both, starting with the most classic one.


The java.awt.Action Interface (Classic GUI Actions)

This is the most traditional meaning of "action" in Java. An Action is an encapsulation of a command or behavior that can be triggered by a user. It's a powerful design pattern that promotes reusability and consistency in graphical user interfaces (GUIs).

What is an Action?

An Action is an interface that extends ActionListener. It represents a task to be performed. The main advantage of using an Action object over a simple ActionListener is that an Action can be configured with properties like its name (NAME), icon (SMALL_ICON), description (SHORT_DESCRIPTION, which becomes a tooltip), and enabled/disabled state (ENABLED).

You can then attach this single Action object to multiple UI components (like a menu item, a toolbar button, and a keyboard shortcut), and they will all stay in sync automatically.

Java中Action重复定义会导致什么问题?-图2
(图片来源网络,侵删)

Key Properties of an Action

An Action object manages several key properties, defined as constants in the interface:

  • NAME: The text displayed on buttons or in menus.
  • SMALL_ICON: The icon for buttons or menu items.
  • SHORT_DESCRIPTION: A short, one-line description (used as a tooltip).
  • LONG_DESCRIPTION: A longer, multi-line description (used in status bars).
  • ACCELERATOR_KEY: A KeyStroke for a keyboard shortcut.
  • MNEMONIC_KEY: An int for a mnemonic key (e.g., 'N' for "New").
  • ACTION_COMMAND_KEY: The command string sent to the listener.
  • SELECTED_KEY: A boolean indicating if the component (e.g., a checkbox menu item) is selected.
  • DISPLAYED_MNEMONIC_INDEX_KEY: An int specifying the index of the mnemonic character in the NAME.
  • ENABLED: A boolean indicating if the action is enabled.

Example: Using Action in Swing

Here is a complete, runnable example that creates a JFrame with a menu bar and a toolbar. Both the menu item and the toolbar button are controlled by the same Action.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class ActionExample {
    public static void main(String[] args) {
        // Create the main window
        JFrame frame = new JFrame("Java Action Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);
        frame.setLayout(new BorderLayout());
        // 1. Create our custom Action
        ExitAction exitAction = new ExitAction();
        // 2. Create a menu bar and add a menu item using the Action
        JMenuBar menuBar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        // JMenuItem will automatically get its name, icon, and accelerator from the Action
        JMenuItem exitMenuItem = new JMenuItem(exitAction);
        fileMenu.add(exitMenuItem);
        menuBar.add(fileMenu);
        frame.setJMenuBar(menuBar);
        // 3. Create a toolbar and add a button using the same Action
        JToolBar toolBar = new JToolBar();
        // JButton will also automatically get its properties from the Action
        JButton exitButton = new JButton(exitAction);
        toolBar.add(exitButton);
        frame.add(toolBar, BorderLayout.NORTH);
        // Display the window
        frame.setVisible(true);
    }
}
/**
 * A custom Action that closes the application when triggered.
 * It demonstrates setting the properties of an Action.
 */
class ExitAction extends AbstractAction {
    public ExitAction() {
        // Configure the properties of this action
        putValue(NAME, "Exit");               // Text for the button/menu item
        putValue(SMALL_ICON, new ImageIcon("exit.png")); // Icon (you'd need an exit.png file)
        putValue(SHORT_DESCRIPTION, "Exit the application"); // Tooltip text
        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("control Q")); // Keyboard shortcut
        putValue(MNEMONIC_KEY, KeyEvent.VK_X); // Mnemonic key (Alt+X)
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        // This is the code that runs when the action is performed
        // For example, find the active window and close it
        for (Frame f : Frame.getFrames()) {
            if (f.isActive()) {
                f.dispose();
                break;
            }
        }
    }
}

Why is this useful? Instead of writing a separate actionPerformed method for a menu item and a button, you create one ExitAction object. You configure it once, and both UI components use it. If you want to change the text or icon, you only change it in one place.


The @Action Annotation (Modern JavaBeans / JavaFX)

This is a more modern approach, part of the JavaBeans framework and heavily used in JavaFX. It's used to bind a method in a controller class to a UI control (like a button's onAction event).

Java中Action重复定义会导致什么问题?-图3
(图片来源网络,侵删)

How it Works

  1. You create a Java class (often a "controller" or "model").
  2. You annotate a public method with @Action.
  3. You specify properties for the action using the annotation's parameters, like name, iconBase, and disabled.
  4. In your FXML (for JavaFX) or other UI code, you can now refer to this action by its name.

Example: @Action in JavaFX with FXML

This is a simplified conceptual example. In a real JavaFX application, you'd typically use FXML for the UI.

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.binding.convert.service.DefaultConversionService;
import org.springframework.binding.expression.support.LiteralExpression;
import org.springframework.binding.value.support.ValueHolder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.richclient.application.support.ApplicationServices;
import org.springframework.richclient.factory.ComponentFactory;
import org.springframework.richclient.factory.DefaultComponentFactory;
import org.springframework.richclient.form.binding.swing.SwingBindingFactory;
import org.springframework.stereotype.Component;
// Note: This requires Spring RCP or a similar framework that supports the @Action annotation.
// A pure JavaFX example without this framework would be different.
// Let's imagine a simplified controller class
@Component
public class MyViewController {
    // This method will be exposed as an "action"
    @Action(
        name = "Say Hello", // The name of the action
        iconBase = "/icons/hello.png", // Path to an icon
        enabled = "true" // Whether the action is enabled by default
    )
    public void sayHelloAction() {
        System.out.println("Hello from the @Action method!");
        // You would typically update a UI label here, not just print to console.
    }
}
// A main application class to set it up (highly simplified)
public class ActionAnnotationApp extends Application {
    @Override
    public void start(Stage primaryStage) {
        MyViewController controller = new MyViewController();
        // In a real app, the framework would automatically find the @Action method
        // and create a button that calls it. Here we do it manually for demonstration.
        Button helloButton = new Button("Say Hello");
        helloButton.setOnAction(event -> {
            try {
                // Reflection is often used by the framework to call the annotated method
                controller.getClass().getMethod("sayHelloAction").invoke(controller);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        VBox root = new VBox(10, helloButton);
        Scene scene = new Scene(root, 300, 200);
        primaryStage.setTitle("@Action Annotation Example");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    public static void main(String[] args) {
        launch(args);
    }
}

Summary: Action Interface vs. @Action Annotation

Feature java.awt.Action Interface @Action Annotation
Primary Use Swing (AWT) GUIs. JavaBeans, JavaFX, and frameworks like Spring RCP.
Core Concept An object that encapsulates a command and its properties (name, icon, etc.). A method annotation that exposes the method as a reusable action.
How it's Used Create an Action object and attach it to JMenuItem, JButton, etc. Annotate a method in a controller class; the framework binds it to UI controls.
Key Benefit Reusability & Consistency: One Action object can control many UI components. Declarative Binding: Cleanly separates UI logic from UI definition (often in FXML).
Era Classic, Java 1.2+ More modern, part of JSR 295 and JavaFX best practices.

So, when someone says "Java action action," they are most likely referring to either the classic java.awt.Action for building Swing UIs or the modern @Action annotation for building JavaFX applications.

分享:
扫描分享到社交APP
上一篇
下一篇