关于这个 SWT 布局,我做错了什么? [英] What am I doing wrong regarding this SWT Layout?

查看:28
本文介绍了关于这个 SWT 布局,我做错了什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to show a simple window in SWT. I want to divide the window into two equal parts, in the left area the user will provide his input, and the right area will show the result of the output.

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

Specifically, the user will type in some characters in the left area (in a textbox), these will be reflected in a label below the textbox. When the user clicks a 'Process' button, a screenshot of just the label control will be taken using Awt.Robot.createScreenCapture. I want to display this screenshot in the right area.

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

Later on, I want to use optical character recognition to read the label and display to the user what he typed in the textbox. But for now, I'm simply having trouble getting this layout to show up correctly. If I press process, then the screenshot image is displayed in the right column, but if I resize or maximize the window, it disappears.

这里是相关类的代码.首先,这是在组合上设置控件的类,并使用 getControl() 返回组合.它返回的组合然后作为 TabItem 插入到 TabFolder 中:

Here's the code of the relevant classes. First, this is the class which sets up the controls on a composite, and returns the composite using getControl(). The composite it returns is then inserted as a TabItem in a 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 类的代码:

Here's the code to the ImgCanvas class referenced above:

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 的代码:

Here's the code for 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();
    }
}

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

Any help on what I'm doing wrong or how to improve this would be appreciated.

推荐答案

好的,给你,用这个替换你的 ImgCanvas 类:

Ok, here you go, just replace your ImgCanvas class with this:

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...您可以重复使用旧的.

Not sure why you created a new Canvas each time you change the image... You can just reuse the old one.

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

Note: Never use .setSize(int, int) unless absolutely necessary, that's what Layouts are for. Read this:

这篇关于关于这个 SWT 布局,我做错了什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆