跳到主要內容

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.

留言

張貼留言

熱門文章

差不多食譜:手工巧克力餅乾 Chocolate Cookies

又是手工餅乾,最近一連出了兩份餅乾食譜,這個「手工巧克力餅乾」已經是第三份了。會不會有更多呢?我可以告訴大家,這是肯定的。 要怪就怪這個陰鬱的冬季雨天,哪裡都不方便去,也懶得出去。餅乾櫃空在那邊已經很久了,雖然有時候會嘴饞,但也沒有迫切去補貨的必要。反正經常開伙,平常該有的材料都會有,自己弄個成分完全透明的零食,也是個不錯的選擇。再說,用烤箱進行烘焙時,房間會變得比較乾燥,也比較溫暖。在夏天是個折磨,但到了冬天,這種感覺還滿不錯的。 話不多說,開始進行這一道「手工巧克力餅乾」的準備工作。

差不多食譜:壽桃 Birthday Bunns

「壽桃」可不是老人家生日的專利,小巧玲瓏的壽桃超級受到小朋友歡迎,直說「好可愛喔!」其實壽桃就是一種造型饅頭/包子,只要掌握了這些方法,要做其他的造型都沒問題。

差不多食譜:檸檬餅乾 Lemon Biscuits

寒流來襲,氣象局持續發布低溫特報。在這冷颼颼的冬日,差不多食譜為您準備了一支有溫度的影片食譜「檸檬餅乾 Lemon Biscuits」。檸檬的酸味能夠讓您有清新的味覺,用檸檬做的餅乾則讓您解除冬日過份進補的油膩感,同時又滿足一直想吃東西的衝動。但我可沒說這種吃法的卡路里不高,對您的身材不會有影響。恐怕您還是得自己稍微節制些! 不過,說老實話,我單純是因為天氣太冷,所以把烤箱拿來當暖爐用。坐在烤箱後面等待餅乾完成,果真有暖呼呼的感覺。