4

我有一个公共类AppHelper用于使用 jframe 显示一些帮助内容。在同一个 JFrame 上有一个退出按钮,单击它会处理 jframe。ActionListener 实现为上述类的静态嵌套类。

此外,帮助窗口的所有组件都在外部类中定义,它们都是私有的和静态的。显示帮助窗口的方法也是静态的。

这是我实现的一些代码:

public class AppHelper {
// helper frame
private static JFrame appHelperFrame;
// helper panel
private static JPanel appHelperPanel;
// helper pane
private static JEditorPane appHelperPane;
// exit helper button
private static JButton exitAppHelperButton;
// constraints
private static GridBagConstraints appHelperPaneCons, exitAppHelperButtonCons;

/**
  set layout
 */
private static void setLayoutConstraints () {
    // defines layout
}
/**
 * initialize the helper elements
 * @param void
 * @return void
*/
public static void initializeElements () {
    // initialize constraints
    setLayoutConstraints();
    // handler
    AppHelper.AppHelperHandler appHelpHandler = new AppHelper.AppHelperHandler();

    appHelperFrame = new JFrame("App Help");
    appHelperPanel = new JPanel();
    appHelperPanel.setLayout(new GridBagLayout());

    appHelperPane = new JEditorPane();
    exitAppHelperButton = new JButton("Exit");

    exitAppHelperButton.addActionListener(appHelpHandler);
    java.net.URL helpURL = null;
    try {
        helpURL = new File("AppHelp.html").toURI().toURL();
    } catch (MalformedURLException ex) {
        Logger.getLogger(AppHelper.class.getName()).log(Level.SEVERE, null, ex);
    }
    try {
        appHelperPane.setPage(helpURL);
    } catch (IOException ex) {
        Logger.getLogger(AppHelper.class.getName()).log(Level.SEVERE, null, ex);
    }
    appHelperPane.setEditable(false);
    appHelperFrame.add(appHelperPanel);
    appHelperPanel.add(appHelperPane, appHelperPaneCons);
    appHelperPanel.add(exitAppHelperButton, exitAppHelperButtonCons);
    appHelperFrame.setSize(350, 400);
    appHelperFrame.setResizable(false);
    appHelperFrame.setVisible(true);
}

/**
 * TODO
 */
public static void showAboutApp() {
    //throw new UnsupportedOperationException("Not yet implemented");

}

/**
 *
 * Acts as the handler for the help window components
 * Implement actionListener interface.
 */
private static class AppHelperHandler implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if(source == exitAppHelperButton)  {
            appHelperFrame.dispose();
        }
    }
}
}

处理 JFrame 而不是将其设置为不可见的原因是我不希望此 JFrame 在此 JFrame 未使用时消耗内存。

现在的问题是我第一次单击帮助按钮(在其他窗口上)时会显示 JFrame。现在,当我单击此帮助窗口上的退出按钮时,处理程序会处理 JFrame。下次我再次单击帮助按钮时,不会显示帮助窗口。我想知道我的代码中是否有任何错误,或者我需要做其他事情。

4

1 回答 1

0

Window.dispose()的 javadoc指出

通过随后调用 pack 或 show 重建本机资源,可以使 Window 及其子组件再次可显示。

这也有效,我试过了。只需打电话appHelperFrame.setVisible(true),仅此而已。如果窗口未激活,请尝试调用appHelperFrame.setState(Frame.NORMAL)which 将激活它。

你只需要调用你的initializeElements方法一次。您的showAboutApp()方法应如下所示:

public static void showAboutApp() {
    if (appHelperFrame == null)
        initializeElements(); // This also makes the frame visible
    else {
        appHelperFrame.setVisible(true);
        appHelperFrame.setState(Frame.NORMAL);
    }
}

最后说明:

如果你总是showAboutApp()从 EDT(事件调度线程)调用它,那么你很好。如果您从多个线程调用它,您可能希望在 EDT 中使用 likeSwingUtilities.invokeAndwait()SwingUtilities.invokeLater()这也确保多个线程之间的同步来执行它。

于 2014-07-25T07:30:38.143 回答