0

データベースから取得したリストを表示する SWT GUI があります。私がやりたいことは、GUI を定期的に更新することです。これには、シェル内のすべてをクリアし、populateList() メソッドを再度実行することが含まれます。これについていくつかの提案された戦略を試しましたが、GUI が更新されません。私の最近の試みは、display.asyncexec を使用して、これを処理するスレッドを作成することです。これにより、無効なスレッド アクセス エラーが発生するようです。

これが私のコードです:

package display;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import object_models.Request;
import util.RestClient.RequestMethod;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;


import util.RestClient;


public class StoragePickupDisplay {

    protected Shell shell;


    private ArrayList<Request> pendingRequests;
    /**
     * Launch the application.
     * @param args
     */
    public static void main(String[] args) {
        try {
            StoragePickupDisplay window = new StoragePickupDisplay();
            window.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Open the window.
     * @throws InterruptedException 
     */
    public void open() throws InterruptedException {
        Display display = Display.getDefault();
        createContents();
        populateList();
        shell.open();
        shell.layout();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }



        display.asyncExec(new Runnable() {
            public void run() {
              populateList();
            }
          });
        Thread.sleep(1000);

        }
    }

    /**
     * Create contents of the window.
     */
    protected void createContents() {
        shell = new Shell();
        //shell.setMaximized(true);

        //shell.setFullScreen(true);
        shell.setText("Request Pickup");
        shell.setMaximized(true);


        GridLayout gridLayout= new GridLayout(1,false);

        shell.setLayout(gridLayout);




    }
    protected void populateList(){


        pendingRequests=new ArrayList<Request>();

        RestClient client = new RestClient("http://XXXXXX:8080/StorageWebService/rest/operations/getPendingRequests");

        try {
            client.Execute(RequestMethod.GET);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        String response = client.getResponse();


        pendingRequests= parseResponse(response);



        for(Request request: pendingRequests){
            Composite row = new Composite(shell,SWT.NONE);

            GridLayout gridLayout = new GridLayout(4,true);
            gridLayout.marginTop=5;
            row.setLayout(gridLayout);
            row.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));


            Composite left = new Composite(row,SWT.NONE);
            left.setLayout(new GridLayout(2,false));
            left.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));

            Label label = new Label(left,SWT.LEFT);
            label.setText(""+request.getId());

            label.setFont(new Font(Display.getDefault(),"Arial",30, SWT.NONE));
            label.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, false, false));


            label = new Label(left,SWT.LEFT);
            label.setText(request.getNickname());
            label.setFont(new Font(Display.getDefault(),"Arial",30, SWT.NONE));
            label.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));

            label = new Label(row,SWT.LEFT);
            label.setText(""+request.getNumberCompleted()+" of "+request.getNumberItems()+" Picked");
            label.setFont(new Font(Display.getDefault(),"Arial",30, SWT.NONE));
            label.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));

            label = new Label(row,SWT.LEFT);
            label.setText("Estimated Wait Time:");
            label.setFont(new Font(Display.getDefault(),"Arial",30, SWT.NONE));
            label.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));



            Label separator = new Label(shell, SWT.HORIZONTAL|SWT.SEPARATOR|SWT.PUSH);

            GridData gridData = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
            //gridData.horizontalSpan=4;
            separator.setLayoutData(gridData);



        }

    }
    public ArrayList<Request> parseResponse(String response){
        ArrayList<Request> list = new ArrayList<Request>();
        try {



            XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser();
            parser.setInput(new StringReader(response));

            int eventType = parser.getEventType();


            Request curRequest = new Request();


            while (eventType != XmlPullParser.END_DOCUMENT) {
                if (eventType == XmlPullParser.START_TAG) {
                    String name = parser.getName();
                    if (name.equalsIgnoreCase("id")) {
                        String text = parser.nextText();
                        curRequest.setId(Integer.parseInt(text));

                    }
                    if (name.equalsIgnoreCase("nickname")) {
                        String text = parser.nextText();
                        curRequest.setNickname(text);

                    }
                    if (name.equalsIgnoreCase("numberCompleted")) {
                        String text = parser.nextText();
                        curRequest.setNumberCompleted(Integer.parseInt(text));

                    }
                    if (name.equalsIgnoreCase("numberItems")) {
                        String text = parser.nextText();
                        curRequest.setNumberItems(Integer.parseInt(text));

                    }
                    if (name.equalsIgnoreCase("status")) {
                        String text = parser.nextText();
                        curRequest.setStatus(Integer.parseInt(text));

                    }

                }

                if (eventType == XmlPullParser.END_TAG) {
                    if (parser.getName().equalsIgnoreCase("Request")) {
                        list.add(curRequest);
                        curRequest = new Request();
                    }
                }
                eventType = parser.next();
            }

        } catch (XmlPullParserException e) {

            e.printStackTrace();
        } catch (IOException e) {

            e.printStackTrace();
        }

        return list;

    }




}
4

3 に答える 3

3

Liam15 が既に述べたように、別のスレッドを開始する必要があります。そうしないと、UI がブロックされ、応答しなくなります。スレッドはデータ取得を処理し、UI を同期的または非同期的に更新する必要があります。

open() メソッドがどのように見えるかの例を次に示します。

public void open() throws InterruptedException {
    Display display = Display.getDefault();
    createContents();
    shell.open();

    Thread updateThread = new Thread() {
        public void run() {
            while (true) {
                final ArrayList<Request> pendingRequests = getPendingRequests();
                Display.getDefault().syncExec(new Runnable() {

                    @Override
                    public void run() {
                        populateList(pendingRequests);
                    }
                });

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    // background thread
    updateThread.setDaemon(true);
    updateThread.start();

    while (!shell.isDisposed()) {
        if (!display.readAndDispatch()) {
            display.sleep();
        }
    }
}

シェルをクリアしてシェルの内容を更新するには、次のコード行を populateList() メソッドに追加します。

メソッドの先頭に以下を追加します。

Control[] oldControls = shell.getChildren();

メソッドの最後に以下を追加します。

for (Control oldControl : oldControls) {
    oldControl.dispose();
}
shell.layout();
于 2013-03-31T10:26:29.487 に答える
1

以下の方法を使用してくださいDisplay

 public void timerExec (int milliseconds, Runnable runnable)

イベントループを実行する前に実行してください。

ex:
 display.timerExec(30000, new Runnable() {
            public void run() {
              populateList();
            }
          });

 while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
于 2013-04-01T14:30:20.160 に答える
0

定期的に GUI を再度開いたり、一部の情報を更新したりするループを使用して、別のスレッドを実行できます。

于 2013-03-29T20:48:15.757 に答える