当前位置: 首页 > 知识库问答 >
问题:

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

洪永长
2023-03-14

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

  1. 遗嘱执行人

我的目标是创建一个更新执行状态的ProgressBar,下面给出了使用的逻辑,

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

注意:在JFrame中添加面板后调用setViable(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);

    }

共有1个答案

柳项明
2023-03-14

关键可能在以下这些方法中:

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();
}

注意:代码未测试。

  • 请查看课程:Swing中的并发

如果这不能解决您的问题,那么您可能必须创建并发布一个sscce或一个最小示例程序/mcve,您可以将代码压缩为仍然编译和运行的最小位,没有外部依赖项(例如需要链接到数据库或图像),没有与您的问题无关的额外代码,但仍然可以证明您的问题。

例如,这个小程序在工作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);
        }

    }
}
 类似资料:
  • 我开发了一个小应用程序来跟踪我的日常工作活动,该工具包含两个类: 遗嘱执行人 我的目标是创建一个更新执行状态的ProgressBar,下面给出了使用的逻辑, 从Exector类中定义的执行任务()中,我创建了UIProgress对象。 UIProgress类扩展了JFrame。创建一个包含带有一个图像和进度条的标签的面板。我在这个类中定义了一个方法updateProgress,它设置了进度条的值。

  • 通过单击Experiment Parameters选项卡中的一个按钮(参见下面的屏幕截图),我创建并运行一个“PreviewAction”,它创建了一个新的选项卡,并用必要的组件填充它。下面是的代码。编辑:我还发布了一个自包含的最小版本,它模拟了真实项目中的条件,并展示了相同的行为。 这里至少存在两个问题: (或)根本不呈现 没有框架本身那么宽,我不知道为什么 我在挥杆方面不是很好,所以我可能错过

  • 有人能告诉我代码有什么问题吗?它只显示第一行和表头information.thks

  • 我正在尝试使用一个名为'jQuery.InstagramFeed'的库,它允许我在不使用访问令牌的情况下显示用户feed中的图像。所以,我一直在尝试使用它,但是,出于某种原因,它并没有向我展示任何东西。 我已经研究了几个星期了,我已经尝试了在这里的很多帖子(以及其他论坛)中提出的很多解决方案,比如下面这些: TypeError:$不是函数调用jQuery函数 “未捕获的TypeError:$不是函

  • 我不确定这是java问题还是与ubuntu有关。我在ubuntu 14.04机器上,我有Java6(jdk_1.60_43)和Java7(jdk_1.70_51)。JAVA_HOME设置为java 7,这就是我的PATH环境变量所指的。所以Java版本会给我以下内容: 现在我通过下载安装脚本并运行它(https://www.ej-technologies.com/download/jprofile