跳到主要內容

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.

留言

張貼留言

熱門文章

差不多食譜:壽桃 Birthday Bunns

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

差不多食譜:巧克力杏仁餅乾 Chocolate Almond Cookies

老闆!來杯咖啡!這杯咖啡怎麼硬硬的?裡頭還一片片白白的東西?別擔心,差不多食譜不會向您介紹壞掉的東西,這也不是咖啡,不過是裝在咖啡杯裡頭的巧克力杏仁餅乾。這麼說來,這已經是第三份和巧克力有關的餅乾食譜了。從最早黑黑的「 手工巧克力餅乾 」,後來加了咖啡液黑白相間的「 咖啡巧克力餅乾 」,現在則是把黑白比例倒過來的「巧克力杏仁餅乾」。喜歡巧克力和手工餅乾的朋友們,千萬別錯過囉!

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

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