0

SWT で単純なウィンドウを表示しようとしています。ウィンドウを 2 つの等しい部分に分割したいと思います。左側の領域ではユーザーが入力を行い、右側の領域には出力の結果が表示されます。

具体的には、ユーザーが左側の領域 (テキスト ボックス) にいくつかの文字を入力すると、これらの文字がテキスト ボックスの下のラベルに反映されます。ユーザーが「プロセス」ボタンをクリックすると、ラベル コントロールのみのスクリーンショットが を使用して取得されAwt.Robot.createScreenCaptureます。このスクリーンショットを右側の領域に表示したいと思います。

後で、光学式文字認識を使用してラベルを読み取り、テキスト ボックスに入力した内容をユーザーに表示したいと考えています。しかし、今のところ、このレイアウトを正しく表示するのに問題があります。プロセスを押すと、スクリーンショット画像が右側の列に表示されますが、ウィンドウのサイズを変更または最大化すると、ウィンドウが消えます。

関連するクラスのコードは次のとおりです。まず、これはコンポジット上にコントロールをセットアップし、 を使用してコンポジットを返すクラスgetControl()です。それが返すコンポジットは、 aTabItemに 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上記のクラスのコードは次のとおりです。

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)に必要な場合を除き、絶対に使用しないでください。それLayoutが s の目的です。これを読む:

于 2013-09-19T09:04:55.670 に答える