2017-10-09 8 views
1

SWTを使用してカスタムスライダを作成しようとしていますが、奇妙な結果がありました。ここに何か不足していて、余裕のある内部キャンバスを持つコンポジットが必要ですすべての周りに15の上、左と右と下。これに似た 何か:レイアウトとマウスイベント

enter image description here

だから私はこのようなメインを書いた:

Main.java

import org.eclipse.swt.SWT; 
import org.eclipse.swt.layout.GridLayout; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 
import org.eclipse.swt.widgets.Text; 

public class Main { 

public static void main (String [] args) { 
    Display display = new Display(); 
    Shell shell = new Shell(display); 
    shell.setLayout(new GridLayout(1,false)); 
    shell.setSize(400,400); 
    CustomSlider slider= new CustomSlider(shell, SWT.NONE); 


    shell.pack(); 
    shell.open(); 

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

複合拡張customSliderクラス:

import org.eclipse.swt.SWT; 
import org.eclipse.swt.events.PaintEvent; 
import org.eclipse.swt.events.PaintListener; 
import org.eclipse.swt.graphics.GC; 
import org.eclipse.swt.graphics.Point; 
import org.eclipse.swt.graphics.Rectangle; 
import org.eclipse.swt.layout.GridData; 
import org.eclipse.swt.layout.GridLayout; 
import org.eclipse.swt.widgets.Canvas; 
import org.eclipse.swt.widgets.Composite; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Event; 
import org.eclipse.swt.widgets.Listener; 
import org.eclipse.swt.widgets.Widget; 

public class CustomSlider extends Composite { 
    private Canvas progressBar; 
    private Rectangle progressBarRect; 
    private int knobSize=15; 
    private Point thisSize; 
    private boolean hover=false; 
    public CustomSlider(Composite arg0, int arg1) { 
     super(arg0, arg1); 
     thisSize= new Point(400, 50); 
     setSize(400, 50); 
     setBackground(arg0.getDisplay().getSystemColor(SWT.COLOR_MAGENTA)); 
     GridLayout gl= new GridLayout(1,false); 
     setLayout(gl); 
     setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 


     progressBar = new Canvas(this, SWT.NONE); 
     GridLayout gl2= new GridLayout(1,false); 
     gl2.marginBottom=knobSize; 
     gl2.marginTop=knobSize; 
     gl2.marginLeft=knobSize; 
     gl2.marginRight=knobSize; 
     gl2.marginWidth=knobSize; 
     gl2.marginHeight=knobSize; 
     progressBar.setLayout(gl2); 
     GridData gd=new GridData(SWT.FILL, SWT.FILL, true, true); 

     progressBar.setLayoutData(gd); 
     progressBar.addPaintListener(new PaintListener() { 

      @Override 
      public void paintControl(PaintEvent arg0) { 
       Canvas canvasProgress=(Canvas)arg0.widget; 
       progressBarRect= canvasProgress.getBounds(); 

       GC gc=arg0.gc; 
       gc.setForeground(canvasProgress.getDisplay().getSystemColor(SWT.COLOR_GREEN)); 
       if (hover){ 
       gc.setBackground(canvasProgress.getDisplay().getSystemColor(SWT.COLOR_RED)); 
       }else{ 
        gc.setBackground(canvasProgress.getDisplay().getSystemColor(SWT.COLOR_BLUE)); 
       } 
       gc.fillRectangle(progressBarRect); 
       gc.drawRectangle(progressBarRect); 

      } 
     }); 


     Listener listener = new Listener() { 
       public void handleEvent(Event event) { 
        System.out.println("---------------"); 
        System.out.println("Canvas:"+((Canvas)event.widget).getBounds()); 
        System.out.println("Composite:"+((Canvas)event.widget).getParent().getBounds()); 
        System.out.println("Shell:"+((Canvas)event.widget).getParent().getParent().getBounds()); 
        Display display=((Widget)event.widget).getDisplay(); 
       switch (event.type) { 

       case SWT.MouseHover: 
        if (progressBarRect.contains(new Point(event.x, event.y))){ 

          hover=true; 
         }else{ 

          hover=false; 
         } 
         break; 

       case SWT.MouseDown: 

        break; 
       case SWT.MouseMove: 
        if (progressBarRect.contains(new Point(event.x, event.y))){ 

          hover=true; 
         }else{ 

          hover=false; 
         } 

        break; 
       case SWT.MouseEnter: 
        if (progressBarRect.contains(new Point(event.x, event.y))){ 

          hover=true; 
         }else{ 

          hover=false; 
         } 

        break; 
       case SWT.MouseExit: 
        if (progressBarRect.contains(new Point(event.x, event.y))){ 
         System.out.println("progressBarRect:"+progressBarRect); 
         System.out.println("Point"+new Point(event.x, event.y)); 
         System.out.println("HOVER!"); 
          hover=true; 
         }else{ 
          System.out.println("OUT!"); 
          hover=false; 
         } 

        break; 
       case SWT.MouseUp: 

        break; 


       } 
       display.asyncExec(() -> progressBar.redraw()); 
       } 
      }; 
      progressBar.addListener(SWT.MouseDown, listener); 
      progressBar.addListener(SWT.MouseUp, listener); 
      progressBar.addListener(SWT.MouseMove, listener); 
      progressBar.addListener(SWT.MouseExit, listener); 
      progressBar.addListener(SWT.MouseEnter, listener); 
      progressBar.addListener(SWT.MouseHover, listener); 



    } 
    public Point getThisSize() { 
     return thisSize; 
    } 
    public void setThisSize(Point thisSize) { 
     this.thisSize = thisSize; 
    } 


} 

今、最初のものはresですULTは、2つだけ(左上と)マージンは考慮されていないようだ、またはより良い、私が欲しいものと一致しません:

enter image description here

第二に、イベントは、予期しない結果になる:MouseExitイベント私はコンポジットから外れていてもキャンバスをつかんでいます! :S

enter image description here

あなたは私がここで何が起こっているか理解するのに助けてくださいことはできますか?

は、私は次のように私のコードを編集グレッグの提案に続きEDIT

...事前にありがとう:

メイン:

import org.eclipse.swt.SWT; 
import org.eclipse.swt.layout.GridLayout; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 


public class Main { 

public static void main (String [] args) { 
    Display display = new Display(); 
    Shell shell = new Shell(display); 
    shell.setLayout(new GridLayout(1,false)); 
    //shell.setSize(400,400); 
    CustomSlider2 slider= new CustomSlider2(shell, SWT.NONE); 


    shell.pack(); 
    shell.open(); 

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

とカスタムスライダーはCustomSlider2になる:

import org.eclipse.swt.SWT; 
import org.eclipse.swt.events.PaintEvent; 
import org.eclipse.swt.events.PaintListener; 
import org.eclipse.swt.graphics.GC; 
import org.eclipse.swt.graphics.Rectangle; 
import org.eclipse.swt.layout.GridData; 
import org.eclipse.swt.layout.GridLayout; 
import org.eclipse.swt.widgets.Canvas; 
import org.eclipse.swt.widgets.Composite; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Event; 
import org.eclipse.swt.widgets.Listener; 
import org.eclipse.swt.widgets.Widget; 

public class CustomSlider2 extends Composite { 
    private Canvas progressBar; 
    private Rectangle progressBarRect; 
    private int knobSize=15; 

    private boolean hover=false; 
    public CustomSlider2(Composite arg0, int arg1) { 
     super(arg0, arg1); 
     setBackground(arg0.getDisplay().getSystemColor(SWT.COLOR_MAGENTA)); 
     setLayout(new GridLayout(1,false)); 

     progressBar = new Canvas(this, SWT.CENTER); 
     final GridData gd=new GridData(SWT.FILL, SWT.FILL, true, true); 
     gd.widthHint = 100; 
     gd.heightHint = 50; 
     GridLayout gl= new GridLayout(); 
     gl.numColumns=1; 
     gl.marginWidth=knobSize; 
     gl.marginHeight=knobSize; 
     progressBar.setLayoutData(gd); 
     progressBar.setLayout(gl); 



     progressBar.addPaintListener(new PaintListener() { 

      @Override 
      public void paintControl(PaintEvent arg0) { 
       Canvas canvasProgress=(Canvas)arg0.widget; 
       Rectangle clientArea= canvasProgress.getBounds(); 
       progressBarRect=new Rectangle(clientArea.x, clientArea.y, clientArea.x + clientArea.width - 1, clientArea.y + clientArea.height - 1); 
       GC gc=arg0.gc; 
       gc.setForeground(canvasProgress.getDisplay().getSystemColor(SWT.COLOR_GREEN)); 
       if (hover){ 
        gc.setBackground(canvasProgress.getDisplay().getSystemColor(SWT.COLOR_RED)); 
       }else{ 
        gc.setBackground(canvasProgress.getDisplay().getSystemColor(SWT.COLOR_BLUE)); 
       } 
       gc.fillRectangle(progressBarRect); 
       gc.drawRectangle(progressBarRect); 

      } 
     }); 


     Listener listener = new Listener() { 
      public void handleEvent(Event event) { 
       System.out.println("---------------"); 
       System.out.println("Canvas:"+((Canvas)event.widget).getBounds()); 
       System.out.println("Composite:"+((Canvas)event.widget).getParent().getBounds()); 
       System.out.println("Shell:"+((Canvas)event.widget).getParent().getParent().getBounds()); 
       Display display=((Widget)event.widget).getDisplay(); 
       switch (event.type) { 
       case SWT.MouseEnter: 
        hover=true; 
        break; 
       case SWT.MouseExit: 
        hover=false;  
        break; 


       } 
       display.asyncExec(() -> progressBar.redraw()); 
      } 
     }; 

     progressBar.addListener(SWT.MouseExit, listener); 
     progressBar.addListener(SWT.MouseEnter, listener); 


    } 


} 

イベントの問題は修正されているようですが、レイアウト1ではなく...キャンバスの周りに余白が残っていません...

+0

'setSize'(または' setBounds')とレイアウトを混在させないでください。レイアウトはサイズを上書きします。 –

+0

こんにちはグレッグ、しかし、私はそれを混在させませんでした、私はコンポジット(CustomSlider)のためのセットサイズを使用し、SWTはキャンバスの境界を決定させるが、私はキャンバスのためにグリッドレイアウトを使用する...何が間違っていますか? – navy1978

+0

私はコンポジットのsetSizeをコメントアウトしても結果は変わらず、マージンは上と下のみで尊重されます...( – navy1978

答えて

1

レイアウトを使用するときは、レイアウトの幅と高さのヒントを使用してコントロールの推奨サイズ。だからここにあなたが使用する可能性があります:paintControl

final GridData gd=new GridData(SWT.FILL, SWT.FILL, true, true); 
gd.widthHint = 400; 
gd.heightHint = 50; 
progressBar.setLayoutData(gd); 

あなたはあなたのレイアウトによって追加の境界線を含む制御のフルサイズを与えるgetBoundsを使用しています。しかし、fillRectangleのような操作では、境界を除外する「クライアント領域」が常に描画されます。したがって、あなたのペイントは次のようなものでなければなりません:

@Override 
public void paintControl(PaintEvent event) { 
    Canvas canvasProgress = (Canvas)event.widget; 
    Rectangle clientArea = canvasProgress.getClientArea(); // Client area 

    .. set colors 

    gc.fillRectangle(clientArea.x, clientArea.y, clientArea.x + clientArea.width - 1, clientArea.y + clientArea.height - 1); 
    gc.drawRectangle(clientArea.x, clientArea.y, clientArea.x + clientArea.width - 1, clientArea.y + clientArea.height - 1); 
} 

マウスの動きについては、イベントの位置を確認する必要はありません。 MouseExitは、マウスがコントロールを離れるときにのみ呼び出されます。

+0

こんにちはGreg、イベントの問題は修正されているようですが、レイアウトの問題は解決していないようです...私はまだキャンバスの周囲に余白がありません。私の質問を編集しましたw code ...) – navy1978

+1

あなたはまだ 'paintControl'で' getBounds'を使っています。これは 'getClientArea'でなければなりません。 –

+0

私の間違い!あなたが正しいです! – navy1978

関連する問題