2016-12-22 4 views
1

При открытии второго диалогового окна в качестве «диалогового окна загрузки», чтобы предотвратить действие пользователя при загрузке большого файла, я хочу, чтобы в диалоговом окне было запрещено любое действие пользователя (щелчок и т. Д.), Когда диалог вверх (и большой файл загружается). Диалог работает как «Немодальный диалог», который вы можете щелкнуть по главному окну и щелкнуть мышью, но при использовании «Модального диалога» вместо этого он замораживает процессы программы после ее отображения.Модальный диалог не работает

Как я могу правильно отобразить модальный диалог?

Код:

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(); 
     } 
    } 

    private void createDialog(final Frame parent) { 

     dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
     dialog.setModal(true); 
     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) { 
      final String path = jfc.getSelectedFile().getAbsolutePath(); 
      String fileName = jfc.getSelectedFile().getName(); 

      lbl_filename.setText(fileName); 
      lbl_path.setText(path); 

      System.out.println("Loading file..."); 

      load.Show(true); 

      new SwingWorker<Void, Void>() { 
       @Override 
       protected Void doInBackground() throws Exception { 
        createDoc(path); 
        return null; 
       }; 

       @Override 
       protected void done() { 
        load.Close(); 
       }; 
      }.execute(); 

      System.out.println("Closing file..."); 
     } 
    } 

    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); // Java OutOfMemory 

     } catch (Exception ex) { 
      Logger.getLogger(Loader.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

ответ

3

Я понимаю, что вы делаете неправильно, - вы звоните шоу, метод, который отображает модальное диалоговое перед начиная с SwingWorker. Опять же, получите SwingWorker и все проводные и запущенные до, показывая модальный диалог.

упрощенный код (с Thread.sleep)

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

import java.util.concurrent.TimeUnit; 
import java.lang.reflect.InvocationTargetException; 
import java.net.URL; 

public class Loader implements Runnable { 
    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(); 
     } 
    } 

    private void createDialog(final Frame parent) { 

     dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
     dialog.setModal(true); 
     dialog.setTitle("Loader"); 

     JLabel label = new JLabel("Label"); 
     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 openFile() { 
     System.out.println("Loading file..."); 

     // !! load.show(true); 

     new SwingWorker<Void, Void>() { 
      @Override 
      protected Void doInBackground() throws Exception { 
       // createDoc(path); 
       createDoc(null); 
       return null; 
      }; 

      @Override 
      protected void done() { 
       load.close(); 
      }; 
     }.execute(); 

     load.show(true); //!! 
    } 

    private void createDoc(String file) { 
     try { 
      TimeUnit.SECONDS.sleep(4); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

Почему вы удалите код createDoc()? Это весь смысл кода и диалогового окна загрузки. Смогу ли я запустить код после отображения диалогового окна? –

+0

@lloyd читает ссылку [mcve], так как объясняет, что я сделал. Для демонстрационных целей этот код может заменить любой длинный код с помощью Thread.sleep. –

+0

Так что я бы просто поместил свой длинный код, где есть thread.sleep? –