在Swing中嵌入SWT的组件

本文介绍了如何在Java Swing应用中嵌入 SWT 组件。通过使用 SWT_AWT 类,可以将 SWT 的 Shell 添加到 Swing 的 Canvas 中,再将 Canvas 放入 Panel,从而实现两者之间的整合。
AI助手已提取文章相关产品:

可以用SWT_AWT类将Shell添加到Canvas上,然后将Canvas放入Panel中,Panel则可以随意放入SWING组件中。

大概代码思路如下:

JFrame frame = new JFrame();
Container cp = frame.getContentPane();
Canvas canvas = new Canvas();
cp.add(canvas,BorderLayout.CENTER); 
frame.setVisible(true);

Display display = new Display();
Shell shell = SWT_AWT.new_Shell(display,canvas);
shell.setLayout(new FillLayout());

Button button = new Button(shell,SWT.PUSH);
button.setText("SWTのボタン");

shell.pack();

while (!shell.isDisposed()) {
  if (!display.readAndDispatch()){
    display.sleep ();
  }
}
关键代码:
Shell shell = SWT_AWT.new_Shell(display,canvas);
但是该代码有一定缺陷,代码后面的while循环是必须部分,因为该循环让display能不断响应shell的事件,但是又因为sleep会使线程进入睡眠状态,所以如果该界面上添加了Swing组件,将无法相应事件,所以解决办法就是让SWT的组件和SWING组件分别位于不同子线程,改进后如下:

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Panel;
import javax.swing.JFrame;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class SWTPanel extends Panel {
	//用来搭载shell的canvas
	private Canvas canvas = null;
	//控制SWT组件的子线程
	private DisplayThread displayThread = null;
	
	public SWTPanel()
	{
		displayThread = new DisplayThread();
		displayThread.start();
		canvas = new Canvas();
		setLayout(new BorderLayout());
		add(canvas, BorderLayout.CENTER);
	}
	
	//改变panel呈现的样式
	public void addNotify() 
	{
		super.addNotify();
		Display dis=displayThread.getDisplay();
		//syncExec的函数作用是让dis所在线程视自己情况,找机会执行后面代码
		dis.syncExec( new Runnable() {
			//此处添加SWT界面的代码
			public void run() {
		    Shell shell = SWT_AWT.new_Shell(displayThread.getDisplay(), canvas );
		    shell.setSize(800, 800);
		    
		    final Text text=new Text(shell,SWT.BORDER); 
	        text.setBounds(110,5,560,25); 
	        Button button=new Button(shell,SWT.BORDER); 
	        button.setBounds(680,5,100,25);        
	        button.setText("go"); 
	        Label label=new Label(shell,SWT.LEFT); 
	        label.setText("输入网址 :"); 
	        label.setBounds(5, 5, 100, 25); 
	        
	        final Browser browser=new Browser(shell,SWT.FILL); 
	        browser.setUrl("www.baidu.com");
	        text.setText("www.baidu.com");
	        browser.setBounds(5,30,800,760); 
	        
	        button.addListener(SWT.Selection, new Listener() 
	        { 
	            public void handleEvent(Event event) 
	            { 
	                String input=text.getText().trim(); 
	                if(input.length()==0)return; 
	                if(!input.startsWith("http://")) 
	                { 
	                    input="http://"+input; 
	                    text.setText(input); 
	                } 
	                browser.setUrl(input); 
	            } 
	        }); 
		   }
		  } );
	}
	
	class DisplayThread extends Thread{
		private Display display;
		Object lock = new Object();
		
		public void run(){
			//添加同步,DisplayThread和SWTPanel所在不同线程,访问同一个display对象,
			//SWTPanel需要等DisplayThread创建display对象后才能引用,所以此处要添加同步
			synchronized (lock) {
				display = Display.getDefault();
				lock.notifyAll();
			}
			swtEventLoop();
		}
		
		private void swtEventLoop(){
			while(true)
			{
				if(!display.readAndDispatch())
				{
					display.sleep();
				}
			}
		}
		
		public Display getDisplay() {
			synchronized (lock) {
				while (display == null) 
				{
					try {
						lock.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				return display;
			}
		}
	}
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		frame.setLayout(new BorderLayout());
		frame.setSize(800, 800);
		
		SWTPanel swtPanel = new SWTPanel();
		frame.add(swtPanel,BorderLayout.CENTER);
	}
}




您可能感兴趣的与本文相关内容

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值