官术网_书友最值得收藏!

Time for action – drawing a custom view

An SWT Canvas can be used to provide custom rendering for a view. As a starting point for drawing a clock, the Canvas will use drawArc to create a circle.

  1. Remove the content of the ClockView, leaving behind an empty implementation of the setFocus and createPartControl methods.
  2. Run the target Eclipse instance and you will see that the ClockView is now empty.
  3. Create a new method called drawClock that takes a PaintEvent, and use the graphics context gc from the event to draw the circle.
  4. In the createPartControl method, do the following:
    1. Create a new Canvas, which is a drawable widget.
    2. Add a PaintListener to the Canvas that uses a method reference to the drawClock method.
  5. The code will look like this:
    package com.packtpub.e4.clock.ui.views;
    import org.eclipse.swt.*;
    import org.eclipse.swt.events.*;
    import org.eclipse.swt.widgets.*;
    import org.eclipse.ui.part.ViewPart;
    public class ClockView extends ViewPart {
      public void createPartControl(Composite parent) {
        final Canvas clock = new Canvas(parent, SWT.NONE);
        clock.addPaintListener(this::drawClock);
      }
      private void drawClock(PaintEvent e) {
        e.gc.drawArc(e.x, e.y, e.width-1, e.height-1, 0, 360);
      }
      public void setFocus() {
      }
    }
  6. Run the target Eclipse instance, and show the ClockView.
  7. Resize the view, and the clock should change size with it:

What just happened?

In SWT, the widget used for custom drawing is Canvas. The View is constructed with a call to createPartControl, which is invoked once when the view is shown for the first time. If the view is minimized and then maximized, it will not be invoked again; however, if the view is closed and a new view is opened, then a call will be made to a new instance of the ClockView to initialize it.

Unlike other Java GUI frameworks, a widget is not added to or removed from a containing parent after creation; instead, the widget's parent is specified at construction time. The constructor also takes a style flag. This is used by widgets in different ways; for example, the Button widget takes various flags to indicate whether it should be rendered as a push button, radio button, checkbox, toggle, or arrow. For consistency, in SWT all widgets have an int style flag, which enables up to 32 bits of different options to be configured.

Note

These are defined as constants in the SWT class; for example, the checkbox button style is represented as SWT.CHECKBOX. Options can be combined. To specify a flat button, the SWT.PUSH and SWT.FLAT options can be combined together with new Button (parent, SWT.PUSH | SWT.FLAT). Generally, the value SWT.NONE is used to represent default options.

The code adds an empty Canvas to the view, but how can graphics be drawn? SWT does not expose a paint method on any of its widgets. Instead, a PaintListener is called whenever the canvas needs to be repainted.

Note

All in the name of performance

You may wonder why all these little things are different between the way SWT handles its widgets compared to how AWT or Swing handles them. The answer is in the name of speed and delegation to native rendering and controls if at all possible. This mattered back in the early days of Java (Eclipse 1.0 was released when Java 1.3 was the most advanced runtime available), when neither the JITs nor CPUs were as powerful as today.

Secondly, the goal of SWT was to offload as much of the processing onto native components (such as AWT) as possible and let the OS do the heavy work instead of Java. By doing that, the time spent in the JVM could be minimized, while allowing the OS to render the graphics in the most appropriate (and performant) way. The PaintListener is one such example of avoiding performing unnecessary drawing-related calls unless a component actually needs it.

The drawClock method is called with a PaintEvent argument, which contains references to all of the data needed to draw the component. To minimize method calls, the fields are publicly readable. It also contains a reference to the graphics context (gc) which can be used to invoke drawing commands.

Finally, the event also records the region in which the paint event is to be fired. The x and y fields show the position of the top left to start from, and the width and height fields of the event show the drawing bounds.

In this case, the graphics context is set up with the necessary foreground color, and drawArc is called between the bounds specified. Note that the arc is specified in degrees (from 0 with a 360 span) rather than radians.

主站蜘蛛池模板: 延边| 天津市| 陇川县| 三穗县| 潜山县| 扶风县| 富锦市| 陇川县| 吐鲁番市| 盐城市| 博爱县| 顺昌县| 卢氏县| 泸州市| 建湖县| 锡林浩特市| 通城县| 绍兴县| 呼和浩特市| 绍兴县| 根河市| 昔阳县| 西乌| 镇远县| 清新县| 铜陵市| 四平市| 从江县| 桦南县| 海宁市| 景洪市| 沂源县| 临夏市| 泰来县| 佛冈县| 札达县| 临泉县| 高州市| 岳普湖县| 石狮市| 湖北省|