跳到主要內容

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.

留言

張貼留言

熱門文章

差不多食譜:萬聖節的蛋白霜幽靈們 Halloween Meringue Ghosts

說到十月,月底的萬聖節肯定是驚嚇指數最高的一天,到處飄忽的幽靈們更是西洋鬼節的主角。不甘心這天總是被 Trick-or-Treat(不給糖就搗蛋)威脅,差不多食譜今年要開始來反擊,邀請大家來當 Ghostbusters 魔鬼剋星,將這群調皮搗蛋的幽靈們一網打盡。 抓鬼的先決條件就是⋯⋯得有些幽靈鬼怪來抓。這可是練習擠花的好時機,因為幽靈本來就是奇形怪狀的,什麼樣的怪樣子都不奇怪,太精緻反而有點奇怪呢!做好直送嘴巴「喀嚓」,看它還敢不敢來 Trick-or-Treat!

差不多食譜:蜂蜜烤南瓜 Roasted Pumpkin with Honey

還記得差不多食譜分享過用煎的南瓜吧!那是屬於家常菜的做法,現在差不多食譜推出另外一種做法,淋上蜂蜜,用烤箱加上精緻的裝飾,讓家常菜變身成為派對食物。相信當你端出這盤「蜂蜜烤南瓜」時,肯定會吸引不少眼球的注意。

金門。毋忘在莒勒石 “Wu Wang Zai Jyu” Inscription

金門有塊石頭,不去看看感覺怪怪的,看了又覺得實在沒什麼。聰明的你應該猜到了,就是那塊出現在教科書裡頭的「毋忘在莒」,金門的象徵。印象中,刻著「毋忘在莒」的那塊大石頭旁邊光禿禿的。或許從小學畢業二十多年後,我頭一次有機會來拜見這塊石頭,旁的小樹苗已經長成這副模樣了吧!再過幾年,恐怕要在林蔭中尋找「毋忘在莒」這四個字。但真要問起「毋忘在莒」這四個字是什麼意思,我相信不少人需要稍微想一下。