I need some help concerning writing widget for Lotus Notes on Java. My problem is : I created a plugin according to this tutorial : Developing a simple plug-in for Lotus Notes
But there is no information how to write any code. Also I failed to find anything using Google. To be more specific:
When I click some email in Notes Client I need to fetch this email address and show it on my widget.
When I click some link I need to open this link in a browser.
Could anyone help me and provide some example? Thanks a lot in advance! Here is my code:
package com.domiclipse.tutorial1.views;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
/**
* This sample class demonstrates how to plug-in a new
* workbench view. The view shows data obtained from the
* model. The sample creates a dummy model on the fly,
* but a real implementation would connect to the model
* available either in this or another plug-in (e.g. the workspace).
* The view is connected to the model using a content provider.
* <p>
* The view uses a label provider to define how model
* objects should be presented in the view. Each
* view can present the same model objects using
* different labels and icons, if needed. Alternatively,
* a single label provider can be shared between views
* in order to ensure that objects of the same type are
* presented in the same way everywhere.
* <p>
*/
public class SampleView extends ViewPart {
private Action action1;
private Action action2;
private Action doubleClickAction;
/*
* The content provider class is responsible for
* providing objects to the view. It can wrap
* existing objects in adapters or simply return
* objects as-is. These objects may be sensitive
* to the current input of the view, or ignore
* it and always show the same content
* (like Task List, for example).
*/
class ViewContentProvider implements IStructuredContentProvider {
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
}
public void dispose() {
}
public Object[] getElements(Object parent) {
return new String[] { "One", "Two", "Three" };
}
}
class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
public String getColumnText(Object obj, int index) {
return getText(obj);
}
public Image getColumnImage(Object obj, int index) {
return getImage(obj);
}
public Image getImage(Object obj) {
return PlatformUI.getWorkbench().
getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
}
}
class NameSorter extends ViewerSorter {
}
/**
* The constructor.
*/
public SampleView() {
}
/**
* This is a callback that will allow us
* to create the viewer and initialize it.
*/
#Override
public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
viewer.setSorter(new NameSorter());
viewer.setInput(getViewSite());
makeActions();
hookContextMenu();
hookDoubleClickAction();
contributeToActionBars();
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
SampleView.this.fillContextMenu(manager);
}
});
// Menu menu = menuMgr.createContextMenu(viewer.getControl());
//viewer.getControl().setMenu(menu);
//getSite().registerContextMenu(menuMgr, viewer);
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
}
private void fillLocalPullDown(IMenuManager manager) {
manager.add(action1);
manager.add(new Separator());
manager.add(action2);
}
private void fillContextMenu(IMenuManager manager) {
manager.add(action1);
manager.add(action2);
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void fillLocalToolBar(IToolBarManager manager) {
manager.add(action1);
manager.add(action2);
}
private void makeActions() {
action1 = new Action() {
public void run() {
showMessage("Action 1 executed");
}
};
action1.setText("Action 1");
action1.setToolTipText("Action 1 tooltip");
action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
action2 = new Action() {
public void run() {
showMessage("Action rehrhrhertrSd");
}
};
action2.setText("Action 2");
action2.setToolTipText("Action 2 tooltip");
action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
doubleClickAction = new Action() {
public void run() {
//ISelection selection = viewer.getSelection();
//Object obj = ((IStructuredSelection)selection).getFirstElement();
//showMessage("Double-click detected on "+obj.toString());
}
};
}
private void hookDoubleClickAction() {
//viewer.addDoubleClickListener(new IDoubleClickListener() {
// public void doubleClick(DoubleClickEvent event) {
// doubleClickAction.run();
// }
//});
}
private void showMessage(String message) {
//MessageDialog.openInformation(
// viewer.getControl().getShell(),
// "Sample View",
// message);
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
// viewer.getControl().setFocus();
}
}
Related
I use this class for my school app projects. It is how I set the application up and it extends JFrame and implements Runnable. Now whenever I use this in school on a Windows computer and everything works and the screen updates, but at home on a Mac it doesn't. I use Eclipse neon with JDK 1.8.0_101
Please help me out, I can't test any projects at home cause of this.
import java.awt.Graphics;
import javax.swing.JFrame;
public abstract class GUIApplication extends JFrame implements Runnable{
private Screen currentScreen;
//no main, cant instentiate an abstract class
public GUIApplication(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
int x=40;
int y=40;
int width=1000;
int height=640;
setBounds(x,y,width,height);
initScreen();
setVisible(true);
}
//this is a method for creating the starting screen
protected abstract void initScreen();
public void setScreen(Screen screen){
//stop controls from previous screen
removeListeners();
setCurrentScreen(screen);
//add new controls
addListeners();
}
private void removeListeners(){
if(getCurrentScreen() != null){
if(getCurrentScreen().getMouseListener() != null) removeMouseListener(getCurrentScreen().getMouseListener());
if(getCurrentScreen().getMouseMotionListener() != null) removeMouseMotionListener(getCurrentScreen().getMouseMotionListener());
if(getCurrentScreen().getKeyListener() != null) removeKeyListener(getCurrentScreen().getKeyListener());
// if(currentScreen.getMouseWheelListener() != null) removeMouseWheelListener(currentScreen.getMouseWheelListener());
}
}
private void addListeners(){
if(getCurrentScreen() != null){
if(getCurrentScreen().getMouseListener() != null)addMouseListener(getCurrentScreen().getMouseListener());
if(getCurrentScreen().getMouseMotionListener() != null) addMouseMotionListener(getCurrentScreen().getMouseMotionListener());
if(getCurrentScreen().getKeyListener() != null){
addKeyListener(getCurrentScreen().getKeyListener());
}
// if(currentScreen.getMouseWheelListener() != null) addMouseWheelListener(currentScreen.getMouseWheelListener());
}
}
public void paint(Graphics g){
g.drawImage(getCurrentScreen().getImage(), 0, 0, null);
}
public void run(){
while(true){
getCurrentScreen().update();
repaint();
try {
Thread.sleep(30);
repaint();
revalidate();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public Screen getCurrentScreen() {
return currentScreen;
}
public void setCurrentScreen(Screen currentScreen) {
this.currentScreen = currentScreen;
}
}
This is how a game would start:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;
import javax.swing.JFrame;
import game.mainScreenTeam.Dragon;
import game.mainScreenTeam.HomeScreen;
import game.miniGameTeam.GameInstructions;
import game.miniGameTeam.GameScreen;
import game.miniGameTeam.HighScoreScreen;
import game.shopScreen.BuyScreenWendy;
import game.shopScreen.HomeShopScreen;
import game.shopScreen.SellShopZheng;
import guiPractice.GUIApplication;
import guiPractice.Screen;
import guiPractice.components.AnimatedComponent;
/**
* #author Kat
*
*/
public class DragonLand extends GUIApplication {
public static DragonLand game;
public static int coins = 1500;
public static HomeScreen homeScreen;
public static Screen shopMain; // shop 1
public static Screen sellScreen; // shop 2
public static Screen buyScreen; // shop 3
public static Screen highscoreScreen; // high score
public static GameScreen miniGameScreen; // minigame
public static Screen gameInstructionsScreen;
public static Screen HelpScreen;
public static Color NAVY;
public static Color BRIGHT_PINK;
public static Color LIGHT_PINK;
public static Color LIGHT_NUDE;
public static Color DARKER_NUDE;
/**
*
*/
// public static void addDragon(AnimatedComponent a){
// dragonList.add(a);
// }
public DragonLand() {
}
/* (non-Javadoc)
* #see guiPractice.GUIApplication#initScreen()
*/
#Override
protected void initScreen() {
initColors();
miniGameScreen = new GameScreen(getWidth(),getHeight());
shopMain = new HomeShopScreen(getWidth(),getHeight());
sellScreen = new SellShopZheng(getWidth(),getHeight());
homeScreen = new HomeScreen(getWidth(),getHeight());
buyScreen = new BuyScreenWendy(getWidth(),getHeight());
highscoreScreen = new HighScoreScreen(getWidth(),getHeight());
HomeScreen.jenCode = new game.mainScreenTeam.HomeJenniber();
gameInstructionsScreen = new GameInstructions(getWidth(), getHeight());
setScreen(homeScreen);
}
private void initColors() {
NAVY = new Color(62,74,99);
BRIGHT_PINK = new Color(224,102,102);
LIGHT_PINK = new Color(248,186,182);
LIGHT_NUDE = new Color(244,215,183);
DARKER_NUDE = new Color(230,195,147);
}
/**
* #param args
*/
public static void main(String[] args) {
game = new DragonLand();
Thread go = new Thread(game);
go.start();
}
//public coin getter + setter
public void setCoins(int x){
coins = x;
}
public int getCoins(){
return coins;
}
}
This is the home screen
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import game.DragonLand;
import guiPractice.ClickableScreen;
import guiPractice.components.Action;
import guiPractice.components.AnimatedComponent;
import guiPractice.components.Button;
import guiPractice.components.Graphic;
import guiPractice.components.TextLabel;
import guiPractice.components.Visible;
import guiPractice.sampleGames.MouseFollower;
/**
* #author Kat
* #author Jenniber
*
*/
public class HomeScreen extends ClickableScreen implements Runnable{
private Graphic background;
public static HomeJenniber jenCode;
public HomeScreen(int width, int height) {
super(width, height);
Thread play = new Thread(this);
play.start();
}
#Override
public void initAllObjects(ArrayList<Visible> viewObjects) {
background=new Graphic(0,0,getWidth(),getHeight(),"img/Grassland.png");
viewObjects.add(background);
HomeKat katCode=new HomeKat(viewObjects, getWidth(), getHeight());
}
#Override
public void run() {
}
}
katCode adds buttons to the screen and image annimations
public void paint(Graphics g){
g.drawImage(getCurrentScreen().getImage(), 0, 0, null);
}
Don't override paint() on a JFrame.
The proper way to do custom painting is to override paintComponent(...) on a JPanel (or JComponent) and then you can set the content pane of the frame to this panel. And don't forget to invoke super.paintComponent(...) as the first statement in the method. Read the section from the Swing tutorial on Custom Painting for more information and working examples.
However if you do get lazy, then at minimum you need to invoke super.paint(...) as the first statement in the paint(...) method.
Also, I doubt you need the revalidate(), since you don't appear to be adding/removing components from the frame.
But in general the order should be:
revalidate(); // to invoke the layout manager
repaint(); // paint components in new location.
I also don't know why you are invoking the update() method. That seems like old AWT code which you don't use in Swing. I suggest you take a look at the tutorial link I gave you and look at the table of contents for other Swing basics.
NOTE
Exceptions in previous versions were caused by the fact that plug-in id was ending with a number. This is probably not possible in Eclipse RCP.
UPDATED VERSION
I am trying to display a View by defining perspective extension in plugin.xml.
Here is may plugin.xml:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
id="application"
point="org.eclipse.core.runtime.applications">
<application>
<run
class="try_03_eclipseplugin.Application">
</run>
</application>
</extension>
<extension
point="org.eclipse.ui.perspectiveExtensions">
<perspectiveExtension
targetID="*">
<view
id="try_03_eclipseplugin.SampleView"
minimized="false"
ratio="0.20"
relationship="left"
relative="org.eclipse.ui.editorss">
</view>
</perspectiveExtension>
</extension>
<extension
point="org.eclipse.ui.views">
<view
allowMultiple="false"
class="try_03_eclipseplugin.SampleView"
icon="icons/sample.gif"
id="try_03_eclipseplugin.SampleView"
name="Sample View">
</view>
</extension>
<extension
point="org.eclipse.ui.handlers">
<handler
class="try_03_eclipseplugin.Handler"
commandId="Try_03_EclipsePlugin.command1">
</handler>
</extension>
<extension
point="org.eclipse.ui.menus">
<menuContribution
allPopups="false"
locationURI="menu:org.eclipse.ui.main.menu">
<command
commandId="Try_03_EclipsePlugin.command1"
label="Try"
style="push">
</command>
</menuContribution>
</extension>
</plugin>
And here is entire code for Application class (all advisors are made as inner classes):
package try_03_eclipseplugin;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.application.IWorkbenchWindowConfigurer;
import org.eclipse.ui.application.WorkbenchAdvisor;
import org.eclipse.ui.application.WorkbenchWindowAdvisor;
/**
* This class controls all aspects of the application's execution
*/
public class Application implements IApplication {
/*
* (non-Javadoc)
*
* #see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.
* IApplicationContext)
*/
public Object start(IApplicationContext context) throws Exception {
Display display = PlatformUI.createDisplay();
try {
int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
/*
int returnCode = PlatformUI.createAndRunWorkbench(display, new WorkbenchAdvisor() {
#Override
public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
return new WorkbenchWindowAdvisor(configurer) {
public void preWindowOpen() {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
configurer.setInitialSize(new Point(400, 300));
configurer.setShowCoolBar(false);
configurer.setShowStatusLine(false);
configurer.setTitle("Hello RCP"); //$NON-NLS-1$
}
};
}
#Override
public String getInitialWindowPerspectiveId() {
return null;
}
});
*/
if (returnCode == PlatformUI.RETURN_RESTART)
return IApplication.EXIT_RESTART;
else
return IApplication.EXIT_OK;
} finally {
display.dispose();
}
}
/*
* (non-Javadoc)
*
* #see org.eclipse.equinox.app.IApplication#stop()
*/
public void stop() {
if (!PlatformUI.isWorkbenchRunning())
return;
final IWorkbench workbench = PlatformUI.getWorkbench();
final Display display = workbench.getDisplay();
display.syncExec(new Runnable() {
public void run() {
if (!display.isDisposed())
workbench.close();
}
});
}
}
The code of SampleView is following:
package try_03_eclipseplugin;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.jface.action.*;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.*;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.SWT;
/**
* This sample class demonstrates how to plug-in a new
* workbench view. The view shows data obtained from the
* model. The sample creates a dummy model on the fly,
* but a real implementation would connect to the model
* available either in this or another plug-in (e.g. the workspace).
* The view is connected to the model using a content provider.
* <p>
* The view uses a label provider to define how model
* objects should be presented in the view. Each
* view can present the same model objects using
* different labels and icons, if needed. Alternatively,
* a single label provider can be shared between views
* in order to ensure that objects of the same type are
* presented in the same way everywhere.
* <p>
*/
public class SampleView extends ViewPart {
/**
* The ID of the view as specified by the extension.
*/
public static final String ID = "try_03_eclipseplugin.SampleView";
private TableViewer viewer;
private Action action1;
private Action action2;
private Action doubleClickAction;
/*
* The content provider class is responsible for
* providing objects to the view. It can wrap
* existing objects in adapters or simply return
* objects as-is. These objects may be sensitive
* to the current input of the view, or ignore
* it and always show the same content
* (like Task List, for example).
*/
class ViewContentProvider implements IStructuredContentProvider {
public void inputChanged(Viewer v, Object oldInput, Object newInput) {
}
public void dispose() {
}
public Object[] getElements(Object parent) {
return new String[] { "One", "Two", "Three" };
}
}
class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
public String getColumnText(Object obj, int index) {
return getText(obj);
}
public Image getColumnImage(Object obj, int index) {
return getImage(obj);
}
public Image getImage(Object obj) {
return PlatformUI.getWorkbench().
getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
}
}
class NameSorter extends ViewerSorter {
}
/**
* The constructor.
*/
public SampleView() {
}
/**
* This is a callback that will allow us
* to create the viewer and initialize it.
*/
public void createPartControl(Composite parent) {
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
viewer.setContentProvider(new ViewContentProvider());
viewer.setLabelProvider(new ViewLabelProvider());
viewer.setSorter(new NameSorter());
viewer.setInput(getViewSite());
// Create the help context id for the viewer's control
PlatformUI.getWorkbench().getHelpSystem().setHelp(viewer.getControl(), "Try_EclipsePlugin_03.viewer");
makeActions();
hookContextMenu();
hookDoubleClickAction();
contributeToActionBars();
}
private void hookContextMenu() {
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
SampleView.this.fillContextMenu(manager);
}
});
Menu menu = menuMgr.createContextMenu(viewer.getControl());
viewer.getControl().setMenu(menu);
getSite().registerContextMenu(menuMgr, viewer);
}
private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalPullDown(bars.getMenuManager());
fillLocalToolBar(bars.getToolBarManager());
}
private void fillLocalPullDown(IMenuManager manager) {
manager.add(action1);
manager.add(new Separator());
manager.add(action2);
}
private void fillContextMenu(IMenuManager manager) {
manager.add(action1);
manager.add(action2);
// Other plug-ins can contribute there actions here
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
}
private void fillLocalToolBar(IToolBarManager manager) {
manager.add(action1);
manager.add(action2);
}
private void makeActions() {
action1 = new Action() {
public void run() {
showMessage("Action 1 executed");
}
};
action1.setText("Action 1");
action1.setToolTipText("Action 1 tooltip");
action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
action2 = new Action() {
public void run() {
showMessage("Action 2 executed");
}
};
action2.setText("Action 2");
action2.setToolTipText("Action 2 tooltip");
action2.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
doubleClickAction = new Action() {
public void run() {
ISelection selection = viewer.getSelection();
Object obj = ((IStructuredSelection)selection).getFirstElement();
showMessage("Double-click detected on "+obj.toString());
}
};
}
private void hookDoubleClickAction() {
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
doubleClickAction.run();
}
});
}
private void showMessage(String message) {
MessageDialog.openInformation(
viewer.getControl().getShell(),
"Sample View",
message);
}
/**
* Passing the focus request to the viewer's control.
*/
public void setFocus() {
viewer.getControl().setFocus();
}
}
I expect view will appear immediately after program run. But it does not happen.
Simultaneously, I have a code to show new instance of a view with menu command -- and it works and shows view and even icon is shown.
This was because of the absence of perspective id.
When defined perspective factory
package try_03_eclipseplugin;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;
public class PerspectiveFactory implements IPerspectiveFactory {
public static final String ID = "Try_03_EclipsePlugin.perspective";
#Override
public void createInitialLayout(IPageLayout layout) {
}
}
and described it in plugin.xml and then returned it's id in advisor:
#Override
public String getInitialWindowPerspectiveId() {
return PerspectiveFactory.ID;
//return "org.eclipse.ui.resourcePerspective";
}
it started to show initial view.
Still don't understand why it does not work with the ID of resource perspective (commented).
I have one org.eclipse.ui.dialogs.CheckedTreeSelectionDialog like below code.
final CheckedTreeSelectionDialog checkedTreeSelectionDialog = new
CheckedTreeSelectionDialog(new Shell(),new ActionLabelProvider(), new
ActionContentProvider());
ActionLabelProvider implements org.eclipse.jface.viewers.ILabelProvider and ActionContentProvider implements org.eclipse.jface.viewers.ITreeContentProvider
I have some elements initially selected and some are not in the CheckedTreeSelectionDialog.
When dialog is open, if I check the unchecked element, I want to show one message.
How can I do this?
Create a subclass of CheckedTreeSelectionDialog and add addCheckStateListener, use the below code.
// When user checks a checkbox in the tree
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.CheckedTreeSelectionDialog;
public class MyCheckedTreeSelectionDialog extends CheckedTreeSelectionDialog {
public MyCheckedTreeSelectionDialog(Shell parent, ILabelProvider labelProvider, ITreeContentProvider contentProvider) {
super(parent, labelProvider, contentProvider);
}
#Override
protected CheckboxTreeViewer getTreeViewer() {
CheckboxTreeViewer treeViewer = super.getTreeViewer();
treeViewer.addCheckStateListener(new ICheckStateListener() {
public void checkStateChanged(CheckStateChangedEvent event) {
if (event.getChecked()) {
// Given element is checked
} else {
// Given element is un-checked
// Your message here
}
}
});
return treeViewer;
}
}
I am using a custom TreeModel for my JTree. I have a root node and only 1 child node that is retrieved by a query from the database. I am able to populate the tree with the desired output.
However, when I click on the child node, it keeps recursively dispalying the same child node and it keeps adding child nodes with the same output. I tried to use static nodes i.e. I created a root node and then added 2 child nodes to it and I observe the same behavior.
My main program
import javax.swing.JFrame;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
public class RunApp {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ShowFrame f = new ShowFrame();
f.setSize(600, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
});
}
}
My show_frame class
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
public class ShowFrame extends JFrame {
private JSplitPane splitPane;
private FormPanel formPanel;
private TreePanel treePanel;
private JTabbedPane tabPane;
private List<Objects> instanceDetails= new ArrayList<Objects>();
public ShowFrame() {
super("new frame");
formPanel = new FormPanel();
instanceDetails.add(new Objects(" "," "," "," "));
treePanel = new TreePanel(instanceDetails);
tabPane = new JTabbedPane();
tabPane.add(treePanel);
splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, formPanel,
tabPane);
splitPane.setOneTouchExpandable(true);
setMinimumSize(new Dimension(500, 500));
add(splitPane, BorderLayout.CENTER);
}
}
This is where I create my TreePanel
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
public class TreePanel extends JPanel {
private int count = 0;
private JTree tree;
private List<Objects> instanceDetails;
private MyTreeModel gm;
private DefaultMutableTreeNode root = new DefaultMutableTreeNode();
private Controller c = new Controller();
public TreePanel(List<Objects> instanceDetails) {
this.instanceDetails = instanceDetails;
tree = new JTree();
if (instanceDetails.get(0).getObjectId() == " ") {
tree.setModel(new MyTreeModel(root));
} else {
tree.setModel(new MyTreeModel(treeNodes(instanceDetails)));
}
gm = new MyTreeModel(root);
gm.fireTreeStructureChanged(root);
tree.getSelectionModel().setSelectionMode(
TreeSelectionModel.SINGLE_TREE_SELECTION);
add(tree);
}
private DefaultMutableTreeNode treeNodes(List<Objects> instanceDetails) {
for (Objects id : instanceDetails) {
count++;
DefaultMutableTreeNode objs = new DefaultMutableTreeNode(count + " : " + id.getType()
+ " : " + id.getObjectId() + " : " + id.getStatus() + " : "
+ id.getCondition());
root.add(objs);
}
return root;
}
}
My tree model
import java.util.Vector;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class MyTreeModel implements TreeModel {
public static Vector<TreeModelListener> treeModelListeners =
new Vector<TreeModelListener>();
private static DefaultMutableTreeNode rootPerson;
public MyTreeModel(DefaultMutableTreeNode nodes) {
rootPerson = nodes;
}
//////////////// Fire events //////////////////////////////////////////////
/**
* The only event raised by this model is TreeStructureChanged with the
* root as path, i.e. the whole tree has changed.
*/
protected void fireTreeStructureChanged(DefaultMutableTreeNode rootPerson) {
TreeModelEvent e = new TreeModelEvent(this, new Object[] {rootPerson});
for (TreeModelListener tml : treeModelListeners) {
tml.treeStructureChanged(e);
}
}
//////////////// TreeModel interface implementation ///////////////////////
/**
* Adds a listener for the TreeModelEvent posted after the tree changes.
*/
public void addTreeModelListener(TreeModelListener l) {
treeModelListeners.addElement(l);
}
/**
* Returns the child of parent at index index in the parent's child array.
*/
public Object getChild(Object parent, int index) {
return rootPerson.getChildAt(index);
}
/**
* Returns the number of children of parent.
*/
public int getChildCount(Object parent) {
return 1;
//rootPerson.getLeafCount()
}
/**
* Returns the index of child in parent.
*/
public int getIndexOfChild(Object parent, Object child) {
return rootPerson.getIndex((DefaultMutableTreeNode) child);
}
/**
* Returns the root of the tree.
*/
public Object getRoot() {
return rootPerson;
}
/**
* Returns true if node is a leaf.
*/
public boolean isLeaf(Object node) {
return rootPerson.isLeaf();
}
/**
* Removes a listener previously added with addTreeModelListener().
*/
public void removeTreeModelListener(TreeModelListener l) {
//removeTreeModelListener(l);
}
/**
* Messaged when the user has altered the value for the item
* identified by path to newValue. Not used by this model.
*/
public void valueForPathChanged(TreePath path, Object newValue) {
}
}
Your implementation of TreeModel is clumsy and is the cause of your issues:
public static Vector<TreeModelListener> treeModelListeners =
new Vector<TreeModelListener>();
private static DefaultMutableTreeNode rootPerson;
--> Bad, Bad, Bad, ... real bad. There is absolutely no need to make these statements static and this will cause severe issues if you happen to create 2 different instances
/**
* Returns the child of parent at index index in the parent's child array.
*/
public Object getChild(Object parent, int index) {
return rootPerson.getChildAt(index);
}
Here, no matter which parent is provided, you return always the same child (hence this is why you see the same child over and over). The code should be return (parent==rootPerson?rootPerson.getChildAt(index):null);
/**
* Returns the number of children of parent.
*/
public int getChildCount(Object parent) {
return 1;
//rootPerson.getLeafCount()
}
Same as previous comment, you don't look what is the parent. Code should be return (parent==rootPerson?1:0);
/**
* Returns the index of child in parent.
*/
public int getIndexOfChild(Object parent, Object child) {
return rootPerson.getIndex((DefaultMutableTreeNode) child);
}
Same as previous comment, you don't look what is the parent. Code should be return (parent==rootPerson?rootPerson.getIndex((DefaultMutableTreeNode) child):-1);
/**
* Returns true if node is a leaf.
*/
public boolean isLeaf(Object node) {
return rootPerson.isLeaf();
}
Again, same mistake, you don't care about node
/**
* Removes a listener previously added with addTreeModelListener().
*/
public void removeTreeModelListener(TreeModelListener l) {
//removeTreeModelListener(l);
}
Why don't you implement properly removeTreeModelListener? (and as suggested by #trashgod, you can always use the default EventListenerList which does most of the work for you)
Conclusion: your implementation of TreeModel is full of bugs and this is why you get the problem you describe. Now, since you are using DefaultMutableTreeNode, I can only encourage you to also use DefaultTreeModel which will handle everything for you and avoid you to have to re-implement this, with all the "risks" it implies.
I use JFace TableViewer and databinding to display data of a database table, some columns have very long text, I found the text is cut out. if I activate the text editor associated with that cell, I can see the full text.
Does swt table has limitation on text length in a cell ? or the OS has such limitation ?(I am using eclipse 3.6 and windows 7 32 bit)
/*******************************************************************************
* Copyright (c) 2006 Tom Schindl and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tom Schindl - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.snippets.viewers;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* A simple TableViewer to demonstrate usage
*
* #author Tom Schindl <tom.schindl#bestsolution.at>
*
*/
public class Snippet001TableViewer {
private class MyContentProvider implements IStructuredContentProvider {
/* (non-Javadoc)
* #see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
*/
public Object[] getElements(Object inputElement) {
return (MyModel[])inputElement;
}
/* (non-Javadoc)
* #see org.eclipse.jface.viewers.IContentProvider#dispose()
*/
public void dispose() {
}
/* (non-Javadoc)
* #see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
*/
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
}
}
public class MyModel {
public int counter;
public MyModel(int counter) {
this.counter = counter;
}
public String toString() {
**return "very loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog text" + this.counter;**
}
}
public Snippet001TableViewer(Shell shell) {
final TableViewer v = new TableViewer(shell);
v.setLabelProvider(new LabelProvider());
v.setContentProvider(new MyContentProvider());
MyModel[] model = createModel();
v.setInput(model);
v.getTable().setLinesVisible(true);
}
private MyModel[] createModel() {
MyModel[] elements = new MyModel[10];
for( int i = 0; i < 10; i++ ) {
elements[i] = new MyModel(i);
}
return elements;
}
/**
* #param args
*/
public static void main(String[] args) {
Display display = new Display ();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
new Snippet001TableViewer(shell);
shell.open ();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
}
It's windows bug/feature (see bugzilla for details), here is the proof (linux screenshot of your code)
I may be possible to workaround this bug/feature by self cell rendering (see Custom Drawing Table and Tree Items tutorial).
I found a simple way to get the whole text shown.
You have to use a StyledCellLabelProvider and override the update-method.
Here is a little example which shows the differences between a StyledCellLabelProvider and a ColumnLabelProvider. To override the update-method of ColumnLabelProvider is unnecessary. I did it to show that it depends on the class.
package tabletest;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.TableColumn;
public class MyClass {
private static final String LINE = "123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J"// 100
+ "123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789S123456789T" // 200
+ "123456789U123456789V123456789W123456789X123456789Y123456789Z" // 260
+ " a lot mor text";
public MyClass(Shell shell){
createControl(shell);
}
private void createControl(Composite parent){
parent.setLayout(new GridLayout(1, true));
TableViewer viewer = new TableViewer(parent, SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL |SWT.H_SCROLL);
viewer.getTable().setHeaderVisible(true);
viewer.getTable().setLinesVisible(true);
viewer.setContentProvider(ArrayContentProvider.getInstance());
viewer.setLabelProvider(new LabelProvider());
createColumn(viewer);
viewer.setInput(new String[] { LINE });
for(TableColumn col : viewer.getTable().getColumns()){
col.pack();
}
GridDataFactory.fillDefaults().grab(true, true).applyTo(viewer.getControl());
}
private void createColumn(TableViewer viewer) {
TableViewerColumn column1 = new TableViewerColumn(viewer, SWT.NONE);
column1.getColumn().setText("ColumnLabelProvider");
column1.setLabelProvider(new ColumnLabelProvider(){
#Override
public void update(ViewerCell cell) {
cell.setText(cell.getElement().toString());
super.update(cell);
}
});
TableViewerColumn column2 = new TableViewerColumn(viewer, SWT.NONE);
column2.getColumn().setText("StyledCellLabelProvider");
column2.setLabelProvider(new StyledCellLabelProvider() {
#Override
public void update(ViewerCell cell) {
cell.setText(cell.getElement().toString());
super.update(cell);
}
});
}
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
new MyClass(shell);
shell.open();
while(!shell.isDisposed()){
if(!display.readAndDispatch()){
display.sleep();
}
}
}
}
It also works in the Snippet001TableViewer when you change the LabelProvider to a StyledCellLabelProvider and override the update-method similar to my example.