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

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

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

这些方法可能是关键在这里:

getWorkedItems ();getWorkedTickets ();getRemainTickets ();

如果它们需要任何时间执行,则在Swing事件线程调用它们将阻塞该线程并完全冻结您的GUI,从而使其无法正确绘制自己。解决方案是在后台线程中调用任何长时间运行的方法,例如SwingWorker的

doInBackground()
方法,并仅在Swing事件线程上进行Swing调用。同样,SwingWorker可以很好地解决此问题,实际上,它具有可以使用的自己的“绑定”进度属性。在worker中,只需调用
setProgress(value)
其中value是您的int从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();}

注意:代码未经测试。

  • 请查看课程:Swing中的并发
  • 另请查看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 pre    private void getRemainTickets() {        mySleep(3);  // emulate long-running pre    }    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);        }    }}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5498766.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存