关于这个SWT布局,我做错了什么?

时间:2013-09-19 07:03:29

标签: java swt

我正试图在SWT中显示一个简单的窗口。我想将窗口分成两个相等的部分,在左侧区域中,用户将提供他的输入,右侧区域将显示输出的结果。

具体来说,用户将在左侧区域(文本框中)键入一些字符,这些字符将反映在文本框下方的标签中。当用户单击“处理”按钮时,将使用Awt.Robot.createScreenCapture获取标签控件的屏幕截图。我想在右侧区域显示此屏幕截图。

稍后,我想使用光学字符识别来读取标签并向用户显示他在文本框中输入的内容。但就目前而言,我只是无法正确显示此布局。如果我按下进程,则屏幕截图图像会显示在右栏中,但如果我调整窗口大小或最大化窗口,它就会消失。

这是相关课程的代码。首先,这是在复合上设置控件的类,并使用getControl()返回复合。然后,它返回的复合作为TabItem插入TabFolder

public class ReadChars
{
    //This is the root container to which all the other controls are added. This container is inserted
    //in a TabFolder as a TabItem:
    private Composite container;

    //Left side input column:

    private Group input;

   //Right side output column:
    private Group output;

    private String fontName;
    private int fontSize;
    private int fontStyle;
    private Font font;

    private Text sourceChars;
    private Label sourceCharsLbl;
    private Button processBtn;

    //Code for this is provided later:
    private ImgCanvas sourceCharsImg;

    public ReadChars(TabFolder parent)
    {        
        fontName = "Courier New";
        fontSize = 12;
        fontStyle = SWT.NORMAL;
        initCompontents(parent);
    }

    private void initCompontents(TabFolder parent)
    {
        container = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        layout.makeColumnsEqualWidth = true;
        container.setLayout(layout);

        font = new Font(Display.getDefault(), fontName, fontSize, fontStyle);
        container.setFont(font);

        input = new Group(container, SWT.NONE);
        input.setLayoutData(getGridData());
        output = new Group(container, SWT.NONE);
        output.setLayoutData(getGridData());


        initInputGroup();
        initOutputGroup();
    }

    private void initInputGroup()
    {
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;                
        layout.makeColumnsEqualWidth = true;

        input.setLayout(layout);

        getHeadingLabel(input).setText("Options");       
        new Label(input, SWT.NONE).setText("Type the characters to parse below (0-9 and .):");
        String defaults = "012345689.";
        sourceChars = getTextbox(input);       
        sourceChars.setText(defaults);

        sourceCharsLbl = new Label(input, SWT.NONE);
        sourceCharsLbl.setLayoutData( getGridData() );
        sourceCharsLbl.setFont(font);        
        sourceCharsLbl.setBackground( new Color(Display.getDefault(), 224, 224,224) );
        sourceCharsLbl.setText(defaults);

        sourceChars.addKeyListener(new KeyAdapter()
        {
            public void keyReleased(KeyEvent e)
            {
                System.out.println("here: " + sourceChars.getText());
                sourceCharsLbl.setText( sourceChars.getText() );
                System.out.println("Text now: " + sourceCharsLbl.getText());
            }
        });                        

        processBtn = new Button(input, SWT.NONE);
        processBtn.setText("Process");
        processBtn.addSelectionListener( getProcessHandler() );     

    }

    private void initOutputGroup()
    {
        //output.setVisible(false);
        GridLayout layout = new GridLayout();
        layout.numColumns = 1;                
        layout.makeColumnsEqualWidth = true;        
        output.setLayout(layout);

        getHeadingLabel(output).setText("Output");
        new Label(output, SWT.NONE).setText("Source Image: ");
        sourceCharsImg = new ImgCanvas(output );
    }

    protected Label getHeadingLabel(Group parent)
    {
        Font font = new Font(Display.getDefault(), fontName, 16, SWT.BOLD);

        Label result = new Label(parent, SWT.NONE);
        result.setFont(font);
        return result;
    }

    protected Text getTextbox(Group parent)
    {
        Text box = new Text(parent, SWT.BORDER);
        GridData data = getGridData();
        data.widthHint = 200;        
        box.setLayoutData(data);
        return box;
    }

    protected GridData getGridData()
    {
        GridData data = new GridData();
        data.horizontalAlignment = SWT.FILL;
        data.grabExcessHorizontalSpace = true;
        return data;
    }

    protected void updateSourceImg()
    {
        Image screenshot = ImgUtility.getScreenShot(sourceCharsLbl);
        GridData gd = new GridData();
        gd.widthHint = screenshot.getBounds().width;
        gd.heightHint = screenshot.getBounds().height;

        sourceCharsImg.setImage(screenshot);
        sourceCharsImg.getCanvas().setLayoutData(gd);
        sourceCharsImg.redraw();
    }

    protected SelectionAdapter getProcessHandler()
    {
        return new SelectionAdapter()
        {
            public void widgetSelected(SelectionEvent e)
            {
                updateSourceImg();
            }
        };
    }

    public Composite getControl()
    {
        return container;
    }
}

以下是上面引用的ImgCanvas类的代码:

public class ImgCanvas
{
    private Composite container;
    private Canvas canvas;
    private Image img;     
    private Object layoutData;

    public ImgCanvas(Composite parent)
    {
        container = new Composite(parent, SWT.NONE);
        container.setLayout( new FillLayout() );
    }

    public ImgCanvas(Composite parent, Image img)
    {
        container = new Composite(parent, SWT.NONE);        
        container.setLayout( new FillLayout() );
        setImage(img);
    }

    public void setCanvas(Canvas canvas)
    {
        if (this.canvas != null)
        {
            System.out.println("Calling dispose");
            this.canvas.dispose();
        }
        else
            System.out.println("Canvas is null");

        this.canvas = canvas;
        initCanvas();
    }

    public void setCanvas()
    {
        Canvas canvas = new Canvas(container, SWT.NONE);
        if (layoutData != null)
            canvas.setLayoutData(layoutData);        
        setCanvas(canvas);
    }

    public void setImage(Image img)
    {
        setCanvas();
        this.img = img; //keep this below setCanvas() to avoid being disposed.
        Composite parent = container.getParent();
        parent.setSize(parent.getBounds().width + img.getBounds().width, 
                parent.getBounds().height + img.getBounds().height);
        container.setSize(img.getBounds().width, img.getBounds().height);
        canvas.setSize(img.getBounds().width, img.getBounds().height);        

        System.out.println("Set image: " + img.getBounds() + ", " + img.toString());
        redraw();
    }

    public Canvas getCanvas()
    {
        return canvas;
    }

    public Composite getContainer()
    {
        return container;
    }

    public Image getImage()
    {
        return img;
    }

    public void redraw()
    {
        System.out.println("redrawing");
        canvas.redraw();
    }

    public void setLayoutData( Object data )
    {
        container.setLayoutData(data);
        canvas.setLayoutData(data);
        this.layoutData = data;
    }

    protected void initCanvas()
    {
        System.out.println("Canvas started");
        canvas.addPaintListener( getPaintListener() );    
        canvas.addDisposeListener(getDisposeListener());
    }

    protected PaintListener getPaintListener()
    {
        return new PaintListener()
        {
            public void paintControl(PaintEvent e)
            {
                System.out.println("Painting");
                if (img != null )
                {
                    System.out.println("Img:" + img.getBounds() );
                    e.gc.drawImage(img, 0, 0);
                    System.out.println("Canvas: " + canvas.getBounds() );
                    //canvas.setSize(img.getBounds().width, img.getBounds().width);
                    //canvas.pack();
                }
                else
                    System.out.println("Img is null: " + img);
            }
        };
    }

    protected DisposeListener getDisposeListener()
    {
        return new DisposeListener()
        {
            @Override
            public void widgetDisposed(DisposeEvent e)
            {
                System.out.println("Disposing");
                if (img != null)
                {                    
                    Composite parent = container.getParent();
                    parent.setSize(parent.getBounds().width - img.getBounds().width, 
                        parent.getBounds().height - img.getBounds().height);
                    img.dispose();
                }
            }
        };
    }
}

以下是ImgUtility的代码:

public class ImgUtility
{
    private static Robot bot;
    private static Display display;
    public static BufferedImage convertToAWT(ImageData data)
    {
        ColorModel colorModel = null;
        PaletteData palette = data.palette;
        if (palette.isDirect)
        {
            colorModel = new DirectColorModel(data.depth, palette.redMask, palette.greenMask, palette.blueMask);
            BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null);
            for (int y = 0; y < data.height; y++)
            {
                for (int x = 0; x < data.width; x++)
                {
                    int pixel = data.getPixel(x, y);
                    RGB rgb = palette.getRGB(pixel);
                    bufferedImage.setRGB(x, y,  rgb.red << 16 | rgb.green << 8 | rgb.blue);
                }
            }
            return bufferedImage;
        }
        else
        {
            RGB[] rgbs = palette.getRGBs();
            byte[] red = new byte[rgbs.length];
            byte[] green = new byte[rgbs.length];
            byte[] blue = new byte[rgbs.length];
            for (int i = 0; i < rgbs.length; i++) {
                RGB rgb = rgbs[i];
                red[i] = (byte)rgb.red;
                green[i] = (byte)rgb.green;
                blue[i] = (byte)rgb.blue;
            }
            if (data.transparentPixel != -1) {
                colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue, data.transparentPixel);
            }
            else
            {
                colorModel = new IndexColorModel(data.depth, rgbs.length, red, green, blue);
            }       
            BufferedImage bufferedImage = new BufferedImage(colorModel, colorModel.createCompatibleWritableRaster(data.width, data.height), false, null);
            WritableRaster raster = bufferedImage.getRaster();
            int[] pixelArray = new int[1];
            for (int y = 0; y < data.height; y++)
            {
                for (int x = 0; x < data.width; x++)
                {
                    int pixel = data.getPixel(x, y);
                    pixelArray[0] = pixel;
                    raster.setPixel(x, y, pixelArray);
                }
            }
            return bufferedImage;
    }
}

    public static ImageData convertToSWT(BufferedImage bufferedImage)
    {
        if (bufferedImage.getColorModel() instanceof DirectColorModel) {
            DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel();
            PaletteData palette = new PaletteData(colorModel.getRedMask(), colorModel.getGreenMask(), colorModel.getBlueMask());
            ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
            for (int y = 0; y < data.height; y++)
            {
                for (int x = 0; x < data.width; x++) {
                    int rgb = bufferedImage.getRGB(x, y);
                    int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF)); 
                    data.setPixel(x, y, pixel);
                    if (colorModel.hasAlpha()) {
                        data.setAlpha(x, y, (rgb >> 24) & 0xFF);
                    }
                }
            }
            return data;        
        }
        else if (bufferedImage.getColorModel() instanceof IndexColorModel)
        {
            IndexColorModel colorModel = (IndexColorModel)bufferedImage.getColorModel();
            int size = colorModel.getMapSize();
            byte[] reds = new byte[size];
            byte[] greens = new byte[size];
            byte[] blues = new byte[size];
            colorModel.getReds(reds);
            colorModel.getGreens(greens);
            colorModel.getBlues(blues);
            RGB[] rgbs = new RGB[size];
            for (int i = 0; i < rgbs.length; i++)
            {
                rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF);
            }
            PaletteData palette = new PaletteData(rgbs);
            ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), colorModel.getPixelSize(), palette);
            data.transparentPixel = colorModel.getTransparentPixel();
            WritableRaster raster = bufferedImage.getRaster();
            int[] pixelArray = new int[1];
            for (int y = 0; y < data.height; y++)
            {
                for (int x = 0; x < data.width; x++)
                {
                    raster.getPixel(x, y, pixelArray);
                    data.setPixel(x, y, pixelArray[0]);
                }
            }
            return data;
        }
        return null;
    }

    public static Image getImage(ImageData data)
    {
        return new Image(display, data);
    }

    public static void setDisplay(Display newDisplay)
    {
        display = newDisplay;
    }

    public static BufferedImage getRawScreenShot(int x, int y, int width, int height)
    {
        java.awt.Rectangle region = new java.awt.Rectangle(x, y, width, height);
        BufferedImage bim = getRobot().createScreenCapture(region);
        return bim;
    }


    public static BufferedImage getRawScreenShot(Control ctrl)
    {
        Point loc = ctrl.getLocation();        
        loc = ctrl.toDisplay(1, 1);
        //ctrl.toDisplay(1, y)

        Point size = ctrl.getSize();          
        return getRawScreenShot(loc.x, loc.y, size.x, size.y);
    }

    public static Image getScreenShot(int x, int y, int width, int height)
    {
        BufferedImage bim = getRawScreenShot(x, y, width, height);
        return getImage( convertToSWT(bim) );
    }    

    public static Image getScreenShot(Control ctrl)
    {
        BufferedImage bim = getRawScreenShot(ctrl);
        return getImage( convertToSWT(bim) );
    }

    public static Robot getRobot()
    {
        if (bot == null)
        {
            try
            {
                bot = new java.awt.Robot();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }        
        return bot;
    }
}

* 编辑:* 以下是主要类:

public class Main
{
    public static void main(String[] args)
    {
        ImgUtility.setDisplay(Display.getDefault());
        WinMgr main = WinMgr.getMain();
        Shell win = main.getShell();   
        win.setLayout( new FillLayout() );
        initComponents(win);

        WinMgr.init(win);
    }

    private static void initComponents(Shell win)
    {
        win.setText("Optical Recognition Libraries");

        Rectangle area = win.getClientArea();
        TabFolder tabs = new TabFolder(win, SWT.FILL);        
        tabs.setLocation(area.x, area.y);        

        new TabItem(tabs, SWT.NONE).setText("Read Characters");
        tabs.getItem(0).setControl( new ReadChars(tabs).getControl() );

    }
}

这是WinMgr类:

public class WinMgr
{
    private Shell shell;
    private static WinMgr mainWinMgr;
    public WinMgr()
    {
        shell = new Shell();
        initShell();
    }       

    public WinMgr(int style)
    {
        shell = new Shell(style);
        initShell();
    }

    public WinMgr(Display parent, int style)
    {
        shell = new Shell(parent, style);
        this.initShell();
    }

    public WinMgr(Display parent)
    {
        shell = new Shell(parent);
        this.initShell();
    }

    public WinMgr(Shell parent, int style)
    {
        shell = new Shell(parent, style);
        this.initShell();
    }

    public Shell getShell()
    {
        return shell;
    }

    public void setShell(Shell newShell)
    {
        shell = newShell;
    }

    public void center()
    {
        Monitor primary = Display.getDefault().getPrimaryMonitor();

    }

    protected void initShell()
    {
        shell.addListener(SWT.Close, this.getOnClose() );
    }

    protected Listener getOnClose()
    {
        return new Listener()
        {
            public void handleEvent(Event event)
            {
                System.out.println("closing");
                shell.dispose();
            }
        };
    }            
    public static void init(Shell mainWin, boolean open)
    {
        Display display = Display.getDefault();

        if (open)
            mainWin.open();

        while (! mainWin.isDisposed())
        {
            try
            {
                if (! display.readAndDispatch())
                    display.sleep();                    
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }             
        }
        display.dispose();
    }

    public static void init(Shell mainWin)
    {
        init(mainWin, true);
    }

    public static WinMgr getMain()
    {
        if (mainWinMgr == null)
            mainWinMgr = new WinMgr( Display.getDefault() );

        return mainWinMgr;
    }

    public static Shell getMainShell()
    {
        return mainWinMgr.getShell();
    }
}

对于我做错了什么或如何改进这一点的任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

好的,在这里,你只需用{:}替换你的ImgCanvas课程。

private Composite   container;
private Canvas      canvas;
private Image       img;

public ImgCanvas(Composite parent)
{
    container = new Composite(parent, SWT.NONE);
    container.setLayout(new GridLayout(1, false));
    container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    canvas = new Canvas(container, SWT.BORDER);
    canvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    initCanvas();
}

public ImgCanvas(Composite parent, Image img)
{
    this(parent);
    setImage(img);
}

public void setImage(Image img)
{
    this.img = img; // keep this below setCanvas() to avoid being disposed.
    System.out.println("Set image: " + img.getBounds() + ", " + img.toString());
    redraw();
}

public void redraw()
{
    System.out.println("redrawing");
    canvas.redraw();
}

protected void initCanvas()
{
    System.out.println("Canvas started");
    canvas.addPaintListener(new PaintListener()
    {
        public void paintControl(PaintEvent e)
        {
            System.out.println("Painting");
            if (img != null)
            {
                System.out.println("Img:" + img.getBounds());
                e.gc.drawImage(img, 0, 0);
                System.out.println("Canvas: " + canvas.getBounds());
            }
            else
                System.out.println("Img is null: " + img);
        }
    });
    canvas.addDisposeListener(new DisposeListener()
    {
        @Override
        public void widgetDisposed(DisposeEvent e)
        {
            System.out.println("Disposing");
            if (img != null)
            {
                img.dispose();
            }
        }
    });
}

不确定为什么每次更改图片时都创建了新的Canvas ...您可以重复使用旧版本。


注意:从不使用.setSize(int, int),除非绝对必要,这就是Layout的用途。阅读本文: