2016-11-20 13 views
1

PleaseWaitというJavaクラスがあり、重いタスクが進行中の場合はいつでも呼びたいと思っています。私のプログラムが重い作業をしたとき、私のactionListenerの最初の行で、このクラスの変数をsetVisible(true)に設定し、actionListenerの最後にsetVisible(true)を設定します。Java、Swing - JPanelは期待通りにJFrameに表示されません

どういうわけか、このクラスのJPanelは、私が呼び出すと表示されません。それは、タイトルが設定された空白の空白のウィンドウです。ここに私のコードは次のとおりです。

public class PleaseWait extends JFrame{ 

public PleaseWait(){ 

    Toolkit toolkit = Toolkit.getDefaultToolkit(); 

    Dimension screenDimensions = toolkit.getScreenSize(); 
    setSize(300,100); //set size based on screen size 
    setTitle("Please wait"); 
    Container container = getContentPane(); 
    setLocation(new Point(screenDimensions.width*1/4+200, screenDimensions.height*1/4+200)); //set location based on screen size 

    JPanel panel = new JPanel(); 
    JLabel wait = new JLabel("Please wait"); 
    Dimension buttonsSize = new Dimension(300,100); 
    panel.setPreferredSize(buttonsSize); 
    wait.setPreferredSize(buttonsSize); 
    panel.setLayout(new BorderLayout()); 
    panel.add(wait, BorderLayout.CENTER); 
    container.add(panel); 

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setResizable(false); //unresizable 
} 
+1

[編集]あなたの質問が含まれるようにしてください実際の[MCVE](すべてのコードを追加します)。 –

+0

これは私がこのクラスで持っているもので、他のクラスは 'PleaseWait wait = new PleaseWait(); wait.setVisible(true); ' –

+1

あなたはリンクをたどって、@ JonnyHenlyによってリンクされたドキュメントを読んだことがありますか?あなたの返信から、私はそうは思わない。投票に参加して「いいえMCVE」(近い理由は1つではありませんが、実際には2つあります)に投票してください。 –

答えて

4

キーは、あなたが投稿したコードではありませんが、この行に:

と重いタスクが進行

である時はいつでもそれを呼びたいです

"重い"タスクを実行していて、実行している間、SwingはこのGUIを描画していません。スイングイベントスレッドでそのタスクを実行する可能性が高いため、スレッドをフリーズすると、あなたのGUI

解決策:SwingWorkerで取得できるようなバックグラウンドスレッドを使用して、「重い」タスクを実行します。

他の側の問題:

  • これは、メインアプリケーションのオフ「依存」または「サブ」ウィンドウのように見えます。その場合は、JFrameであってはなりません。なぜなら、アプリケーションには1つのメインアプリケーションウィンドウしかなくてはならず、むしろJDialogでなければならないからです。
  • setPreferredSize(...)を使用していて、コンポーネントのサイズをハードコーディングしていますが、問題があります。

例えば、

import java.awt.*; 
import java.awt.Dialog.ModalityType; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 

import javax.swing.*; 

public class TestPleaseWait { 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> { 
      MainPanel mainPanel = new MainPanel(); 
      JFrame frame = new JFrame("Application"); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.add(mainPanel); 
      frame.pack(); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
     }); 
    } 
} 

@SuppressWarnings("serial") 
class MainPanel extends JPanel { 
    private static final int PREF_W = 600; 
    private static final int PREF_H = 450; 

    public MainPanel() { 
     add(new JButton(new AbstractAction("Without Background Thread") { 
      { 
       putValue(MNEMONIC_KEY, KeyEvent.VK_O); 
      } 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       final PleaseWait wait = new PleaseWait(); 
       wait.setVisible(true); 
       try { 
        Thread.sleep(4000); 
       } catch (InterruptedException e1) { 
       } 
       wait.setVisible(false); 
      } 
     })); 
     add(new JButton(new AbstractAction("With Background Thread") { 
      private JDialog waitDialog = null; 
      private MyWaitPanel myWaitPanel = new MyWaitPanel(); 

      { 
       putValue(MNEMONIC_KEY, KeyEvent.VK_W); 
      } 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (waitDialog == null) { 
        Component component = MainPanel.this; 
        Window win = SwingUtilities.getWindowAncestor(component); 
        waitDialog = new JDialog(win, "Please Wait", ModalityType.APPLICATION_MODAL); 
        waitDialog.add(myWaitPanel); 
        waitDialog.pack(); 
        waitDialog.setLocationRelativeTo(win); 
       } 

       new Thread(() -> { 
        try { 
         Thread.sleep(4000); 
        } catch (InterruptedException e1) { 
        } 
        SwingUtilities.invokeLater(() -> { 
         waitDialog.setVisible(false); 
        }); 

       }).start(); 
       waitDialog.setVisible(true); 
      } 
     })); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(PREF_W, PREF_H); 
    } 
} 

@SuppressWarnings("serial") 
class MyWaitPanel extends JPanel { 
    private JProgressBar progressBar = new JProgressBar(); 

    public MyWaitPanel() { 
     progressBar.setIndeterminate(true); 

     JLabel waitLabel = new JLabel("Please Wait", SwingConstants.CENTER); 
     waitLabel.setFont(waitLabel.getFont().deriveFont(Font.BOLD, 40)); 

     int ebGap = 10; 
     setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap)); 
     setLayout(new BorderLayout(ebGap, ebGap)); 
     add(waitLabel, BorderLayout.PAGE_START); 
     add(progressBar); 
    } 
} 

@SuppressWarnings("serial") 
class PleaseWait extends JFrame { 

    public PleaseWait() { 

     Toolkit toolkit = Toolkit.getDefaultToolkit(); 

     Dimension screenDimensions = toolkit.getScreenSize(); 
     setSize(300, 100); // set size based on screen size 
     setTitle("Please wait"); 
     Container container = getContentPane(); 
     setLocation(new Point(screenDimensions.width * 1/4 + 200, 
       screenDimensions.height * 1/4 + 200)); 

     JPanel panel = new JPanel(); 
     JLabel wait = new JLabel("Please wait"); 
     Dimension buttonsSize = new Dimension(300, 100); 
     panel.setPreferredSize(buttonsSize); 
     wait.setPreferredSize(buttonsSize); 
     panel.setLayout(new BorderLayout()); 
     panel.add(wait, BorderLayout.CENTER); 
     container.add(panel); 

     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setResizable(false); // unresizable 
    } 
} 
+0

私は問題が並行性またはその欠如に関連していると考えました。 –

+0

@JonnyHenly:概念の証明としてデモプログラムを参照してください。 –

+0

私のコメントはあなたの答えに同意していました。 –

関連する問題