2016-12-22 1 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를 얻고이 모달 대화 상자를 표시하기 전에 모든 유선 및 실행 을 실행하십시오.

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() 코드를 제거 않았다 (Thread.sleep를 포함)

간체 코드? 코드와 로딩 대화 상자의 전체 지점입니다. 대화 상자가 표시된 후 코드를 실행할 수 있습니까? –

+0

@lloyd는 내가 한 일을 설명하는대로 [mcve] 링크를 읽습니다. 데모 용으로이 코드는 장기 실행 코드를 Thread.sleep으로 대체 할 수 있습니다. –

+0

그래서 나는 thread.sleep이있는 곳에서 장기 실행 코드를 배치 할까? –

관련 문제