Java Swing实用程序

Java Swing实用程序,java,swing,Java,Swing,我想创建一条加载消息,在加载信息时,该消息将在屏幕上弹出。我将为它调用initLoadingPanel()方法,以便JFrame可见。我的问题是如何关闭它 我的代码如下 public class DataMigration extends JFrame{ private JFrame frmDataMigration; private JFrame loader; private JButton btnProcess; public static void mai

我想创建一条加载消息,在加载信息时,该消息将在屏幕上弹出。我将为它调用initLoadingPanel()方法,以便JFrame可见。我的问题是如何关闭它

我的代码如下

public class DataMigration extends JFrame{

    private JFrame frmDataMigration;

    private JFrame loader;

private JButton btnProcess;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    DataMigration window = new DataMigration();
                    window.frmDataMigration.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public DataMigration() {
        initialize();
    }

    private void initialize() {

        LoggerImp.startLog(CLASS_NAME, "initialize()");

        frmDataMigration = new JFrame();

btnProcess = new JButton("Load");
        btnProcess.setEnabled(false);
        btnProcess.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

            SwingWorker <CSV, CSV> worker = new SwingWorker<CSV, CSV>() {

                @Override
                protected CSV doInBackground() throws Exception {
                    return FileReaderCSVHelper.fileReader(dirName.getText(), fileName.getText());
                }

                @Override
                protected void done() {
                    try {
                        csv = doInBackground();
                        generateTableList(csv.getCsvTitle(), stateController.getFieldNames());
                    } catch (ExecutionException ex) {
                        ex.printStackTrace();
                    } catch (Exception e){

                    }
                    loader.dispose();
                }

            };
            worker.execute();
        }
        });
     frmDataMigration.getContentPane().add(btnProcess);
}

   public void initLoadingPanel(){
     SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
             loader = new JFrame("Loading....");
             ImageIcon img = new ImageIcon("loader.gif");
             loader.add(new JLabel(" Loading...", img, JLabel.CENTER));

             loader.setAlwaysOnTop(true);
             loader.pack();
             loader.setSize( 448, 497);
             loader.setVisible(true);
             loader.setLocationRelativeTo(null);
         }
     });
}
公共类数据迁移扩展JFrame{
私有JFrame frmDataMigration;
私人车架装载机;
私有JButton btnProcess;
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
公开募捐{
试一试{
DataMigration window=新建DataMigration();
window.frmDataMigration.setVisible(true);
}捕获(例外e){
e、 printStackTrace();
}
}
});
}
公共数据迁移(){
初始化();
}
私有void初始化(){
LoggerImp.startolog(类名称,“initialize()”);
frmDataMigration=newjframe();
btnProcess=新按钮(“加载”);
btnProcess.setEnabled(false);
btnProcess.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件arg0){
SwingWorker worker=新SwingWorker(){
@凌驾
受保护的CSV doInBackground()引发异常{
返回FileReaderCSVHelper.fileReader(dirName.getText(),fileName.getText());
}
@凌驾
受保护的void done(){
试一试{
csv=doInBackground();
generateTableList(csv.getCsvTitle(),stateController.getFieldNames());
}捕获(ExecutionException ex){
例如printStackTrace();
}捕获(例外e){
}
loader.dispose();
}
};
worker.execute();
}
});
frmDataMigration.getContentPane().add(btnProcess);
}
public void initLoadingPanel(){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
装载机=新JFrame(“装载…”);
ImageIcon img=新的ImageIcon(“loader.gif”);
添加(新JLabel(“加载…”,img,JLabel.CENTER));
loader.setAlwaysOnTop(真);
loader.pack();
装载机设置尺寸(448497);
loader.setVisible(true);
loader.setLocationRelativeTo(空);
}
});
}

通常,您只需要调用
loader.dispose()
loader.setVisible(false)
,这就提出了一个问题,您是如何加载资源的

您可能需要将
loader
的引用传递给代码的这一部分,这样当它完成时,您就可以处理框架了

由于框架是装饰性的,用户只需点击“[x]”按钮并关闭窗口,而您可以将框架
defaultCloseOperation
设置为
dou\u NOTHING\u ON\u close
,这看起来仍然很奇怪

您可以使用移除框架装饰

由于
loader
是从
JFrame
扩展而来的,因此用户仍然可以与父窗口交互(如果父窗口可见),更好的解决方案可能是使用
JDialog
,并将其设为模态

你也可以考虑看一些其他的想法< /P> 已更新

你在隐藏你的变量

首先,将
loader
声明为
DataMigration

public class DataMigration extends JFrame{
    //...
    private JFrame loader;
但是,然后在
Runnable
run
方法中重新声明它

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        JFrame loader = new JFrame("Loading....");
initLoadingPanel();
SwingWorker worker = new SwingWorker<CVS, CVS>() {

    @Override
    protected CVS doInBackground() throws Exception {
        return FileReaderCSVHelper.fileReader(dirName.getText(), fileName.getText());
    }

    @Override
    protected void done() {
        try {
            cvs = get();
            generateTableList(csv.getCsvTitle(), stateController.getFieldNames());
        } catch (ExecutionException ex) {
            ex.printStackTrace();
        }
        loader.dispose();
    }

};
worker.execute();
这意味着实例字段仍然为空,请尝试

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        loader = new JFrame("Loading....");
相反

还有

public void actionPerformed(ActionEvent arg0) {
    initLoadingPanel();
    csv = FileReaderCSVHelper.fileReader(dirName.getText(), fileName.getText());
    generateTableList(csv.getCsvTitle(), stateController.getFieldNames());
    loader.dispose();
}
不会执行您认为应该执行的操作…您“可能”会幸运地看到
加载程序
帧,但很可能不会,因为您正在阻止事件调度线程

相反,你应该考虑使用<代码> SaveWorks…< /P>

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        JFrame loader = new JFrame("Loading....");
initLoadingPanel();
SwingWorker worker = new SwingWorker<CVS, CVS>() {

    @Override
    protected CVS doInBackground() throws Exception {
        return FileReaderCSVHelper.fileReader(dirName.getText(), fileName.getText());
    }

    @Override
    protected void done() {
        try {
            cvs = get();
            generateTableList(csv.getCsvTitle(), stateController.getFieldNames());
        } catch (ExecutionException ex) {
            ex.printStackTrace();
        }
        loader.dispose();
    }

};
worker.execute();

通常,您只需要调用
loader.dispose()
loader.setVisible(false)
,这就提出了一个问题,即如何加载资源

您可能需要将
loader
的引用传递给代码的这一部分,这样当它完成时,您就可以处理框架了

由于框架是装饰性的,用户只需点击“[x]”按钮并关闭窗口,而您可以将框架
defaultCloseOperation
设置为
dou\u NOTHING\u ON\u close
,这看起来仍然很奇怪

您可以使用移除框架装饰

由于
loader
是从
JFrame
扩展而来的,因此用户仍然可以与父窗口交互(如果父窗口可见),更好的解决方案可能是使用
JDialog
,并将其设为模态

你也可以考虑看一些其他的想法< /P> 已更新

你在隐藏你的变量

首先,将
loader
声明为
DataMigration

public class DataMigration extends JFrame{
    //...
    private JFrame loader;
但是,然后在
Runnable
run
方法中重新声明它

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        JFrame loader = new JFrame("Loading....");
initLoadingPanel();
SwingWorker worker = new SwingWorker<CVS, CVS>() {

    @Override
    protected CVS doInBackground() throws Exception {
        return FileReaderCSVHelper.fileReader(dirName.getText(), fileName.getText());
    }

    @Override
    protected void done() {
        try {
            cvs = get();
            generateTableList(csv.getCsvTitle(), stateController.getFieldNames());
        } catch (ExecutionException ex) {
            ex.printStackTrace();
        }
        loader.dispose();
    }

};
worker.execute();
这意味着实例字段仍然为空,请尝试

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        loader = new JFrame("Loading....");
相反

还有

public void actionPerformed(ActionEvent arg0) {
    initLoadingPanel();
    csv = FileReaderCSVHelper.fileReader(dirName.getText(), fileName.getText());
    generateTableList(csv.getCsvTitle(), stateController.getFieldNames());
    loader.dispose();
}
不会执行您认为应该执行的操作…您“可能”会幸运地看到
加载程序
帧,但很可能不会,因为您正在阻止事件调度线程

相反,你应该考虑使用<代码> SaveWorks…< /P>

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        JFrame loader = new JFrame("Loading....");
initLoadingPanel();
SwingWorker worker = new SwingWorker<CVS, CVS>() {

    @Override
    protected CVS doInBackground() throws Exception {
        return FileReaderCSVHelper.fileReader(dirName.getText(), fileName.getText());
    }

    @Override
    protected void done() {
        try {
            cvs = get();
            generateTableList(csv.getCsvTitle(), stateController.getFieldNames());
        } catch (ExecutionException ex) {
            ex.printStackTrace();
        }
        loader.dispose();
    }

};
worker.execute();

在线程“AWT-EventQueue-0”java.lang.NullPointerException中调用loader.dispose()异常时,我遇到了以下错误(可能是因为您在
run
method.Instea的本地上下文中声明了
loader