跳到主要內容

Concise's Anatomy: SWT native Toolbar (for Mac)

Concise 0.1 beta

One of the most significant change of Concise 0.1 beta is the Graphic User Interface.  It is now really "graphic."  Thanks to Joseph Wain's marvelous icons (http://glyphish.com/).  Besides, what makes the Mac-like toolbar possible is the new feature of SWT (the standard widget toolkit) 3.7.  Let's see how this works.


Shell.getToolBar() returns a ToolBar that appears in the title area of the Shell.  ToolItems added to that ToolBar will have the look and feel of the platform.

Well, I must say this isn't native enough.  The ToolBar returned from Shell.getToolBar() does feel like Leopard (Mac OS X 10.5) or Snow Leopard (Mac OS X 10.6).  As for Lion (Mac OS X 10.7), there is still room to improve.  Nonetheless, Shell.getToolBar() is enough to develop Mac-like user interface under careful design.  The result is shown in Concise 0.1 beta's user interface.

We may follow bug 222859 to see how to use SWT native ToolBar in your Mac (or cross-platform) application.  A test case provided by Felipe Heidrich is a good starting point.  Felipe Heidrich created two different type ToolBars which he called TRIM_FILL (regular toolBar) vs. getToolBar() (native app toolbar).



package tests;

import org.eclipse.swt.SWT;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class UnifiedToolbar {

public static void main(String[] args) {
 Display display = new Display();
 main1(display);
 main3(display);
 Shell shell = display.getShells()[0];
 while (!shell.isDisposed()) {
  if (!display.readAndDispatch())
   display.sleep();
 }
 display.dispose();
}
public static void main3(Display display) {
 Shell shell = new Shell(display, SWT.SHELL_TRIM );
 GridLayout layout = new GridLayout(1, false);
 layout.marginHeight = layout.marginWidth = 0;
 shell.setLayout(layout);

 ToolBar toolBar = shell.getToolBar();
 ToolItem item = new ToolItem (toolBar, SWT.PUSH);
 Image image = new Image(display, 30, 30);
 item.setImage(image);
 item = new ToolItem (toolBar, SWT.PUSH);
 item.setText("native app toolbar");
 
 Button b = new Button(shell, SWT.PUSH);
 b.setText("client");
 shell.setSize(300, 400);
 shell.open();
}


public static void main1(Display display) {
 Shell shell = new Shell(display, SWT.SHELL_TRIM);
 GridLayout layout = new GridLayout(1, false);
 layout.marginHeight = layout.marginWidth = 0;
 shell.setLayout(layout);
 
 ToolBar toolBar = new ToolBar(shell, SWT.FLAT);
 ToolItem item = new ToolItem (toolBar, SWT.PUSH);
 Image image = new Image(display, 30, 30);
 item.setImage(image);
 item = new ToolItem (toolBar, SWT.PUSH);
 item.setText("regular toolbar");
 toolBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
 
 Composite composite = new Composite(shell, SWT.BORDER);
 composite.setLayoutData(new GridData(GridData.FILL_BOTH));
 composite.setLayout(new GridLayout(1, false));
 Button b = new Button(composite, SWT.PUSH);
 b.setText("client");
 shell.setSize(300, 400);
 shell.open();
}

}

You may have discovered there's a blank room under the native app toolBar.  I don't know why.  But this "native" ToolBar does act like a Component which occupies a space whatever Layout (GridLayout(), FillLayout(), or ...) you're using.  Hence, I have come up with a idea by using FormLayout() and a Composite() to solve the strange situation.

The trick is to put the ToolBar into a Composite.  If your ToolBar = Shell.getToolBar(), the Composite will return 0 px in height.  Otherwise, the Composite's height is equal to ToolBar's actual height.  Here is my solution:

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;


public class NativeToolBar {

 public static void main(String[] args) {
  Display display = new Display();
  Shell shell = new Shell(display, SWT.SHELL_TRIM);
  shell.setLayout(new FormLayout());
  shell.setSize(300, 400);
  
  Composite cToolBar = new Composite(shell, SWT.EMBEDDED);
  cToolBar.setLayout(new FillLayout());
  ToolBar toolBar;
  if (System.getProperty("os.name").toLowerCase().contains("mac"))
   toolBar = shell.getToolBar();
  else
   toolBar = new ToolBar(cToolBar, SWT.FLAT);
  ToolItem item = new ToolItem(toolBar, SWT.PUSH);
  Image image = new Image(display, 30, 30);
  item.setImage(image);
  item = new ToolItem(toolBar, SWT.PUSH);
  item.setText("ToolBar");
  
  cToolBar.pack();
  FormData fd = new FormData();
  fd.left = new FormAttachment(0);
  fd.top = new FormAttachment(0);
  fd.right = new FormAttachment(0, shell.getClientArea().width);
  fd.bottom = new FormAttachment(0, cToolBar.getSize().y);
  cToolBar.setLayoutData(fd);
  
  Composite composite = new Composite(shell, SWT.BORDER);
  composite.setLayout(new GridLayout(1, false));
  fd = new FormData();
  fd.left = new FormAttachment(0);
  fd.top = new FormAttachment(cToolBar);
  fd.right = new FormAttachment(0, shell.getClientArea().width);
  fd.bottom = new FormAttachment(0, shell.getClientArea().height);
  composite.setLayoutData(fd);
  
  Button b = new Button(composite, SWT.PUSH);
  b.setText("client");
  
  
  shell.open();
  shell.layout();
  
  while (!shell.isDisposed()) {
   if (!display.readAndDispatch()) {
    display.sleep();
   }
  }
  
 } 
}

Note that this API is a work in progress, and is currently Cocoa-only, according to SWT official website.  We'd better keep a eye on the future New and Noteworthy announcements of SWT.

留言

張貼留言

熱門文章

差不多食譜:搖元宵 Yuan Xiao

元宵節就要到囉!除了放天燈、猜燈謎之外,這天還要做什麼呢?當然就是吃元宵啦~

「抓烏龜」的麻將遊戲

今天要和大家分享一個打發時間的簡單遊戲——抓烏龜。這可是我老爸老媽特別從美國學回來的,是個名符其實的「海歸」遊戲,據說是在下雪時無聊打發時間用的。

差不多食譜:蘆筍舒芙蕾 Asparagus Soufflé

舒芙蕾是由具備各式風味的底醬 (crème anglaise,有時也會看到卡仕達、奶黃醬等翻譯) ,加上由蛋白打發的蛋白霜而成的。主要的味道與變化就在那個底醬,最基本的就是蛋黃和牛奶的混合物,也就是卡仕達 (custard) 。想要甜的,就用糖、果汁、或其他甜味劑讓它做成甜的;要有顏色,可以用藍莓 (紫色) 、巧克力 (咖啡色) 、草莓 (粉紅色) 等去做變化。這次差不多食譜要做的是一款鹹的、具有乳酪風味的綠色舒芙蕾,主要的材料就是夏天盛產的蘆筍。