第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何從 no-gui 類實時更新 Java Jframe 控件

如何從 no-gui 類實時更新 Java Jframe 控件

繁星淼淼 2021-11-11 17:45:09
我的 Java JFrame 項目有一個乏味的問題。我想要做的(并尋找如何做)是從無ListBoxGUI 類實時添加元素,或者換句話說“異步”,而不凍結(jié)我的應(yīng)用程序。這清楚嗎?我試過SwingWorker和線程但沒有結(jié)果。我所能做的就是在所有進(jìn)程完成后更新列表框(顯然我的應(yīng)用程序凍結(jié)了,因為我的進(jìn)程很長)。這是我的架構(gòu):控制器package controller;import business.MyBusiness;import util.MyLog;import view.MyView;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;public class MyController {    MyLog log;    MyBusiness business;    MyView view;    public MyController(){        log = new MyLog();        business = new MyBusiness(log.getLog());        view = new MyView(log.getLog());    }    public void runProcess() {        view.addButtonListener(new ActionListener() {             @Override             public void actionPerformed(ActionEvent e) {                 business.runProcess();            }}        );    }}商業(yè)package business;import MyLog;import java.util.List;import javax.swing.DefaultListModel;import javax.swing.SwingWorker;public class MyBusiness {    private int counter = 0;    private DefaultListModel<String> model;    private MyLog log;    public MyBusiness(DefaultListModel<String> model) {        this.model = model;a    }    public void runProcess() {        SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {            @Override            protected Void doInBackground() throws Exception {                for (int i = 0; i < 10; i++) {                    publish("log message number " + counter++);                    Thread.sleep(2000);                }                return null;            }            @Override            protected void process(List<String> chunks) {                // this is called on the Swing event thread                for (String text : chunks) {                    model.addElement("");                }            }        };        worker.execute();    }}
查看完整描述

2 回答

?
藍(lán)山帝景

TA貢獻(xiàn)1843條經(jīng)驗 獲得超7個贊

這是一個過度簡化的示例,String說明使用SwingWorker.


為了使 a 的基本使用SwingWorker更容易理解,它被過度簡化。


這是一個單文件mcve,這意味著您可以將整個代碼復(fù)制粘貼到一個文件 (MyView.java) 中并執(zhí)行:


import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.event.ActionListener;

import java.util.List;

import javax.swing.DefaultListModel;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JList;

import javax.swing.SwingWorker;


//gui only, unaware of logic 

public class MyView extends JFrame {


    private JList<String> loglist;

    private JButton log;


    public MyView(DefaultListModel<String> model) {


        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        log = new JButton("Start Process");

        add(log, BorderLayout.PAGE_START);

        loglist = new JList<>(model);

        loglist.setPreferredSize(new Dimension(200,300));


        add(loglist, BorderLayout.PAGE_END);

        pack();

        setVisible(true);

    }


    void addButtonListener(ActionListener listener) {

        log.addActionListener(listener);

    }


    public static void main(String args[]) {

        new MyController();

    }

}


//represents the data (and some times logic) used by GUI

class Model {


    private DefaultListModel<String> model;


    Model() {


        model = new DefaultListModel<>();

        model.addElement("No logs yet");

    }


    DefaultListModel<String> getModel(){

        return model;

    }

}


//"wires" the GUI, model and business process 

class MyController {


    MyController(){

        Model model = new Model();

        MyBusiness business = new MyBusiness(model.getModel());

        MyView view = new MyView(model.getModel());

        view .addButtonListener(e -> business.start());

    }

}


//represents long process that needs to update GUI

class MyBusiness extends SwingWorker<Void, String>{


    private static final int NUMBER_OF_LOGS = 9;

    private int counter = 0;

    private DefaultListModel<String> model;


    public MyBusiness(DefaultListModel<String> model) {

        this.model= model;

    }


    @Override  //simulate long process 

    protected Void doInBackground() throws Exception {


        for(int i = 0; i < NUMBER_OF_LOGS; i++) {


            //Successive calls to publish are coalesced into a java.util.List, 

            //which is by process.

            publish("log message number " + counter++);

            Thread.sleep(1000);

        }


        return null;

    }


    @Override

    protected void process(List<String> logsList) {

        //process the list received from publish

        for(String element : logsList) {

            model.addElement(element);

        }

    }


    void start() { 

        model.clear(); //clear initial model content 

        super.execute();

    }

}



查看完整回答
反對 回復(fù) 2021-11-11
?
哆啦的時光機

TA貢獻(xiàn)1779條經(jīng)驗 獲得超6個贊

首先是一些規(guī)則和建議:

  • 您的模型或此處的“業(yè)務(wù)”代碼應(yīng)該不了解 GUI,并且不應(yīng)依賴于 GUI 結(jié)構(gòu)

  • 同樣,所有 Swing 代碼都應(yīng)在事件線程上調(diào)用,所有長時間運行的代碼都應(yīng)在后臺線程中調(diào)用

  • 如果您有長時間運行的更改狀態(tài)的代碼,并且如果該狀態(tài)需要反映在 GUI 中,這意味著您需要某種回調(diào)機制,模型以某種方式通知重要方其狀態(tài)已經(jīng)改變。這可以使用 PropertyChangeListeners 或通過將某種類型的回調(diào)方法注入模型來完成。

  • 使視圖變得愚蠢。它從用戶那里獲取輸入并通知控制器,它由控制器更新。幾乎所有的程序“大腦”都位于控制器和模型中。例外——一些輸入驗證通常在視圖中完成。

  • 不要忽略基本的 Java OOP 規(guī)則——通過保持字段私有來隱藏信息,并允許外部類僅通過您完全控制的公共方法更新狀態(tài)。

  • MCVE結(jié)構(gòu)是一個很好的學(xué)習(xí)和使用,即使不問一個問題在這里。學(xué)習(xí)簡化您的代碼并隔離您的問題以最好地解決它。

例如,可以將此代碼復(fù)制并粘貼到所選 IDE 中的單個文件中,然后運行:

import java.awt.event.ActionEvent;

import java.awt.event.KeyEvent;

import java.util.List;

import java.util.Random;

import java.util.concurrent.TimeUnit;

import java.util.function.Consumer;

import javax.swing.*;


public class Mcve1 {

    private static void createAndShowGui() {

        // create your model/view/controller and hook them together

        MyBusiness1 model = new MyBusiness1();

        MyView1 myView = new MyView1();

        new MyController1(model, myView);  // the "hooking" occurs here


        // create and start the GUI

        JFrame frame = new JFrame("MCVE");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add(myView);

        frame.pack();

        frame.setLocationRelativeTo(null);

        frame.setVisible(true);

    }


    public static void main(String[] args) {

        // start GUI on Swing thread

        SwingUtilities.invokeLater(() -> createAndShowGui());

    }

}

@SuppressWarnings("serial")

class MyView1 extends JPanel {

    private MyController1 controller;

    private DefaultListModel<String> logListModel = new DefaultListModel<>();

    private JList<String> logList = new JList<>(logListModel);


    public MyView1() {

        logList.setFocusable(false);

        logList.setPrototypeCellValue("abcdefghijklabcdefghijklabcdefghijklabcdefghijkl");

        logList.setVisibleRowCount(15);

        add(new JScrollPane(logList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,

                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));


        // my view's buttons just notify the controller that they've been pushed

        // that's it

        add(new JButton(new AbstractAction("Do stuff") {

            {

                putValue(MNEMONIC_KEY, KeyEvent.VK_D);

            }


            @Override

            public void actionPerformed(ActionEvent evt) {

                if (controller != null) {

                    controller.doStuff(); // notification done here

                }

            }

        }));

    }


    public void setController(MyController1 controller) {

        this.controller = controller;

    }


    // public method to allow controller to update state

    public void updateList(String newValue) {

        logListModel.addElement(newValue);

    }

}

class MyController1 {

    private MyBusiness1 myBusiness;

    private MyView1 myView;


    // hook up concerns

    public MyController1(MyBusiness1 myBusiness, MyView1 myView) {

        this.myBusiness = myBusiness;

        this.myView = myView;

        myView.setController(this);

    }


    public void doStuff() {

        // long running code called within the worker's doInBackground method

        SwingWorker<Void, String> worker = new SwingWorker<Void, String>() {

            @Override

            protected Void doInBackground() throws Exception {

                // pass a call-back method into the method

                // so that this worker is notified of changes

                myBusiness.longRunningCode(new Consumer<String>() {                    

                    // call back code

                    @Override

                    public void accept(String text) {

                        publish(text); // publish to the process method

                    }

                });

                return null;

            }


            @Override

            protected void process(List<String> chunks) {

                // this is called on the Swing event thread

                for (String text : chunks) {

                    myView.updateList(text);

                }

            }

        };

        worker.execute();


    }


}

class MyBusiness1 {

    private Random random = new Random();

    private String text;


    public void longRunningCode(Consumer<String> consumer) throws InterruptedException {

        consumer.accept("Starting");

        // mimic long-running code

        int sleepTime = 500 + random.nextInt(2 * 3000);

        TimeUnit.MILLISECONDS.sleep(sleepTime);

        consumer.accept("This is message for initial process");


        // ...

        // Doing another long process and then print log

        // ...

        sleepTime = 500 + random.nextInt(2 * 3000);

        TimeUnit.MILLISECONDS.sleep(sleepTime);

        consumer.accept("This is not complete. Review");


        // ...

        // Doing another long process and then print log

        // ...

        sleepTime = 500 + random.nextInt(2 * 3000);

        TimeUnit.MILLISECONDS.sleep(sleepTime);

        consumer.accept("Ok this works. Have fun");

    }


    public String getText() {

        return text;

    }


}

另一種做同樣事情的方法是使用符合 Swing 的 PropertyChangeSupport 和 PropertyChangeListeners。例如:


import java.awt.event.ActionEvent;

import java.awt.event.KeyEvent;

import java.beans.*;

import java.util.Random;

import java.util.concurrent.TimeUnit;

import javax.swing.*;

import javax.swing.event.SwingPropertyChangeSupport;


public class Mcve2 {

    private static void createAndShowGui() {

        MyBusiness2 myBusiness = new MyBusiness2();

        MyView2 myView = new MyView2();

        new MyController2(myBusiness, myView);


        JFrame frame = new JFrame("MCVE");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add(myView);

        frame.pack();

        frame.setLocationRelativeTo(null);

        frame.setVisible(true);

    }


    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> createAndShowGui());

    }

}

@SuppressWarnings("serial")

class MyView2 extends JPanel {

    private MyController2 controller;

    private DefaultListModel<String> logListModel = new DefaultListModel<>();

    private JList<String> logList = new JList<>(logListModel);


    public MyView2() {

        logList.setFocusable(false);

        logList.setPrototypeCellValue("abcdefghijklabcdefghijklabcdefghijklabcdefghijkl");

        logList.setVisibleRowCount(15);

        add(new JScrollPane(logList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,

                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));

        add(new JButton(new AbstractAction("Do stuff") {

            {

                putValue(MNEMONIC_KEY, KeyEvent.VK_D);

            }


            @Override

            public void actionPerformed(ActionEvent evt) {

                if (controller != null) {

                    controller.doStuff();

                }

            }

        }));

    }

    public void setController(MyController2 controller) {

        this.controller = controller;

    }

    public void updateList(String newValue) {

        logListModel.addElement(newValue);

    }

}

class MyController2 {


    private MyBusiness2 myBusiness;

    private MyView2 myView;


    public MyController2(MyBusiness2 myBusiness, MyView2 myView) {

        this.myBusiness = myBusiness;

        this.myView = myView;

        myView.setController(this);


        myBusiness.addPropertyChangeListener(MyBusiness2.TEXT, new TextListener());

    }


    public void doStuff() {

        new Thread(() -> {

            try {

                myBusiness.longRunningCode();

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }) .start();

    }


    private class TextListener implements PropertyChangeListener {

        @Override

        public void propertyChange(PropertyChangeEvent evt) {

            String newValue = (String) evt.getNewValue();

            myView.updateList(newValue);

        }

    }


}

class MyBusiness2 {

    public static final String TEXT = "text";

    private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);

    private Random random = new Random();

    private String text;


    public void longRunningCode() throws InterruptedException {

        setText("Starting");

        // mimic long-running code

        int sleepTime = 500 + random.nextInt(2 * 3000);

        TimeUnit.MILLISECONDS.sleep(sleepTime);

        setText("This is message for initial process");


        // ...

        // Doing another long process and then print log

        // ...

        sleepTime = 500 + random.nextInt(2 * 3000);

        TimeUnit.MILLISECONDS.sleep(sleepTime);

        setText("This is not complete. Review");


        // ...

        // Doing another long process and then print log

        // ...

        sleepTime = 500 + random.nextInt(2 * 3000);

        TimeUnit.MILLISECONDS.sleep(sleepTime);

        setText("Ok this works. Have fun");

    }


    public void setText(String text) {

        String oldValue = this.text;

        String newValue = text;

        this.text = text;

        pcSupport.firePropertyChange(TEXT, oldValue, newValue);

    }


    public String getText() {

        return text;

    }


    public void addPropertyChangeListener(PropertyChangeListener listener) {

        pcSupport.addPropertyChangeListener(listener);

    }


    public void removePropertyChangeListener(PropertyChangeListener listener) {

        pcSupport.removePropertyChangeListener(listener);

    }


    public void addPropertyChangeListener(String name, PropertyChangeListener listener) {

        pcSupport.addPropertyChangeListener(name, listener);

    }


    public void removePropertyChangeListener(String name, PropertyChangeListener listener) {

        pcSupport.removePropertyChangeListener(name, listener);

    }

}



查看完整回答
反對 回復(fù) 2021-11-11
  • 2 回答
  • 0 關(guān)注
  • 249 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號