2016-12-20 76 views
0

我已经开发了一个小的应用程序来跟踪我的日常工作活动,该工具包含两个类:的Java JFrame中被显示,但内容(面板)不能正常显示

  1. 执行人
  2. UIProgress

我的目标是建立一个进度条,其更新的执行,使用下面给出的逻辑的状态,

  • 从Executor类中定义的executeTask(),我创建了 UIProgress对象。
  • UIProgress类扩展了JFrame。创建一个包含 标签的面板,其中包含一个图像和进度条。我在这个类中定义了一个 方法updateProgress,它为 进度条设置了值。
  • 在executeTask()方法(在Executor类中)中,创建了UIProgress 对象。在executeTask()中,我调用不同的函数来执行 任务,并且在每个函数调用 带有整数值的UIProgress.updateProgress()方法来更新进度条。
  • 但是在运行程序时,JFrame UI是透明的,意味着它没有显示内容,而是包含框架中的背景数据。只有progressbar正在显示并且它正在更新,但是整个JFrame是透明的。我们没有看到面板(图像),它显示为透明模式。

注意:在将面板添加到JFrame后调用setVisible(true)。

Executor.java

public void executeTask () 
{ 

    /* Create and display the form */ 

    progress = new UIProgress(); 
    progress.prepareGUI(); 

    progress.updateProgress (10);   
    getWorkedItems();   
    //progress.pack(); 

    progress.updateProgress (30); 
    getWorkedTickets(); 



    progress.updateProgress (50); 
    getRemainTickets();  

    progress.updateProgress (70); 
    jf.postTriagedTicketDetailsDaily(); 
    ... 
} 

UIProgress.java

public class UIProgress extends javax.swing.JFrame { 
    public UIProgress() { 

      try { 
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); 
      } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
     } 
     initComponents(); 

    } 


    private void initComponents() { 

     panelHeading = new javax.swing.JPanel(); 
     jLabel1 = new javax.swing.JLabel(); 
     progress_cntrl = new javax.swing.JProgressBar(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     panelHeading.setBackground(new java.awt.Color(204, 204, 204)); 
     panelHeading.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0))); 
     panelHeading.setDebugGraphicsOptions(javax.swing.DebugGraphics.NONE_OPTION); 
     panelHeading.setOpaque(false); 

     jLabel1.setBackground(new java.awt.Color(0, 0, 0)); 
     jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/devtriagerepot_daily/Background-20.jpeg"))); // NOI18N 

     javax.swing.GroupLayout panelHeadingLayout = new javax.swing.GroupLayout(panelHeading); 
     panelHeading.setLayout(panelHeadingLayout); 
     panelHeadingLayout.setHorizontalGroup(
      panelHeadingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelHeadingLayout.createSequentialGroup() 
       .addContainerGap(29, Short.MAX_VALUE) 
       .addComponent(progress_cntrl, javax.swing.GroupLayout.PREFERRED_SIZE, 651, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addGap(27, 27, 27)) 
      .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) 
     ); 
     panelHeadingLayout.setVerticalGroup(
      panelHeadingLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(panelHeadingLayout.createSequentialGroup() 
       .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 147, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addGap(26, 26, 26) 
       .addComponent(progress_cntrl, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addGap(0, 31, Short.MAX_VALUE)) 
     ); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addComponent(panelHeading, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addGap(0, 4, Short.MAX_VALUE)) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 
       .addComponent(panelHeading, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) 
     ); 

     getAccessibleContext().setAccessibleParent(this); 

     pack(); 
    } 
    public void prepareGUI() 
    { 
     progress_cntrl.setMaximum(120); 
     progress_cntrl.setStringPainted(true); 

     Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize(); 
     int x = (int) ((dimension.getWidth() - this.getWidth())/2); 
     int y = (int) ((dimension.getHeight() - this.getHeight())/2); 
     this.setLocation(x, y); 

     pack(); 
     setVisible(true); 
    } 

    public void updateProgress (int val) 
    { 

     progress_cntrl.update(progress_cntrl.getGraphics()); 
     progress_cntrl.setValue(val); 

    } 
+0

发布您的代码的相关部分。 –

+0

添加了代码片段。 –

+0

查看编辑以回答 –

回答

2

的关键很可能在这些方法在这里:

getWorkedItems();   

getWorkedTickets(); 

getRemainTickets();  

如果他们采取任何时间表演完全,你的在Swing事件线程中调用它们会阻塞线程并完全冻结您的GUI,导致它无法正确绘制自己。解决方法是在后台线程中调用任何长时间运行的方法,例如SwingWorker的doInBackground()方法,并仅在Swing事件线程上进行Swing调用。 SwingWorker再一次为此工作得很好,实际上它有自己的“绑定”进度属性可以使用。在worker中,只需调用setProgress(value),其中value的取值范围是0到100。然后,将一个PropertyChangeListener附加到worker上,以便在更新progress属性时可以通知GUI这些更改。

一个告诫:一定要听取工人完成其运行,以便您可以调用get()上的工人,因为这个病让你陷阱和响应在运行期间可能被调用的任何异常。

例如,您的代码可能看起来是这样的:

public void executeTask() { 
    progress = new UIProgress(); 
    progress.prepareGUI(); 

    final SwingWorker<Void, Void> myWorker = new SwingWorker<Void, Void>() { 
     @Override 
     protected Void doInBackground() throws Exception { 
      // progress.updateProgress (10); 
      setProgress(10); // sets the worker's "bound" progress property 
      getWorkedItems(); 

      setProgress(30); 
      getWorkedTickets(); 

      setProgress(50); 
      getRemainTickets(); 

      setProgress(70); 

      // ... only further background work goes here 
      // no direct Swing calls 
      return null; 
     } 
    }; 
    myWorker.addPropertyChangeListener(new PropertyChangeListener() { 

     @Override 
     public void propertyChange(PropertyChangeEvent evt) { 

      if ("progress".equals(evt.getPropertyName())) { 
       // if the progress property has been changed 
       // get its value and use it to update the GUI 
       progress.updateProgress((int) evt.getNewValue()); 
      } else if (SwingWorker.StateValue.DONE == evt.getNewValue()) { 
       // worker is done then here notify the GUI 
       // perhaps call: 
       // jf.postTriagedTicketDetailsDaily(); 

       // call get() on worker to catch and handle exceptions 
       try { 
        myWorker.get(); 
       } catch (InterruptedException | ExecutionException e) { 
        // TODO handle the excpetions here 
        e.printStackTrace(); 
       } 
      } 
     } 
    }); 
    myWorker.execute(); 
} 

注:代码没有测试。

如果这没有解决您的问题,那么你可能将不得不创建和发布sscce或您将一份minimal example program/mcve你的代码进入了仍然编译和运行的最小位,没有外部依赖(例如需要链接到数据库或图像),没有额外的代码与你的问题无关,但仍然显示你的问题。

例如,这个小程序演示了一个工作界面上面的代码:

import java.awt.*; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.io.IOException; 
import java.net.URI; 
import java.net.URISyntaxException; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.TimeUnit; 

import javax.swing.*; 

public class TestWorker { 
    private UIProgress progress; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> { 
      new TestWorker().executeTask(); 
     }); 
    } 

    public void executeTask() { 
     progress = new UIProgress(); 
     progress.prepareGUI(); 

     final SwingWorker<Void, Void> myWorker = new SwingWorker<Void, Void>() { 
      @Override 
      protected Void doInBackground() throws Exception { 
       // progress.updateProgress (10); 
       setProgress(10); // sets the worker's "bound" progress property 
       getWorkedItems(); 

       setProgress(30); 
       getWorkedTickets(); 

       setProgress(50); 
       getRemainTickets(); 

       setProgress(70); 

       TimeUnit.SECONDS.sleep(2); 

       // ... only further background work goes here 
       // no direct Swing calls 
       return null; 
      } 
     }; 
     myWorker.addPropertyChangeListener(new PropertyChangeListener() { 

      @Override 
      public void propertyChange(PropertyChangeEvent evt) { 

       if ("progress".equals(evt.getPropertyName())) { 
        // if the progress property has been changed 
        // get its value and use it to update the GUI 
        progress.updateProgress((int) evt.getNewValue()); 
       } else if (SwingWorker.StateValue.DONE == evt.getNewValue()) { 
        // worker is done then here notify the GUI 
        progress.updateProgress(100); 
        // perhaps call: 
        // jf.postTriagedTicketDetailsDaily(); 

        // call get() on worker to catch and handle exceptions 
        try { 
         myWorker.get(); 
        } catch (InterruptedException | ExecutionException e) { 
         // TODO handle the exceptions here 
         e.printStackTrace(); 
        } 
       } 
      } 
     }); 
     myWorker.execute(); 
    } 

    // dummy methods just to demonstrate long-running code 
    private void getRemainTickets() { 
     mySleep(3); // emulate long-running code 
    } 

    private void getWorkedTickets() { 
     mySleep(4); 
    } 

    private void getWorkedItems() { 
     mySleep(2); 
    } 

    private void mySleep(int seconds) { 
     try { 
      TimeUnit.SECONDS.sleep(seconds); 
     } catch (InterruptedException e) {} 
    } 

    @SuppressWarnings("serial") 
    private class UIProgress extends JPanel { 
     private static final int PREF_W = 400; 
     private static final int PREF_H = 100; 
     private JProgressBar progressBar = new JProgressBar(0, 100); 
     private JLabel statusLabel = new JLabel(" "); 

     public UIProgress() { 
      JPanel statusPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0)); 
      statusPanel.add(new JLabel("Status:")); 
      statusPanel.add(Box.createHorizontalStrut(4)); 
      statusPanel.add(statusLabel);    

      setLayout(new BorderLayout()); 
      setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); 
      add(statusPanel, BorderLayout.PAGE_START); 
      add(progressBar, BorderLayout.PAGE_END); 
     } 

     public void prepareGUI() { 
      JFrame frame = new JFrame("UI Progress"); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.add(this); 
      frame.pack(); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
     } 

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

     public void updateProgress(int prog) { 
      String text = String.format("Current Progress is %d%%", prog); 
      statusLabel.setText(text); 
      progressBar.setValue(prog); 
     } 

    } 
} 
+0

非常感谢。现在工作正常。 –