从另一个 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();
}
}
我想处理另一个 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();
}
}