首页 > 解决方案 > 在 swt 画布上绘制多个矩形

问题描述

首先,这是一个附加问题

上一个问题: swt 中按区域改变颜色?

我解决了一次,但后来我尝试在这个画布上绘制几个框,但出现错误并与我联系

错误

Exception in thread "main" org.eclipse.swt.SWTException: Graphic is disposed
    at org.eclipse.swt.SWT.error(SWT.java:4869)
    at org.eclipse.swt.SWT.error(SWT.java:4784)
    at org.eclipse.swt.SWT.error(SWT.java:4755)
    at org.eclipse.swt.graphics.GC.setBackground(GC.java:4122)
    at View.MainWindow$2$1.paintControl(MainWindow.java:137)
    at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:234)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
    at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4195)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1037)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1061)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1046)
    at org.eclipse.swt.widgets.Composite.WM_PAINT(Composite.java:1616)
    at org.eclipse.swt.widgets.Control.windowProc(Control.java:4816)
    at org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:340)
    at org.eclipse.swt.widgets.Display.windowProc(Display.java:4921)
    at org.eclipse.swt.internal.win32.OS.DispatchMessage(Native Method)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3610)
    at View.MainWindow.init(MainWindow.java:185)
    at View.MainWindow.main(MainWindow.java:193)

我的代码

public class MainWindow implements Runnable {

    /**
     * Launch the application.
     * 
     * @param args
     */

    public void init() {
        Display display = Display.getDefault();
        Shell shell = new Shell();
        shell.setSize(720, 500);
        shell.setText("SWT Application");
        shell.setLayout(null);

        org.eclipse.swt.graphics.Color blue = display.getSystemColor(SWT.COLOR_BLUE);
        org.eclipse.swt.graphics.Color green = display.getSystemColor(SWT.COLOR_GREEN);
        org.eclipse.swt.graphics.Color darkBlue = display.getSystemColor(SWT.COLOR_DARK_BLUE);
        org.eclipse.swt.graphics.Color red = display.getSystemColor(SWT.COLOR_RED);
        org.eclipse.swt.graphics.Color gray = display.getSystemColor(SWT.COLOR_GRAY);
        
        Canvas canvas = new Canvas(shell, SWT.NONE);
        canvas.setBounds(41, 130, 640, 282);
        
        
        Composite composite_1 = new Composite(canvas, SWT.NONE);
        composite_1.setSize(1, 282);

        Composite composite_2 = new Composite(canvas, SWT.NONE);
        composite_2.setSize(640, 282);
        composite_2.setBackground(blue);
        
        Canvas canvas2 = new Canvas(composite_1, SWT.NONE);
        canvas2.setBounds(0,0, 640, 282);
        canvas2.setBackground(green);

        Label lblNewLabel = new Label(composite_2, SWT.NONE);
        lblNewLabel.setBounds(10, 69, 142, 156);
        lblNewLabel.setImage(new Image(display, "C:\\image.png"));

        Label degree0 = new Label(shell, SWT.NONE);
        degree0.setBounds(0, 122, 35, 15);
        degree0.setText("  0   -");

        Label degree360 = new Label(shell, SWT.NONE);
        degree360.setBounds(0, 402, 35, 15);
        degree360.setText("360 -");

        Label startDistance = new Label(shell, SWT.NONE);
        startDistance.setBounds(43, 423, 87, 15);
        startDistance.setText("0 m");

        Label previousDistance = new Label(shell, SWT.NONE);
        previousDistance.setBounds(659, 423, 35, 15);
        previousDistance.setText("30m");

        
        /*ArrayList<Integer> compositeArray = new ArrayList<Integer>();
        HashMap<Integer, Composite> myHashMap = new HashMap<Integer, Composite>();
          
        for(int i=0; i<100; i++) { compositeArray.add(i); }
          
        for(int i=0; i<=100; i++) { 
            myHashMap.put(i, Composite "$tempComposite"+compositeArray.get(i));
            myHashMap.get(i).setBounds(0, 0, 0, 0);
        }
          
        myHashMap.forEach((k,v)->{ 
            System.out.println("key: "+k+"value: "+v);
        });
         */

        //canvas.setBounds(41, 130, 640, 282);
        
        canvas2.addPaintListener(new PaintListener() {
            public void paintControl(PaintEvent e) {
                e.gc.setForeground(red);
                e.gc.setBackground(red);
                e.gc.drawRectangle(0, 0, 5, 10);
                e.gc.dispose();
              }
            });
        
        
        final Runnable run = new Runnable() {
            private int counter = 0;

            @Override
            public void run() {
                //Image Move
                lblNewLabel.setLocation(lblNewLabel.getLocation().x + 1, lblNewLabel.getLocation().y);

                //Composite Background GreenColor
                composite_1.setSize(composite_1.getSize().x + 1, 282);
                composite_1.setBackground(green);

                // ramdom 함수
                int random = (int) (Math.random() * 10);
                int randomH = (int) (Math.random() * 30);
                int randomW = (int) (Math.random() * 10) + 1;

                // TODO : 그냥 사각형 을 생성 및 점 생성 해야될거 같음 
                // 0~2 중만 점찍기
                switch (random) {
                case 0: {
                    //canvas2.redraw();
                    canvas2.addPaintListener(new PaintListener() {
                        public void paintControl(PaintEvent e) {
                            e.gc.setBackground(red);
                            e.gc.drawRectangle(composite_1.getSize().x, composite_1.getSize().y, 5, 15);
                            canvas2.dispose();
                            e.gc.dispose();

                          }
                        });
                    System.out.print(random);
                    break;
                }
                case 1: {
                    //canvas2.redraw();
                    canvas2.addPaintListener(new PaintListener() {
                        public void paintControl(PaintEvent e) {
                            e.gc.setBackground(gray);
                            e.gc.drawRectangle(composite_1.getSize().x, composite_1.getSize().y, 5, 15);
                            canvas2.dispose();
                            e.gc.dispose();
                          }
                        });
                    System.out.print(random);
                    break;
                }
                case 2: {
                    //canvas2.redraw();
                    canvas2.addPaintListener(new PaintListener() {
                        public void paintControl(PaintEvent e) {
                            e.gc.setBackground(darkBlue);
                            e.gc.drawRectangle(composite_1.getSize().x, composite_1.getSize().y, 5, 15);
                            canvas2.dispose();
                            e.gc.dispose();
                          }
                        });
                    System.out.print(random);
                    break;
                }
                }

                display.timerExec(1000, this);

            }
        };
        
        display.timerExec(1000, run);

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

    public static void main(String[] args) {
        MainWindow a = new MainWindow();
        a.init();
    }
    
    
    public void redrawCanvas (Canvas canvas) {
        GC gc = new GC(canvas);
        gc.dispose();
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        Display.getDefault().timerExec(1000, this);
    }
    
}

我也处理了 GC,但我不知道为什么会出现这个错误。你能告诉我我哪里错了吗?真的 swt 很难,所以我需要帮助

标签: javaswt

解决方案


删除所有

e.gc.dispose();

来电。

你应该只调用你创建的dispose对象,SWT 给你的对象不能被释放。GCnew GC(...)GC

您还必须删除所有canvas2.dispose()呼叫。在不再需要它之前,您不得丢弃控件。


推荐阅读