【发布时间】:2016-12-21 17:30:13
【问题描述】:
我正在尝试让我的应用程序显示一个简单的加载对话框,以便用户知道时间密集型进程何时工作以及何时完成。我只是希望它使用我下载的 gif 显示一个简单的“加载”。我已经尝试过只使用文本,但它仍然不起作用。
我可以让对话框在我想要的时候显示(并消失),问题是显示后对话框(或框架)上不会显示任何内容。我尝试了许多不同的技术,都给出了相同的结果,一个空白对话框。
我终于创建了一个单独的类来显示对话框(加载 gif)并且我让它正确显示(单独),但是当我从我的主应用程序运行它时,它再次显示一个黑色对话框。我测试了将 gif 放入 JOptionPane 并且它可以工作,问题是我无法随意关闭它。
这是我的自定义代码。
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import java.util.logging.*;
import org.w3c.dom.*;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import javax.swing.filechooser.FileNameExtensionFilter;
public class Loader implements Runnable {
final JFileChooser jfc = new JFileChooser();
static JFrame frame = new JFrame();
Frame parentUI = new Frame();
JDialog dialog = new JDialog();
JLabel lbl_filename = new JLabel();
JLabel lbl_path = new JLabel();
static Loader load = new Loader(null);
public static void main(String[] args) throws InterruptedException, InvocationTargetException {
load.run();
frame.setVisible(true);
}
public Loader(Frame parent) {
init();
parentUI = parent;
}
@Override
public void run() {
createDialog(parentUI);
}
public final void init() {
JButton btn = new JButton("Open");
frame.setTitle("Loader Test");
frame.setSize(500, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setLayout(new FlowLayout());
btn.addActionListener(new Action1());
frame.add(btn);
frame.add(lbl_filename);
frame.add(lbl_path);
}
class Action1 implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
openFile();
load.Close();
}
}
private void createDialog(final Frame parent) {
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setTitle("Loader");
URL url = this.getClass().getResource("/resource/loader.gif");
Icon icon = new ImageIcon(url);
JLabel label = new JLabel(icon);
dialog.add(label);
dialog.pack();
dialog.setLocationRelativeTo(parent);
}
public void Show(Boolean visible) {
this.run();
dialog.setVisible(visible);
}
public void Close() {
dialog.setVisible(false);
}
private void setJFCFilter(String file, String ext) {
FileNameExtensionFilter filter = new FileNameExtensionFilter(file, ext);
jfc.setFileFilter(filter);
}
private void openFile() {
File default_dir = new File(".");
jfc.setCurrentDirectory(default_dir);
setJFCFilter("Scalable Vector Graphics", "svg");
int returnVal = jfc.showOpenDialog(parentUI);
if (returnVal == JFileChooser.APPROVE_OPTION) {
String path = jfc.getSelectedFile().getAbsolutePath();
String fileName = jfc.getSelectedFile().getName();
lbl_filename.setText(fileName);
lbl_path.setText(path);
load.Show(true);
createDoc(path);
load.Close();
}
}
private void createDoc(String file) {
try {
NodeList svgIDPaths;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
String xpathIDExp = "//g/@id";
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
XPathExpression expression = xpath.compile(xpathIDExp);
svgIDPaths = (NodeList)expression.evaluate(doc, XPathConstants.NODESET);
} catch (Exception ex) {
Logger.getLogger(Loader.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
编辑:使用此文件进行测试 -> svg_test.svg
我试过这样称呼它:
loader.show(true);
而且在它自己的线程中也是这样:
private void load(final Boolean visible) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
loader.show(visible);
}
});
t.start();
}
这两种方法都不起作用并且给我相同的结果,一个空白对话框。我过去曾遇到过这个问题,但只是放弃并删除了它(加载对话框)。我已经用进度条和简单的文本尝试过,似乎没有任何效果。
我也在 JOptionPane 中尝试过它并且它有效,但这是不可取的(当我不想通过按钮单击时我想关闭/打开)。
private void load() {
ImageIcon icon = new ImageIcon(MainForm.class.getResource("/resource/loader.gif").getFile());
JOptionPane.showMessageDialog(null, "Loading...", "Loader", JOptionPane.INFORMATION_MESSAGE, icon);
}
我知道您不能在 EDT 上运行多个对话框并且必须使用单独的线程,但我使用的是单独的线程并且它不工作(它自己工作)。
(另请注意,我有一个主应用程序(框架)正在运行/打开第二个对话框)。
感谢任何帮助。
【问题讨论】:
-
抱歉,忘记了。完成后我会更新。
-
更新了,打开任何SVG文件都不行。
-
// Java OutOfMemory是什么意思? -
另外,“ETF”是什么意思?您指的是 Swing EDT -- 事件调度线程吗?