0

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

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

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

这是相关类的代码。首先,这是在组合上设置控件并使用 . 返回组合的类getControl()。然后将它返回的组合作为 a 插入TabItema 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();
    }
}

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

4

1 回答 1

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),就是这样Layouts 的用途。读这个:

于 2013-09-19T09:04:55.670 回答