Java Jframe正在显示,但内容(面板)未正确显示

Java Jframe正在显示,但内容(面板)未正确显示,java,swing,Java,Swing,我开发了一个小应用程序来跟踪我的日常工作活动,该工具包含两个类: 执行人 UIProgress 我的目标是创建一个更新执行状态的ProgressBar,使用的逻辑如下所示 根据Executor类中定义的executeTask(),我已经创建了 UIProgress对象 UIProgress类扩展了JFrame。创建一个包含 带有一个图像和进度条的标签。我定义了一个 方法updateProgress,该方法设置 进步吧 在executeTask()方法(在Executor类中)中,创建了UIPr

我开发了一个小应用程序来跟踪我的日常工作活动,该工具包含两个类:

  • 执行人
  • UIProgress
  • 我的目标是创建一个更新执行状态的ProgressBar,使用的逻辑如下所示

    • 根据Executor类中定义的executeTask(),我已经创建了 UIProgress对象
    • UIProgress类扩展了JFrame。创建一个包含 带有一个图像和进度条的标签。我定义了一个 方法updateProgress,该方法设置 进步吧
    • 在executeTask()方法(在Executor类中)中,创建了UIProgress 对象在executeTask()中,我调用不同的函数来执行 每个函数调用后的任务和 带有整数值的UIProgress.updateProgress()方法来更新progressbar
    • 但在运行程序时,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();
        ...
    }
    
    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);
    
        }
    
    UIProgress.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();
        ...
    }
    
    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);
    
        }
    

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

    getWorkedItems ();        
    
    getWorkedTickets ();
    
    getRemainTickets ();    
    
    如果它们需要任何时间来执行,那么在Swing事件线程上调用它们将阻塞该线程并完全冻结GUI,使其无法正确绘制自身。解决方案是在后台线程中调用任何长时间运行的方法,例如SwingWorker的
    doInBackground()
    方法,并仅在Swing事件线程上进行Swing调用。同样,SwingWorker可以很好地实现这一点,事实上,它有自己的“绑定”进度属性,可以使用。在worker中,只需调用
    setProgress(value)
    ,其中value是从0到100的int。然后将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();
    }
    
    public void executeTask(){
    进度=新的UIProgress();
    progress.prepareGUI();
    最终SwingWorker myWorker=新SwingWorker(){
    @凌驾
    受保护的Void doInBackground()引发异常{
    //progress.updateProgress(10);
    setProgress(10);//设置工作进程的“绑定”进度属性
    getWorkedItems();
    进展(30);
    getWorkedTickets();
    统计进展(50);
    getRemainTickets();
    进展(70);
    //…这里只有进一步的背景工作
    //没有直接的Swing呼叫
    返回null;
    }
    };
    myWorker.addPropertyChangeListener(新的PropertyChangeListener(){
    @凌驾
    公共作废属性更改(属性更改事件evt){
    if(“progress”.equals(evt.getPropertyName())){
    //如果进度属性已更改
    //获取它的值并使用它更新GUI
    progress.updateProgress((int)evt.getNewValue());
    }else if(SwingWorker.StateValue.DONE==evt.getNewValue()){
    //worker完成后,在这里通知GUI
    //或许可以打电话:
    //jf.postTriagedTicketDetailsDaily();
    //对worker调用get()以捕获和处理异常
    试一试{
    myWorker.get();
    }捕获(中断异常|执行异常e){
    //我要处理这里的例外情况
    e、 printStackTrace();
    }
    }
    }
    });
    myWorker.execute();
    }
    
    注意:代码未测试

    • 请退房
    • 还可以查看
    如果这不能解决您的问题,那么您可能必须创建并发布一个或多个示例,其中您将代码压缩为最小的位,仍然可以编译和运行,没有外部依赖项(例如需要链接到数据库或图像),没有与您的问题无关的额外代码,但仍然可以演示您的问题

    例如,此小程序在工作GUI中演示上述代码:

    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);
            }
    
        }
    }
    
    import java.awt.*;
    导入java.awt.event.ActionListener;
    导入java.beans.PropertyChangeEvent;
    导入java.beans.PropertyChangeListener;
    导入java.io.IOException;
    导入java.net.URI;
    导入java.net.URISyntaxException;
    导入java.util.concurrent.ExecutionException;
    导入java.util.concurrent.TimeUnit;
    导入javax.swing.*;
    公共类测试人员{
    私营部门的进展;
    公共静态void main(字符串[]args){
    SwingUtilities.invokeLater(()->{
    新建TestWorker().executeTask();
    });
    }
    public void executeTask(){
    进度=新的UIProgress();
    progress.prepareGUI();
    最终SwingWorker myWorker=新SwingWorker(){
    @凌驾
    受保护的Void doInBackground()引发异常{
    //progress.updateProgress(10);
    setProgress(10);//设置工作进程的“绑定”进度属性
    getWorkedItems();
    进展(30);
    getWorkedTickets();
    统计进展(50);
    getRemainTickets();
    进展(70);
    时间单位。秒。睡眠(2);
    //…这里只有进一步的背景工作
    //没有直接的Swing呼叫
    返回null;
    }
    };
    myWorker.addPropertyChangeListen