2016-11-20 6 views
1

Я получил класс java под названием PleaseWait и хочу называть его всякий раз, когда выполняется тяжелая задача. Когда моя программа выполняет тяжелую задачу, в первой строке моего actionListener я установил переменную этого класса setVisible(true), а затем установил setVisible(true) в конце actionListener.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» (есть не только одна близкая причина, но и две, которые упоминают об этом). –

ответ

4

Ключ не в коде, вы в курсе, но в этой строке:

и хотите назвать это всякий раз, когда тяжелая задача выполняется

У вас запущена «тяжелая» задача, и пока вы ее запускаете, Swing не рисует этот графический интерфейс, потому что вы, вероятно, запускаете эту задачу в потоке событий Swing, и тем самым замораживает поток, и ваш графический интерфейс пользователя.

Решение: используйте фоновый поток, который можно получить через SwingWorker, для запуска «тяжелой» задачи.

Другие побочные вопросы:

  • Это, как представляется, «зависимый» или окно «к югу» от основного приложения. Если это так, это не должно быть JFrame, так как приложение должно иметь только одно основное окно приложения, но скорее это должен быть 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

О, мой комментарий соглашался с вашим ответом. –

Смежные вопросы