I have designed a checkbox treeviewer using jface but when i run the program it doesnot display any thing on the UI.I am not able to find the where the issue is.Please help me whrer the problem is as I am new to jface.
private void createTreeMenu(Composite parentComposite){
/*treeItem = new TreeItem(tree, SWT.MULTI | SWT.CHECK | SWT.VIRTUAL |SWT.BORDER );
treeItem.setText("(1)Test Session");
treeItem.setImage(new Image(null, TreeViewer.class.getClassLoader().getResourceAsStream("icons/Folder-Main.JPG")));*/
Composite treeMenu = new Composite(parentComposite, SWT.BORDER);
treeMenu.setLayout(new GridLayout(1, false));
treeMenu.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, true));
/*tree = new Tree (treeMenu, SWT.MULTI | SWT.CHECK |SWT.VIRTUAL );
GridData treeGD = new GridData(SWT.FILL, GridData.FILL, true, true);
tree.setLayoutData(treeGD);*/
CheckboxTreeViewer treeViewer=new CheckboxTreeViewer(tree);
treeViewer.setContentProvider(new FileTreeContentProvider());
treeViewer.setLabelProvider(new FileTreeLabelProvider1());
treeViewer.setInput(treeItem);
parameters.add("root");
/*treeItem = new TreeItem(tree, SWT.MULTI | SWT.CHECK | SWT.VIRTUAL |SWT.BORDER );
treeItem.setText("(1)Test Session");
treeItem.setImage(new Image(null, TreeViewer.class.getClassLoader().getResourceAsStream("icons/Folder-Main.JPG")));*/
tree.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
if(e.item == null)
{
return;
}
treeSelection = tree.getSelection();
}
});
treeMenu.addListener(SWT.MouseDown, new Listener() {
#Override
public void handleEvent(Event event) {
tree.setSelection(new TreeItem[] {});
treeSelection = null;
}
});
final Menu menu = new Menu(tree);
tree.setMenu(menu);
loadMenuDetails(menu);
}
public TreeItem getInput()
{
treeItem = new TreeItem(tree, SWT.MULTI | SWT.CHECK | SWT.VIRTUAL |SWT.BORDER );
treeItem.setText("(1)Test Session");
treeItem.setImage(new Image(null, TreeViewer.class.getClassLoader().getResourceAsStream("icons/Folder-Main.JPG")));
return treeItem;
}
/**
* This class provides the content for the tree in FileTree
*/
class FileTreeContentProvider implements ITreeContentProvider {
/**
* Gets the children of the specified object
*
* #param arg0
* the parent object
* #return Object[]
*/
public Object[] getChildren(Object arg0) {
// Return the files and subdirectories in this directory
//return ((File) arg0).listFiles();
return null;
}
/**
* Gets the parent of the specified object
*
* #param arg0
* the object
* #return Object
*/
public Object getParent(Object arg0) {
// Return this file's parent file
//return ((File) arg0).getParentFile();
return null;
}
/**
* Returns whether the passed object has children
*
* #param arg0
* the parent object
* #return boolean
*/
public boolean hasChildren(Object arg0) {
// Get the children
Object[] obj = getChildren(arg0);
// Return whether the parent has children
return obj == null ? false : obj.length > 0;
}
/**
* Gets the root element(s) of the tree
*
* #param arg0
* the input data
* #return Object[]
*/
/*public Object[] getElements(Object arg0) {
// These are the root elements of the tree
// We don't care what arg0 is, because we just want all
// the root nodes in the file system
return File.listRoots();
//return "New ROOT";
}*/
public Object[] getElements(Object inputElement) {
//TreeItem rootItem = new TreeItem((Tree) arg0, SWT.CHECK);
//rootItem.setText("ROOT");
// return new Object[] { "Session Root" }; // your root item you want to display
treeItem = new TreeItem(tree, SWT.MULTI | SWT.CHECK | SWT.VIRTUAL |SWT.BORDER );
treeItem.setText("(1)Test Session");
treeItem.setImage(new Image(null, TreeViewer.class.getClassLoader().getResourceAsStream("icons/Folder-Main.JPG")));
if (inputElement instanceof TreeItem)
{
System.out.println("getelements");
return ((List<String>)inputElement).toArray();
}
return new Object[] {parameters.toArray()};
}
/**
* Disposes any created resources
*/
public void dispose() {
// Nothing to dispose
}
/**
* Called when the input changes
*
* #param arg0
* the viewer
* #param arg1
* the old input
* #param arg2
* the new input
*/
public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
// Nothing to change
}
}
class FileTreeLabelProvider1 implements ILabelProvider {
// The listeners
private List listeners;
// Images for tree nodes
private Image file;
private Image dir;
// Label provider state: preserve case of file names/directories
/**
* Constructs a FileTreeLabelProvider
*/
public FileTreeLabelProvider1() {
// Create the list to hold the listeners
listeners = new ArrayList();
// Create the images
try {
file = new Image(null, new FileInputStream("images/file.gif"));
dir = new Image(null, new FileInputStream("images/directory.gif"));
} catch (FileNotFoundException e) {
// Swallow it; we'll do without images
}
}
/**
* Gets the image to display for a node in the tree
*
* #param arg0
* the node
* #return Image
*/
public Image getImage(Object arg0) {
// If the node represents a directory, return the directory image.
// Otherwise, return the file image.
return ((File) arg0).isDirectory() ? dir : file;
}
/**
* Gets the text to display for a node in the tree
*
* #param arg0
* the node
* #return String
*/
public String getText(Object arg0) {
// Get the name of the file
String text = ((File) arg0).getName();
// If name is blank, get the path
if (text.length() == 0) {
text = ((File) arg0).getPath();
}
// Check the case settings before returning the text
return text ;
}
/**
* Adds a listener to this label provider
*
* #param arg0
* the listener
*/
public void addListener(ILabelProviderListener arg0) {
listeners.add(arg0);
}
/**
* Called when this LabelProvider is being disposed
*/
public void dispose() {
// Dispose the images
if (dir != null)
dir.dispose();
if (file != null)
file.dispose();
}
/**
* Returns whether changes to the specified property on the specified
* element would affect the label for the element
*
* #param arg0
* the element
* #param arg1
* the property
* #return boolean
*/
public boolean isLabelProperty(Object arg0, String arg1) {
return false;
}
/**
* Removes the listener
*
* #param arg0
* the listener to remove
*/
public void removeListener(ILabelProviderListener arg0) {
listeners.remove(arg0);
}
}
Try giving the tree object the parent composite and the flags (SWT.BORDER | SWT.CHECK)
it worked for me this way
tree = new Tree(treeMenu, SWT.BORDER | SWT.CHECK);
Related
I found this Custom fileTree Component from github to implement it into my project, I'm using this JTree component to access and display file information like file name, file path, file type in a JTable. The project is about File Tagging, I've implemented all necessary features related to that! The only thing remaining is an issue that I need to rectify in fileTree Component
Here is the code of all the java classes:
Constants.java
package jtree;
public class Constants {
/**
* the name of the OS as given by the Java system property "os.name"
*/
public final static String osname = System.getProperty("os.name");
/**
* true if the program is running on OS X
*/
public final static boolean isOSX = osname.equalsIgnoreCase("Mac OS X");
/**
* true if the program is running on Linux
*/
public final static boolean isLinux = osname.equalsIgnoreCase("Linux");
/**
* true if the program is running on Solaris
*/
public final static boolean isSolaris = osname.equalsIgnoreCase("SunOS");
/**
* true if the program is running on Windows Vista
*/
public final static boolean isVista = osname.equalsIgnoreCase("Windows Vista");
/**
* true if the program is running on Windows
*/
public final static boolean isWindows = !(isOSX || isLinux || isSolaris);
}
FileTree.java
package jtree;
import java.awt.Component;
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import javax.swing.JFileChooser;
import javax.swing.JTree;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
public class FileTree extends JTree {
/** Creates a new instance of FileTree */
public FileTree() {
super(new DefaultTreeModel(new DefaultMutableTreeNode("root")));
fileTreeModel = (DefaultTreeModel)treeModel;
showHiddenFiles = false;
showFiles = true;
navigateOSXApps = false;
initComponents();
initListeners();
}
/**
* returns the data model used by the FileTree. This method returns the same value
* as <code>getModel()</code>, with the only exception being that this method
* returns a <code>DefaultTreeModel</code>
* #return the data model used by the <code>FileTree</code>
*/
public DefaultTreeModel getFileTreeModel() {
return fileTreeModel;
}
/**
* returns the selected file in the tree. If there are multiple selections in the
* tree, then it will return the <code>File</code> associated with the value
* returned from <code>getSelectionPath</code>. You can enable/disable mutliple
* selections by changing the mode of the <code>TreeSelectionModel</code>.
* #return the selected file in the tree
*/
public File getSelectedFile() {
TreePath treePath = getSelectionPath();
if (treePath == null)
return null;
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)treePath.getLastPathComponent();
FileTreeNode fileTreeNode = (FileTreeNode)treeNode.getUserObject();
return fileTreeNode.file;
}
/**
* returns an array of the files selected in the tree. To enable/disable multiple
* selections, you can change the selection mode in the
* <code>TreeSelectionModel</code>.
* #return an array of the files selected in the tree
*/
public File[] getSelectedFiles() {
TreePath[] treePaths = getSelectionPaths();
if (treePaths == null)
return null;
File [] files = new File[treePaths.length];
for (int i=0; i<treePaths.length; i++)
{
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)treePaths[i].getLastPathComponent();
FileTreeNode fileTreeNode = (FileTreeNode)treeNode.getUserObject();
files[i] = fileTreeNode.file;
}
return files;
}
/**
* initializes class members
*/
private void initComponents() {
if (Constants.isWindows)
fsv = FileSystemView.getFileSystemView();
initRoot();
setCellRenderer(new FileTreeCellRenderer());
setEditable(false);
}
/**
* sets up the listeners for the tree
*/
private void initListeners() {
addTreeExpansionListener(new TreeExpansionListener() {
public void treeCollapsed(TreeExpansionEvent event) {
}
public void treeExpanded(TreeExpansionEvent event) {
TreePath path = event.getPath();
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) path.getLastPathComponent();
treeNode.removeAllChildren();
populateSubTree(treeNode);
fileTreeModel.nodeStructureChanged(treeNode);
}
});
FileTreeListener ftl = new FileTreeListener(this);
addMouseListener(ftl);
}
/**
* initializes the tree model
*/
private void initRoot() {
File[] roots = null;
if (Constants.isWindows)
roots = fsv.getRoots();
else
roots = File.listRoots();
if (roots.length == 1)
{
rootNode = new DefaultMutableTreeNode(new FileTreeNode(roots[0]));
populateSubTree(rootNode);
}
else if (roots.length > 1)
{
rootNode = new DefaultMutableTreeNode("Computer");
for (File root:roots)
rootNode.add(new DefaultMutableTreeNode(root));
}
else
rootNode = new DefaultMutableTreeNode("Error");
fileTreeModel.setRoot(rootNode);
}
/**
* returns true if deleting is allowed in the tree, false otherwise. The default
* value is false.
* #return true if deleting is allowed in the tree, false otherwise
*/
public boolean isDeleteEnabled() {
return allowDelete;
}
/**
* returns true if the user can navigate into OS X application bundles. false
* otherwise
* #return true if the user can navigate into OS X application bundles
*/
public boolean isNavigateOSXApps() {
return navigateOSXApps;
}
/**
* returns true if files will be shown in the tree, false otherwise. Default value
* is true.
* #return true if files will be shown in the tree, false otherwise
*/
public boolean isShowFiles() {
return showFiles;
}
/**
* returns true if the tree will show hidden files, false otherwise. Default value
* is false.
* #return true if the tree will show hidden files, false otherwise
*/
public boolean isShowHiddenFiles() {
return showHiddenFiles;
}
/**
* called whenever a node is expanded
* #param node the node to expand
*/
private void populateSubTree(DefaultMutableTreeNode node) {
Object userObject = node.getUserObject();
if (userObject instanceof FileTreeNode)
{
FileTreeNode fileTreeNode = (FileTreeNode)userObject;
File []files = fileTreeNode.file.listFiles();
// Windows displays directories before regular files, so we're going
// to sort the list of files such that directories appear first
if (Constants.isWindows)
{
Arrays.sort(files, new Comparator<File>() {
public int compare(File f1, File f2) {
boolean f1IsDir = f1.isDirectory();
boolean f2IsDir = f2.isDirectory();
if (f1IsDir == f2IsDir)
return f1.compareTo(f2);
if (f1IsDir && !f2IsDir)
return -1;
// here we assume that f1 is a file, and f2 is a directory
return 1;
}
});
}
else
Arrays.sort(files);
for (File file:files)
{
if (file.isFile() && !showFiles)
continue;
if (!showHiddenFiles && file.isHidden())
continue;
FileTreeNode subFile = new FileTreeNode(file);
DefaultMutableTreeNode subNode = new DefaultMutableTreeNode(subFile);
if (file.isDirectory())
{
if (!Constants.isOSX || navigateOSXApps || !file.getName().endsWith(".app"))
subNode.add(new DefaultMutableTreeNode("Fake"));
}
node.add(subNode);
}
}
}
/**
* Expands the tree to the <code>File</code> specified by the argument, and selects
* it as well. If the <code>currFile</code> does not exist or is null, calling this
* method will have no effect.
* #param currFile The file or directory to expand the tree to and select.
*/
public void setCurrentFile(File currFile) {
if (currFile == null || !currFile.exists())
return;
String path = currFile.getPath();
String [] pathParts = null;
if (Constants.isWindows)
pathParts = path.split("\\\\");
else
pathParts = path.split(File.separator);
if (Constants.isWindows)
{
int childCount = rootNode.getChildCount();
DefaultMutableTreeNode myComputer = null;
for (int i=0; i<childCount; i++)
{
FileTreeNode fileTreeNode =
(FileTreeNode)((DefaultMutableTreeNode)rootNode.getChildAt(i)).getUserObject();
if (fileTreeNode.file.getPath().equals(FileTreeNode.WINDOWS_MYCOMPUTER))
{
myComputer = (DefaultMutableTreeNode)rootNode.getChildAt(i);
TreePath treePath = new TreePath(myComputer.getPath());
expandPath(treePath);
break;
}
}
DefaultMutableTreeNode currNode = myComputer;
for (String part:pathParts)
{
childCount = currNode.getChildCount();
for (int i=0; i<childCount; i++)
{
DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)currNode.getChildAt(i);
FileTreeNode fileTreeNode = (FileTreeNode)childNode.getUserObject();
String pathName = fileTreeNode.file.getName();
if (pathName.length() == 0)
pathName = fileTreeNode.file.getPath().substring(0, 2);
if (pathName.equals(part))
{
TreePath treePath = new TreePath(childNode.getPath());
expandPath(treePath);
selectionModel.setSelectionPath(treePath);
currNode = childNode;
break;
}
}
}
}
else
{
DefaultMutableTreeNode currNode = rootNode;
for (String part:pathParts)
{
int childCount = currNode.getChildCount();
for (int i=0; i<childCount; i++)
{
DefaultMutableTreeNode childNode = (DefaultMutableTreeNode)currNode.getChildAt(i);
FileTreeNode fileTreeNode = (FileTreeNode)childNode.getUserObject();
if (fileTreeNode.file.getName().equals(part))
{
TreePath treePath = new TreePath(childNode.getPath());
expandPath(treePath);
selectionModel.setSelectionPath(treePath);
currNode = childNode;
break;
}
}
}
}
}
/**
* Allow or disallow the user to delete files from the tree view.
* #param allowDelete <code>true</code> allows deleting of files/directories. <code>false</code> does
* not.
*/
public void setDeleteEnabled(boolean allowDelete) {
this.allowDelete = allowDelete;
}
/**
* Toggle the showing of files in the tree (as opposed to just directories)
* #param showFiles <code>true</code> shows files in the tree. <code>false</code> does not.
*/
public void setShowFiles(boolean showFiles) {
if (this.showFiles != showFiles)
{
this.showFiles = showFiles;
initRoot();
}
}
/**
* Allows or disallows the showing of hidden files and directories in the tree.
* #param showHiddenFiles <code>true</code> shows hidden files. <code>false</code> does not.
*/
public void setShowHiddenFiles(boolean showHiddenFiles) {
if (showHiddenFiles != this.showHiddenFiles)
{
this.showHiddenFiles = showHiddenFiles;
initRoot();
}
}
/**
* sets whether the user can navigate into OS X application bundles (.app). The
* default value is <code>false</code>
* #param navigateOSXApps if true, users will be able to navigate into OS X application bundles. set it
* to false to disallow navigating bundles.
*/
public void setNavigateOSXApps(boolean navigateOSXApps) {
this.navigateOSXApps = navigateOSXApps;
}
/**
* the root node of the <code>FileTree</code>
*/
protected DefaultMutableTreeNode rootNode;
/**
* the <code>TreeModel</code> for this object. The same value as the <code>JTree</code>
* treeModel member.
*/
protected DefaultTreeModel fileTreeModel;
/**
* just a filesystemview used to get icons for nodes in Windows
*/
protected FileSystemView fsv;
/**
* whether or not to show hidden files
*/
protected boolean showHiddenFiles;
/**
* whether or not to show files
*/
protected boolean showFiles;
/**
* whether to allow deleting of files
*/
protected boolean allowDelete;
/**
* allows/disallows navigating into OS X application bundles
*/
protected boolean navigateOSXApps;
/**
* A subclass of DefaultTreeCellRenderer that is responsible for rendering the
* nodes and their icons
*/
private class FileTreeCellRenderer extends DefaultTreeCellRenderer {
/**
* just a simple constructor
*/
public FileTreeCellRenderer() {
fileChooser = new JFileChooser();
}
/**
* returns a renderered node for the tree
* #param tree the tree to render the node for
* #param value the value of the node
* #param selected if the node is selected
* #param expanded if it's expanded
* #param leaf if its a leaf or not
* #param row the row number
* #param hasFocus if it has focus
* #return a renderered node for the tree
*/
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
if (userObject instanceof FileTreeNode)
{
FileTreeNode fileTreeNode = (FileTreeNode)userObject;
if (!Constants.isWindows)
{
try { setIcon(fileChooser.getIcon(fileTreeNode.file)); }
catch (Exception e) { e.printStackTrace(); }
}
else
{
try { setIcon(fsv.getSystemIcon(fileTreeNode.file)); }
catch (Exception e) { e.printStackTrace(); }
}
}
return this;
}
/**
* used to obtain icons for non-Windows OSes
*/
private JFileChooser fileChooser;
}
}
FileTreeListener.Java
package jtree;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
public class FileTreeListener extends MouseAdapter {
/**
* Creates a new instance of FileTreeListener
* #param fileTree the <code>FileTree</code> to listen for
*/
public FileTreeListener(FileTree fileTree) {
if (fileTree == null)
throw new IllegalArgumentException("Null argument not allowed");
this.fileTree = fileTree;
}
/**
* Listens for right-clicks on the tree.
* #param e contains information about the mouse click event
*/
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3)
rightClick(e.getX(), e.getY());
}
/**
*
* #param x the x coordinate of the mouse when it was pressed
* #param y the y coordinate of the mouse when it was pressed
*/
private void rightClick(int x, int y) {
TreePath treePath = fileTree.getPathForLocation(x, y);
if (treePath == null)
return;
if (!fileTree.isDeleteEnabled())
return;
JPopupMenu popup = new JPopupMenu();
popup.add(new DeleteFileAction(treePath));
popup.show(fileTree, x, y);
}
/**
* the <code>FileTree</code> to listen on
*/
private FileTree fileTree;
/**
* feature not implemented
*/
private class RenameAction extends AbstractAction {
public RenameAction(TreePath treePath) {
this.treePath = treePath;
putValue(Action.NAME, "Rename");
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)treePath.getLastPathComponent();
fileTreeNode = (FileTreeNode)treeNode.getUserObject();
if (!fileTreeNode.file.canWrite())
setEnabled(false);
}
#Override
public void actionPerformed(ActionEvent e) {
fileTree.startEditingAtPath(treePath);
}
private TreePath treePath;
private FileTreeNode fileTreeNode;
}
private class DeleteFileAction extends AbstractAction {
/**
* constructor for the action to delete a file or directory
* #param treePath the treepath of the node to act on
*/
public DeleteFileAction(TreePath treePath) {
this.treePath = treePath;
if (Constants.isOSX)
putValue(Action.NAME, "Move to Trash");
else
{
putValue(Action.NAME, "Delete");
putValue(Action.MNEMONIC_KEY, KeyEvent.VK_D);
}
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)treePath.getLastPathComponent();
fileTreeNode = (FileTreeNode)treeNode.getUserObject();
if (!fileTreeNode.file.canWrite())
setEnabled(false);
}
/**
* the action called when the user wants to delete a file or directory
* #param e information about the event that caused this method to be called
*/
public void actionPerformed(ActionEvent e) {
int choice = JOptionPane.showConfirmDialog(fileTree.getRootPane(),
"Are you sure you want to delete '" + fileTreeNode.file.getName()+"'?",
"Confirm delete",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (choice == 1)
return; // they selected no
boolean success = false;
if (fileTreeNode.file.isDirectory())
success = deleteDirectory(fileTreeNode.file);
else
success = fileTreeNode.file.delete();
if (success)
{
fileTree.getFileTreeModel().removeNodeFromParent(
(DefaultMutableTreeNode)treePath.getLastPathComponent());
}
}
/**
* deletes a directory and its content
* #param dir The directory to delete
* #return true on success, false otherwise
*/
private boolean deleteDirectory(File dir) {
if (dir == null || !dir.exists() || !dir.isDirectory())
return false;
boolean success = true;
File [] list = dir.listFiles();
for (File file:list)
{
if (file.isDirectory())
{
if (!deleteDirectory(file))
success = false;
}
else
{
if (!file.delete())
success = false;
}
}
if (!dir.delete()) // finally delete the actual directory
success = false;
return success;
}
/**
* The <code>TreePath</code> to the node that will be deleted.
*/
private TreePath treePath;
/**
* The <code>FileTreeNode</code> stored inside the <code>DefaultMutableTreeNode</code>'s
* user object
*/
private FileTreeNode fileTreeNode;
}
}
FileTreeNode.java
package jtree;
import java.io.File;
public class FileTreeNode {
/**
* Creates a new instance of FileTreeNode
* #param file The <code>File</code> that will be represented by this class.
*/
public FileTreeNode(File file) {
if (file == null)
throw new IllegalArgumentException("Null file not allowed");
this.file = file;
}
/**
* returns the representation of this <code>File</code> best suited for use in
* the <code>FileTree</code>.
* #return the representation of this <code>File</code> as a <code>String</code>
*/
public String toString() {
String name = file.getName();
if (!Constants.isWindows)
return name;
if (name.length() == 0)
return file.getPath();
if (Constants.isVista)
{
if (name.equals(WINDOWS_MYCOMPUTER)){
return "Computer";
}
if ("::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}".equals(name)){
return "My Network";
}
return name;
}
if (name.equals(WINDOWS_MYCOMPUTER)){
return "This PC";
}
if ("::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}".equals(name)){
return "Network";
}
if ("::{031E4825-7B94-4DC3-B131-E946B44C8DD5}".equals(name)){
return "Library-MS";
}
return name;
}
/**
* the object being represented
*/
public File file;
/**
* the hex string that represents 'My Computer' in Windows
*/
public static final String WINDOWS_MYCOMPUTER = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}";
/**
* the hex string that represents 'My Network Places' in Win2k and XP
*/
public static final String WINDOWS_MYNETWORKPLACES = "::{208D2C60-3AEA-1069-A2D7-08002B30309D}";
/**
* the hex string that represents 'Network' in Vista
*/
public static final String WINDOWSVISTA_NETWORK = "::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}";
}
Main.java
package jtree;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
public class Main {
/** Creates a new instance of Main */
public Main() {
}
public static void main(String[] args) {
JFrame jframe = new JFrame();
jframe.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Container container = jframe.getContentPane();
container.setLayout(new BorderLayout());
FileTree fileTree = new FileTree();
fileTree.setShowHiddenFiles(false);
fileTree.setDeleteEnabled(true);
JScrollPane scrollPane = new JScrollPane(fileTree);
container.add(scrollPane, BorderLayout.CENTER);
jframe.setSize(300, 450);
jframe.setLocationByPlatform(true);
jframe.setVisible(true);
}
}
I've been trying to implement the Timer function for 3 or 5 seconds to update the JTree using the updateUI(), repaint(), revalidate() methods including the DefaultTreeModel. I'm still unable to keep the file JTree updated whenever a file is renamed, moved or deleted. Can someone please help me rectify this issue and guide me where to place the code snippet if written by you?
What I managed to do so far is adding a ToolBarManager for the ToolBar I created, which contains the ToolItem I want to add but nothing is shown when the hover popup based on this DefaultInformationControl is open.
I gave all the ToolItems text and style.
My code is :
public class JavaTextHover implements IJavaEditorTextHover, ITextHoverExtension{
.
.
.
#Override
public IInformationControlCreator getHoverControlCreator() {
return new IInformationControlCreator() {
public IInformationControl createInformationControl(Shell parent) {
ToolBar toolBar = new ToolBar(parent, SWT.NONE);
ToolItem itemPush = new ToolItem(toolBar, SWT.PUSH);
itemPush.setText("PUSH item");
ToolItem itemCheck = new ToolItem(toolBar, SWT.CHECK);
itemCheck.setText("CHECK item");
ToolItem itemRadio1 = new ToolItem(toolBar, SWT.RADIO);
itemRadio1.setText("RADIO item 1");
ToolItem itemRadio2 = new ToolItem(toolBar, SWT.RADIO);
itemRadio2.setText("RADIO item 2");
ToolItem itemSeparator = new ToolItem(toolBar, SWT.SEPARATOR);
Text text = new Text(toolBar, SWT.BORDER | SWT.SINGLE);
text.pack();
itemSeparator.setWidth(text.getBounds().width);
itemSeparator.setControl(text);
final ToolItem itemDropDown = new ToolItem(toolBar, SWT.DROP_DOWN);
itemDropDown.setText("DROP_DOWN item");
itemDropDown.setToolTipText("Click here to see a drop down menu ...");
final Menu menu = new Menu(parent, SWT.POP_UP);
new MenuItem(menu, SWT.PUSH).setText("Menu item 1");
new MenuItem(menu, SWT.PUSH).setText("Menu item 2");
new MenuItem(menu, SWT.SEPARATOR);
new MenuItem(menu, SWT.PUSH).setText("Menu item 3");
itemDropDown.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if(event.detail == SWT.ARROW) {
Rectangle bounds = itemDropDown.getBounds();
Point point = toolBar.toDisplay(bounds.x, bounds.y + bounds.height);
menu.setLocation(point);
menu.setVisible(true);
}
}
});
Listener selectionListener = new Listener() {
public void handleEvent(Event event) {
ToolItem item = (ToolItem)event.widget;
System.out.println(item.getText() + " is selected");
if( (item.getStyle() & SWT.RADIO) != 0 || (item.getStyle() & SWT.CHECK) != 0 )
System.out.println("Selection status: " + item.getSelection());
}
};
itemPush.addListener(SWT.Selection, selectionListener);
itemCheck.addListener(SWT.Selection, selectionListener);
itemRadio1.addListener(SWT.Selection, selectionListener);
itemRadio2.addListener(SWT.Selection, selectionListener);
itemDropDown.addListener(SWT.Selection, selectionListener);
toolBar.pack();
toolBar.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,false));
ToolBarManager tbm=new ToolBarManager(toolBar);
System.out.println(tbm.getControl().getChildren().length);
DefaultInformationControl dic=new DefaultInformationControl(parent, tbm);
dic.setBackgroundColor(new Color(null, 98,201,145));
return dic;
}
};
}
.
.
.
}
The only example of using the tool bar that I can see in the Eclipse core code does things this way:
private static final class PresenterControlCreator extends AbstractReusableInformationControlCreator {
#Override
public IInformationControl doCreateInformationControl(Shell parent) {
ToolBarManager tbm= new ToolBarManager(SWT.FLAT);
NLSHoverControl iControl= new NLSHoverControl(parent, tbm);
OpenPropertiesFileAction openPropertiesFileAction= new OpenPropertiesFileAction(iControl);
tbm.add(openPropertiesFileAction);
tbm.update(true);
return iControl;
}
}
NLSHoverControl extends DefaultInformationControl.
So it is adding to the tool bar after creating the DefaultInformationControl and using actions rather than tool items.
static class NLSHoverControl extends DefaultInformationControl implements IInformationControlExtension2 {
/**
* The NLS control input.
*/
private NLSHoverControlInput fInput;
/**
* Creates a resizable NLS hover control with the given shell as parent.
*
* #param parent the parent shell
* #param tbm the toolbar manager or <code>null</code> if toolbar is not desired
*/
public NLSHoverControl(Shell parent, ToolBarManager tbm) {
super(parent, tbm);
}
/**
* Creates an NLS hover control with the given shell as parent.
*
* #param parent the parent shell
* #param tooltipAffordanceString the text to be used in the status field or
* <code>null</code> to hide the status field
*/
public NLSHoverControl(Shell parent, String tooltipAffordanceString) {
super(parent, tooltipAffordanceString);
}
/**
* {#inheritDoc} This control can handle {#link NLSStringHover.NLSHoverControlInput}.
*/
public void setInput(Object input) {
Assert.isLegal(input instanceof NLSHoverControlInput);
NLSHoverControlInput info= (NLSHoverControlInput)input;
setInformation(info.fInformation);
fInput= info;
}
/**
* Returns the control input.
*
* #return the control input
*/
public NLSHoverControlInput getInput() {
return fInput;
}
}
im trying to build input dialog using swt.
i want to read my class properties and make the dialog window on specified order or even lexicographic order. i'll keep my class properties in linkedhahmap\treemap.
example:
public class MazeProperties {
/** Maze Name. */
private String MazeName;
/** Number of rows in maze. */
private int x;
/** The Floors. */
private int y;
/** Number of columns in maze. */
private int z;
public MazeProperties(String mazeName, int rows, int floors, int columns) {
MazeName = mazeName;
Rows = rows;
Floors = floors;
Columns = columns;
}
public class ClassInputDialog extends Dialog{
/** The shell. */
Shell shell;
/** the generic class. */
private Class<?> template;
/** Property Descriptors give me the ability to see what properties the class contains - and has generic functionalities for setters and getters for fields!. */
PropertyDescriptor[] descs;
/** I wanna have a robust connection between a property to a text box - that way upon pressing OK I could know what class property was written in it.
*
*/
HashMap<PropertyDescriptor,Text> txtMap=new LinkedHashMap<PropertyDescriptor,Text>();
//TreeMap<String,Text> txtMapOrderName=new TreeMap<String,Text>();
//Map<PropertyDescriptor, Text> txtMap = Collections.synchronizedMap(new LinkedHashMap<PropertyDescriptor, Text>());
/** The bonus demanded that this dialog will support all given classes
* but what happens when a class has an enum? a whole new story with combo-boxes and once again I wanna have a connection between the class field enum to the String that was selected in the form.
*
*/
HashMap<PropertyDescriptor,String> enumMap=new **HashMap<PropertyDescriptor,String>();**
/** This is the reference of the instance I will return.
*
*/
private Object input;
/** Ct'r for people that don't know a thing about SWT.
* #param parent - Shell
* #param template - The Class to create form to
*/
public ClassInputDialog(Shell parent,Class<?> template) {
this(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL,template);
}
/**
* Ct'r with SWT style.
*
* #param parent - Shell
* #param style - SWT style
* #param template - The Class to create form to
*/
public ClassInputDialog(Shell parent, int style,Class<?> template) {
super(parent, style);
this.template=template;
descs=PropertyUtils.getPropertyDescriptors(template);
setText("Set Properties");
}
/**
* Gets the input.
*
* #return the input
*/
public Object getInput() {
return input;
}
/**
* Sets the input.
*
* #param input the new input
*/
public void setInput(Object input) {
this.input = input;
}
/** Here the window layout is set and the main loop event happens. When window closes User's input is returned.
* #return The user's input
*/
public Object open() {
this.shell = new Shell(getParent(), getStyle());
shell.setText(getText());
createContents(shell);
shell.pack();
shell.open();
Display display = getParent().getDisplay();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
//display.dispose();
return input;
}
/** Creates Window content and layout - sets Labels, Text boxes and combo boxes nicely.
* #param shell - window's parent
*/
private void createContents(final Shell shell) {
shell.setLayout(new GridLayout(2, true));
for(**PropertyDescriptor propDesc: descs**)
if(!propDesc.getName().equals("class"))
{
if(!propDesc.getPropertyType().isEnum())
{
Label label = new Label(shell, SWT.NONE);
label.setText(propDesc.getName());
GridData data = new GridData();
data.horizontalSpan = 2;
label.setLayoutData(data);
final Text text = new Text(shell, SWT.BORDER);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
text.setLayoutData(data);
txtMap.put(propDesc, text);
// txtMapOrderName.put(propDesc.getDisplayName(), text);
System.out.println(propDesc.getDisplayName());
}
else
{
Label label = new Label(shell, SWT.NONE);
label.setText(propDesc.getName());
GridData data = new GridData();
data.horizontalSpan = 2;
label.setLayoutData(data);
final Combo combo = new Combo(shell, SWT.DROP_DOWN);
String[] toCombo=new String[propDesc.getPropertyType().getEnumConstants().length];
for(int i=0;i<propDesc.getPropertyType().getEnumConstants().length;i++)
toCombo[i]=propDesc.getPropertyType().getEnumConstants()[i].toString();
combo.setItems(toCombo);
data = new GridData(GridData.FILL_HORIZONTAL);
data.horizontalSpan = 2;
combo.setLayoutData(data);
combo.addSelectionListener(new SelectionListener() {
#Override
public void widgetSelected(SelectionEvent arg0) {
enumMap.put(propDesc, combo.getText());
}
#Override
public void widgetDefaultSelected(SelectionEvent arg0) {
}
});
}
}
the output is not as the class properties order, it's something like
y
mazeName
x
z
If you want to map keys to values in a deterministic, predictable order, you should store them in a TreeMap, taking care that the key class implements Comparator. If it doesn't, you must implement your own Comparator and pass it as a parameter to the TreeMap constructor.
In your case, if you want PropertyDescriptor as key, you must implement your own Comparator to compare PropertyDescriptor objects.
I am using a JXComboBox as cell editor in a modified JXTable/RXTable with custom models. I am noticing a delay when starting to type inside the cell.
Edit: also, if you type more keys faster in the box, the first one you typed will not appear first in the editor.
The table:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.text.*;
import org.jdesktop.swingx.JXTable;
/**
* This is a modified version of RXTable following this thread:
* http://stackoverflow.com/questions/7365397/combining-jxtable-with-rxtable.
* The JRXTable provides some extensions to the default JTable
*
* 1) Select All editing - when a text related cell is placed in editing mode
* the text is selected. Controlled by invoking a "setSelectAll..." method.
*
* 2) reorderColumns - static convenience method for reodering table columns
*/
public class JRXTable extends JXTable {
private boolean isSelectAllForMouseEvent = false;
private boolean isSelectAllForActionEvent = false;
private boolean isSelectAllForKeyEvent = false;
//
// Constructors
//
/**
* Constructs a default
* <code>JRXTable</code> that is initialized with a default data model, a
* default column model, and a default selection model.
*/
public JRXTable() {
this(null, null, null);
}
/**
* Constructs a
* <code>JRXTable</code> that is initialized with
* <code>dm</code> as the data model, a default column model, and a default
* selection model.
*
* #param dm the data model for the table
*/
public JRXTable(TableModel dm) {
this(dm, null, null);
}
/**
* Constructs a
* <code>JRXTable</code> that is initialized with
* <code>dm</code> as the data model,
* <code>cm</code> as the column model, and a default selection model.
*
* #param dm the data model for the table
* #param cm the column model for the table
*/
public JRXTable(TableModel dm, TableColumnModel cm) {
this(dm, cm, null);
}
/**
* Constructs a
* <code>JRXTable</code> that is initialized with
* <code>dm</code> as the data model,
* <code>cm</code> as the column model, and
* <code>sm</code> as the selection model. If any of the parameters are
* <code>null</code> this method will initialize the table with the
* corresponding default model. The
* <code>autoCreateColumnsFromModel</code> flag is set to false if
* <code>cm</code> is non-null, otherwise it is set to true and the column
* model is populated with suitable
* <code>TableColumns</code> for the columns in
* <code>dm</code>.
*
* #param dm the data model for the table
* #param cm the column model for the table
* #param sm the row selection model for the table
*/
public JRXTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) {
super(dm, cm, sm);
}
/**
* Constructs a
* <code>JRXTable</code> with
* <code>numRows</code> and
* <code>numColumns</code> of empty cells using
* <code>DefaultTableModel</code>. The columns will have names of the form
* "A", "B", "C", etc.
*
* #param numRows the number of rows the table holds
* #param numColumns the number of columns the table holds
*/
public JRXTable(int numRows, int numColumns) {
this(new DefaultTableModel(numRows, numColumns));
}
/**
* Constructs a
* <code>JRXTable</code> to display the values in the
* <code>Vector</code> of
* <code>Vectors</code>,
* <code>rowData</code>, with column names,
* <code>columnNames</code>. The
* <code>Vectors</code> contained in
* <code>rowData</code> should contain the values for that row. In other
* words, the value of the cell at row 1, column 5 can be obtained with the
* following code:
* <p>
* <pre>((Vector)rowData.elementAt(1)).elementAt(5);</pre>
* <p>
*
* #param rowData the data for the new table
* #param columnNames names of each column
*/
public JRXTable(Vector rowData, Vector columnNames) {
this(new DefaultTableModel(rowData, columnNames));
}
/**
* Constructs a
* <code>JRXTable</code> to display the values in the two dimensional array,
* <code>rowData</code>, with column names,
* <code>columnNames</code>.
* <code>rowData</code> is an array of rows, so the value of the cell at row
* 1, column 5 can be obtained with the following code:
* <p>
* <pre> rowData[1][5]; </pre>
* <p>
* All rows must be of the same length as
* <code>columnNames</code>.
* <p>
*
* #param rowData the data for the new table
* #param columnNames names of each column
*/
public JRXTable(final Object[][] rowData, final Object[] columnNames) {
super(rowData, columnNames);
}
//
// Overridden methods
//
/*
* Override to provide Select All editing functionality
*/
#Override
public boolean editCellAt(int row, int column, EventObject e) {
boolean result = super.editCellAt(row, column, e);
// my editing
//
// if (e instanceof KeyEvent && isSelectAllForKeyEvent) {
// KeyEvent keyEvent = (KeyEvent) e;
// Character keyChar = keyEvent.getKeyChar();
// if (keyChar == KeyEvent.VK_ESCAPE) {
// return result;
// }
// }
// my editing
if (isSelectAllForMouseEvent
|| isSelectAllForActionEvent
|| isSelectAllForKeyEvent) {
selectAll(e);
}
return result;
}
/*
* Select the text when editing on a text related cell is started
*/
private void selectAll(EventObject e) {
final Component editor = getEditorComponent();
// add suport for the text editor from a ComboBox
// move to editCellAt method?
if (getEditorComponent() instanceof JComboBox) {
final JComboBox combo = (JComboBox) getEditorComponent();
ComboBoxEditor comboEditor = combo.getEditor();
final JTextField comboTextField = (JTextField) comboEditor.getEditorComponent();
// comboEditor.selectAll();
if (e instanceof KeyEvent && isSelectAllForKeyEvent) {
KeyEvent keyEvent = (KeyEvent) e;
final Character keyChar = keyEvent.getKeyChar();
if (keyChar == KeyEvent.VK_ESCAPE) {
System.out.println("escape");
// combo.getFocusCycleRootAncestor().requestFocus();
// combo.transferFocus();
} else {
comboEditor.selectAll();
comboTextField.setText(comboTextField.getText());
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// set null value if the Delete key is pressed
if (keyChar == KeyEvent.VK_DELETE) {
combo.setSelectedItem(null);
comboTextField.setText(null);
} else {
comboTextField.selectAll();
// comboTextField.setText("");
}
}
});
}
}
return;
}
if (editor == null
|| !(editor instanceof JTextComponent
|| editor instanceof JFormattedTextField)) {
return;
}
if (e == null) {
((JTextComponent) editor).selectAll();
return;
}
// Typing in the cell was used to activate the editor
if (e instanceof KeyEvent && isSelectAllForKeyEvent) {
((JTextComponent) editor).selectAll();
return;
}
// If the cell we are dealing with is a JFormattedTextField
// force to commit, and invoke selectall
if (editor instanceof JFormattedTextField) {
invokeSelectAll((JFormattedTextField) editor);
return;
}
// F2 was used to activate the editor
if (e instanceof ActionEvent && isSelectAllForActionEvent) {
((JTextComponent) editor).selectAll();
return;
}
// A mouse click was used to activate the editor.
// Generally this is a double click and the second mouse click is
// passed to the editor which would remove the text selection unless
// we use the invokeLater()
if (e instanceof MouseEvent && isSelectAllForMouseEvent) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
((JTextComponent) editor).selectAll();
}
});
}
}
private void invokeSelectAll(final JFormattedTextField editor) {
// old trick: force to commit, and invoke selectall
editor.setText(editor.getText());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
editor.selectAll();
}
});
}
//
// Newly added methods
//
/*
* Sets the Select All property for for all event types
*/
public void setSelectAllForEdit(boolean isSelectAllForEdit) {
setSelectAllForMouseEvent(isSelectAllForEdit);
setSelectAllForActionEvent(isSelectAllForEdit);
setSelectAllForKeyEvent(isSelectAllForEdit);
}
/*
* Set the Select All property when editing is invoked by the mouse
*/
public void setSelectAllForMouseEvent(boolean isSelectAllForMouseEvent) {
this.isSelectAllForMouseEvent = isSelectAllForMouseEvent;
}
/*
* Set the Select All property when editing is invoked by the "F2" key
*/
public void setSelectAllForActionEvent(boolean isSelectAllForActionEvent) {
this.isSelectAllForActionEvent = isSelectAllForActionEvent;
}
/*
* Set the Select All property when editing is invoked by
* typing directly into the cell
*/
public void setSelectAllForKeyEvent(boolean isSelectAllForKeyEvent) {
this.isSelectAllForKeyEvent = isSelectAllForKeyEvent;
}
//
// Static, convenience methods
//
/**
* Convenience method to order the table columns of a table. The columns are
* ordered based on the column names specified in the array. If the column
* name is not found then no column is moved. This means you can specify a
* null value to preserve the current order of a given column.
*
* #param table the table containing the columns to be sorted
* #param columnNames an array containing the column names in the order they
* should be displayed
*/
public static void reorderColumns(JTable table, Object... columnNames) {
TableColumnModel model = table.getColumnModel();
for (int newIndex = 0; newIndex < columnNames.length; newIndex++) {
try {
Object columnName = columnNames[newIndex];
int index = model.getColumnIndex(columnName);
model.moveColumn(index, newIndex);
} catch (IllegalArgumentException e) {
}
}
}
} // End of Class JRXTable
The test class:
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
import java.util.HashMap;
import javax.swing.ComboBoxEditor;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.table.DefaultTableModel;
import org.jdesktop.swingx.JXComboBox;
import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;
import org.jdesktop.swingx.autocomplete.ComboBoxCellEditor;
import org.jdesktop.swingx.autocomplete.ObjectToStringConverter;
import org.jdesktop.swingx.renderer.DefaultListRenderer;
import org.jdesktop.swingx.renderer.DefaultTableRenderer;
import org.jdesktop.swingx.renderer.StringValue;
public class TestSwingXComboCellEditor {
public static void main(String[] args) {
TestSwingXComboCellEditor test = new TestSwingXComboCellEditor();
test.go();
}
public void go() {
//create the frame
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// create and add a tabbed pane to the frame
JTabbedPane tabbedPane = new JTabbedPane();
frame.getContentPane().add(tabbedPane);
//create a table and add it to a scroll pane in a new tab
JRXTable table = new JRXTable();
table.setModel(new DefaultTableModel(new Object[]{"A", "B"}, 5));
table.setSelectAllForEdit(true);
JScrollPane scrollPane = new JScrollPane(table);
tabbedPane.addTab("test", scrollPane);
// create a simple JComboBox and set is as table cell editor on column A
UserRepository rep = new UserRepository();
UserInfo[] comboElements = rep.getAllUsers();
DefaultComboBoxModel model = new DefaultComboBoxModel(comboElements);
JXComboBox comboBox = new JXComboBox(model);
StringValue stringValue = new StringValue() {
public String getString(Object value) {
if (value instanceof UserInfo) {
UserInfo userInfo = (UserInfo) value;
return userInfo.getFirstName();
} else {
return "";
}
}
};
ComboBoxCellEditor cellEditor = new ComboBoxCellEditor(comboBox);
comboBox.setRenderer(new DefaultListRenderer(stringValue));
comboBox.setEditable(true);
AutoCompleteDecorator.decorate(comboBox, new ObjectToStringConverter() {
#Override
public String getPreferredStringForItem(Object item) {
if (item instanceof UserInfo) {
return ((UserInfo) item).getFirstName();
} else {
return null;
}
}
});
table.getColumn("A").setCellEditor(cellEditor);
table.getColumn("A").setCellRenderer(new DefaultTableRenderer(stringValue));
// pack and show frame
frame.pack();
frame.setVisible(true);
}
public class UserInfo {
private String firstName;
private String lastName;
public UserInfo(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}
public class UserRepository {
UserInfo[] comboElements;
HashMap<String, UserInfo> objectsMap;
public UserRepository() {
comboElements = new UserInfo[5];
comboElements[0] = new UserInfo("John", "Doe");
comboElements[1] = new UserInfo("Betty", "Doe");
comboElements[2] = new UserInfo("Elenor", "Smith");
comboElements[3] = new UserInfo("Helen", "Kelly");
comboElements[4] = new UserInfo("Joe", "Black");
objectsMap = new HashMap<>();
for (int i = 0; i < 5; i++) {
objectsMap.put(comboElements[i].getFirstName(), comboElements[i]);
}
}
public UserInfo getUserInfo(String name) {
return objectsMap.get(name);
}
public UserInfo[] getAllUsers() {
return comboElements;
}
}
}
If I create a new shell using the following code:
shell = new Shell( Display.getDefault(), SWT.RESIZE);
Then this gives me a shell without a title bar or minimize / maximize buttons, which is what I want. I'm able to resize this window to any size, which works great. But the problem is, the window is fixed in its place, and I cannot move it by dragging it around.
If I add either SWT.CASCADE or SWT.CLOSE, this gives me the title bar and close button, which I don't want, but moreover, it puts a limit on how small the window can be resized, i.e I can't resize it horizontally past a certain limit.
How can I make the window moveable without the close button / title bar? If there's no native way in SWT to do it, can I do it by listening for a mouse drag event and manually setting the location of the shell? If so, how would I get the mouse coordinates from the movement of the mouse?
Help would be appreciated. Thanks!
You need use own listeners. Below code should help:-
public class Demo {
static Boolean blnMouseDown=false;
static int xPos=0;
static int yPos=0;
public static void main(final String[] args) {
Display display=new Display();
final Shell shell = new Shell( Display.getDefault(), SWT.RESIZE);
shell.open();
shell.addMouseListener(new MouseListener() {
#Override
public void mouseUp(MouseEvent arg0) {
// TODO Auto-generated method stub
blnMouseDown=false;
}
#Override
public void mouseDown(MouseEvent e) {
// TODO Auto-generated method stub
blnMouseDown=true;
xPos=e.x;
yPos=e.y;
}
#Override
public void mouseDoubleClick(MouseEvent arg0) {
// TODO Auto-generated method stub
}
});
shell.addMouseMoveListener(new MouseMoveListener() {
#Override
public void mouseMove(MouseEvent e) {
// TODO Auto-generated method stub
if(blnMouseDown){
shell.setLocation(shell.getLocation().x+(e.x-xPos),shell.getLocation().y+(e.y-yPos));
}
}
});
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.close();
}
}
This is my implementation:
/**
* Class to allow user to move a shell without a title.
*
* #author Laurent Muller
* #version 1.0
*/
public class MoveShellListener implements Listener {
/*
* the parent shell
*/
private final Shell parent;
/*
* the mouse down location
*/
private Point ptMouseDown;
/**
* Creates a new instance of this class.
*
* #param parent
* the shell to handle.
*/
public MoveShellListener(final Shell parent) {
if (parent == null) {
SWT.error(SWT.ERROR_NULL_ARGUMENT);
}
if (parent.isDisposed()) {
SWT.error(SWT.ERROR_WIDGET_DISPOSED);
}
// copy and add listener
this.parent = parent;
addControl(parent);
}
/**
* Adds the given control to the list of listened controls. If the given
* control is an instance of {#link Composite}, the children controls are
* also added.
*
* #param control
* the control to add.
*/
public void addControl(final Control control) {
// check control
if (isDisposed(control) || control.getShell() != parent) {
return;
}
// add listeners
control.addListener(SWT.MouseDown, this);
control.addListener(SWT.MouseUp, this);
control.addListener(SWT.MouseMove, this);
// children
if (control instanceof Composite) {
final Control[] children = ((Composite) control).getChildren();
for (final Control child : children) {
addControl(child);
}
}
}
/**
* Adds the given controls to the list of listened controls. If one of the
* given controls is an instance of {#link Composite}, the children controls
* are also added.
*
* #param controls
* the controls to add.
*/
public void addControls(final Control... controls) {
if (controls != null) {
for (final Control control : controls) {
addControl(control);
}
}
}
/**
* {#inheritDoc}
*/
#Override
public void handleEvent(final Event e) {
switch (e.type) {
case SWT.MouseDown:
onMouseDown(e);
break;
case SWT.MouseUp:
onMouseUp(e);
break;
case SWT.MouseMove:
onMouseMove(e);
break;
}
}
/**
* Removes the given control to the list of listened controls. If the given
* control is an instance of {#link Composite}, the children controls are
* also removed.
*
* #param control
* the control to remove.
*/
public void removeControl(final Control control) {
// check control
if (control == parent || isDisposed(control)
|| control.getShell() != parent) {
return;
}
// remove listeners
control.removeListener(SWT.MouseDown, this);
control.removeListener(SWT.MouseUp, this);
control.removeListener(SWT.MouseMove, this);
// children
if (control instanceof Composite) {
final Control[] children = ((Composite) control).getChildren();
for (final Control child : children) {
removeControl(child);
}
}
}
/**
* Removes the given controls to the list of listened controls. If one of
* the given controls is an instance of {#link Composite}, the children
* controls are also removed.
*
* #param controls
* the controls to remove.
*/
public void removeControls(final Control... controls) {
if (controls != null) {
for (final Control control : controls) {
removeControl(control);
}
}
}
/**
* Checks if the given control is null or disposed.
*
* #param control
* the control to verify.
* #return true if the control is null or
* disposed.
*/
private boolean isDisposed(final Control control) {
return control == null || control.isDisposed();
}
/**
* Handles the mouse down event.
*
* #param e
* the event data.
*/
private void onMouseDown(final Event e) {
if (e.button == 1) {
ptMouseDown = new Point(e.x, e.y);
}
}
/**
* Handles the mouse move event.
*
* #param e
* the event data.
*/
private void onMouseMove(final Event e) {
if (ptMouseDown != null) {
final Point location = parent.getLocation();
location.x += e.x - ptMouseDown.x;
location.y += e.y - ptMouseDown.y;
parent.setLocation(location);
}
}
/**
* Handles the mouse up event.
*
* #param e
* the event data.
*/
private void onMouseUp(final Event e) {
ptMouseDown = null;
}
}