从另一个 class 处置 JDialog

Dispose JDialog from another class

我想处理另一个 class 的 JDialog,因为我试图保持 classes 和方法干净,而不是在同一个 class 中创建按钮和处理侦听器].那么问题来了。

我尝试从第一个 class 创建一个 get 方法来获取对话框,然后在第三个上处理它,但没有成功。

public class AddServiceListener extends JFrame implements ActionListener {

/**
 * Creates listener for the File/New/Service button.
 */
public AddServiceListener() {

}

/**
 * Performs action.
 */
public void actionPerformed(ActionEvent e) {    
    AddServiceWindow dialog = new AddServiceWindow();
    dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    dialog.setVisible(true);
}
}


public class AddServiceWindow extends JDialog {

private JPanel contentPanel;
private JFrame frame;
private JPanel buttonPanel;
private JLabel nameLabel;
private JTextField nameField;
private JLabel destinationLabel;
private JTextField destinationField;
private JButton destinationButton;
private JButton okButton;
private JButton cancelButton;

/**
 * Creates the dialog window.
 */
public AddServiceWindow() {
    ManageMinder mainFrame = new ManageMinder();
    frame = mainFrame.getFrame();

    contentPanel = new JPanel();
    contentPanel.setLayout(null);

    setTitle("New Service File");
    setSize(340, 220);
    setLocationRelativeTo(frame);
    getContentPane().setLayout(new BorderLayout());
    contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
    getContentPane().add(contentPanel, BorderLayout.CENTER);

    buttonPanel = new JPanel();
    buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
    getContentPane().add(buttonPanel, BorderLayout.SOUTH);

    createLabels();
    createTextFields();
    createButtons();
    addListeners();
}

/**
 * Creates the labels.
 */
private void createLabels() {
    nameLabel = new JLabel("Name:");
    nameLabel.setHorizontalAlignment(SwingConstants.RIGHT);
    nameLabel.setBounds(25, 25, 52, 16);
    contentPanel.add(nameLabel);

    destinationLabel = new JLabel("Path:");
    destinationLabel.setHorizontalAlignment(SwingConstants.RIGHT);
    destinationLabel.setBounds(7, 70, 70, 16);
    contentPanel.add(destinationLabel);
}

/**
 * Creates the text fields.
 */
private void createTextFields() {
    nameField = new JTextField();
    nameField.setBounds(87, 22, 220, 22);
    contentPanel.add(nameField);
    nameField.setColumns(10);

    destinationField = new JTextField();
    destinationField.setBounds(87, 68, 220, 20);
    contentPanel.add(destinationField);
    destinationField.setColumns(10);
}

/**
 * Creates the buttons of the window.
 */
private void createButtons() {  
    destinationButton = new JButton("Select...");
    destinationButton.setBounds(87, 99, 82, 23);
    destinationButton.setFocusPainted(false);
    contentPanel.add(destinationButton);

    okButton = new JButton("OK");
    okButton.setFocusPainted(false);
    buttonPanel.add(okButton);

    cancelButton = new JButton("Cancel");
    cancelButton.setFocusPainted(false);
    buttonPanel.add(cancelButton);
}

/**
 * Adds listeners to buttons.
 */
private void addListeners() {       
    ActionListener destinationAction = new AddDestinationListener(destinationField);
    destinationButton.addActionListener(destinationAction);

    ActionListener okAction = new SaveNewServiceFileListener(nameField, destinationField);
    okButton.addActionListener(okAction);
}
}


public class SaveNewServiceFileListener extends JFrame implements ActionListener {

private JTextField nameField;
private JTextField destinationField;
private String path;
private File newService;

/**
 * Creates listener for the File/New/Add Service/OK button.
 */
public SaveNewServiceFileListener(JTextField nameField, JTextField destinationField) {
    this.nameField = nameField;
    this.destinationField = destinationField;
}

/**
 * Performs action.
 */
public void actionPerformed(ActionEvent e) {
    path = destinationField.getText() + "\" + nameField.getText() + ".csv";

    try {
        newService = new File(path);
        if(newService.createNewFile()) {
            System.out.println("Done!");
            // DISPOSE HERE
        }
        else {
            System.out.println("Exists!");
        }
    } catch (IOException io) {
        throw new RuntimeException(io);
    }
}
}

我该怎么办,所以对话框设置在第三个,当单击“确定”并创建文件时?

更改另一个对象状态的方法是 1) 对该对象有一个 引用,以及 2) 在其上调用一个 public 方法。

这里的另一个对象是 JDialog,您希望通过调用 .close().dispose() 来更改其可见性的状态。您遇到的问题是对 JDialog 的引用不容易获得,因为它隐藏在 AddServiceListener class 的 actionPerformed(...) 方法中。

所以不要这样做——不要隐藏引用,而是将其放入需要它的 class 的字段中。

如果你绝对需要有stand-aloneActionListenerclasses,那么我认为最简单的做法就是把对话框out 监听器 class 并进入视图 class,您的主 GUI,然后在视图上调用监听器方法。例如

假设对话框 class 被称为 SomeDialog 并且主 GUI 被称为 MainGui。然后在MainGui中放入对对话框的引用class:

public class MainGui extends JFrame {
    private SomeDialog someDialog = new SomeDialog(this);

而不是让你的听众创建对话,让他们在主要 class 中调用一个方法来执行此操作:

public class ShowDialogListener implements ActionListener {
    private MainGui mainGui;

    public ShowDialogListener(MainGui mainGui) {
        // pass the main GUI reference into the listener
        this.mainGui = mainGui;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // tell the main GUI to display the dialog
        mainGui.displaySomeDialog();
    }
}

那么MainGUI可以有:

public void displaySomeDialog() {
    someDialog.setVisible(true);
}

一个示例 MRE 程序可能如下所示:

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.*;

import javax.swing.*;

public class FooGui002 {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            MainGui mainGui = new MainGui();
            mainGui.setVisible(true);
        });
    }
}
@SuppressWarnings("serial")
class MainGui extends JFrame {
    private SomeDialog someDialog;
    private JButton showSomeDialogButton = new JButton("Show Some Dialog");
    private JButton closeSomeDialogButton = new JButton("Close Some Dialog");

    public MainGui() {
        super("Main GUI");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(500, 200));

        someDialog = new SomeDialog(this);

        showSomeDialogButton.addActionListener(new ShowDialogListener(this));
        showSomeDialogButton.setMnemonic(KeyEvent.VK_S);

        closeSomeDialogButton.addActionListener(new CloseSomeDialogListener(this));
        closeSomeDialogButton.setMnemonic(KeyEvent.VK_C);

        setLayout(new FlowLayout());
        add(showSomeDialogButton);
        add(closeSomeDialogButton);
        pack();
        setLocationByPlatform(true);
    }

    public void displaySomeDialog() {
        someDialog.setVisible(true);
    }

    public void closeSomeDialog() {
        someDialog.setVisible(false);
    }
}
@SuppressWarnings("serial")
class SomeDialog extends JDialog {
    public SomeDialog(Window window) {
        super(window, "Some Dialog", ModalityType.MODELESS);
        setPreferredSize(new Dimension(300, 200));
        add(new JLabel("Some Dialog", SwingConstants.CENTER));
        pack();
        setLocationByPlatform(true);
    }
}
class ShowDialogListener implements ActionListener {
    private MainGui mainGui;

    public ShowDialogListener(MainGui mainGui) {
        this.mainGui = mainGui;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        mainGui.displaySomeDialog();
    }
}
class CloseSomeDialogListener implements ActionListener {
    private MainGui mainGui;

    public CloseSomeDialogListener(MainGui mainGui) {
        this.mainGui = mainGui;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        mainGui.closeSomeDialog();
    }
}