Events combination SmartGWT - java

I'm working on Java, SmartGWT 2.5 & Mozilla FF 3.6.x. I'm using Tree, TreeGrid & TreeNode in my application. I need to drag a node and while dragging I have to see the other nodes on which mouse will pass with changed background color. I tried with dragStart, dragStop, onCellOver, onCellOut and dragMove, but maybe I don't make a good combination of them. So, how can be these events combinated to get what I need?

Add a DropOverHandler on the target widget (a TreeGrid in this case).
You'll then need to use one of the many available styling APIs (probably getCellCSSText()) so that it returns different results while the mouse remains over the target grid, and call markForRedraw() on the grid from DropOver so that your new styling is applied.
Overriding willAcceptDrop() is how you tell the system whether dropping on a particular row is allowed (affects the mouse cursor).
Detect the mouse exiting the grid via the DropOut event, and call markForRedraw() again there.

Related

GEF : automatic scrolling during drag and drop

I have a graphical editor written with GEF. In this editor it's possible to drag and drop elements around and create connection by dragging and dropping on specific anchor points.
Everything works fine, except that the diagram does not automatically scroll when the user drags stuff around.
I would expect the diagram to scroll automatically when the user reaches the side of it while dragging something.
Is such a feature supported by GEF? Which class/setter should be called to enable it?
If it's not directly supported, how to proceed to achieve it?
It's been a while since I last fiddled with GEF.
Does drag and drop not work at all or just in the direction of negative coordinates?
What Layout are you using?
IIRC, there were different layouts with one of them (FreeForm?) supporting negative coordinates, so if you just have trouble with negative coords, you could try to change the Layout.
Here is an example of a Scrolling Graphical editor (the author says ;)) which might give you a good hint.
And there is a class named org.eclipse.gef.ui.parts.ScrollingGraphicalViewer that might help, too.
Only hints, though, since I don't know your code.
First step is to make your canvas scrollable. This is explained in this book, pages 96 - 101.
Assuming you are already drawing your figures on a FigureCanvas and you're using FreeformFigures and FreeformLayer, you can do the following:
Add a MouseMoveListener on your Figure in its EditPart. Each time a drag is detected, in the mouseDragEvent method, reveal your figure with getViewer().reveal(EditPart.this).
This will cause your Figure to always be constantly revealed when it's being dragged.

Can I programmatically find the position of a handle in a JTree row?

Can I programmatically find the position of a handle in a JTree row?
By the handle I mean that little knob which, if single-clicked, expands/collapse its corresponding JTree row.
I'm using the AWT Robot and trying to point the mouse on that handle.
As it is controlled by the tree's UI delegate, typically a subclass of BasicTreeUI, the geometry varies from one L&F to the next. Absent a more general approach, you may be able to test/demonstrate the required functionality using some combination of the programatic navigation methods.
setRootVisible()
expandRow()
setSelectedValue()
setSelectionPath()
scrollPathToVisible()
scrollRowToVisible()

Design for TreeCellRenderer

I have been looking into JTree and TreeCellRenderer. It seems in general, the application (with one JTree) has only one instance of TreeCellRenderer. The application makes multiple calls to TreeCellRenderer's getTreeCellRendererComponent method to decide how each TreeCell is drawn, and such call are made in many occasions (when a cell is selected, deselected, move over, when scrolling, etc.). Why did they decide to do that instead of having multiple instances of TreeCellRenderer, each responsible for one cell??
I am trying to make a JTree where each cell contains a checkbox. The checkbox can be checked/unchecked by the user. Then, the TreeNode userObject's values are set base on the state of these checkboxes. But, from the current JTree design this is impossible - since there is only one instance of JCheckBox, and is only used to show how the Cell looks like (you can't really check it). In some sense I want to separate selection of the TreeCell and the checking of the boxes.
I have some workarounds (implementing MouseAdapter and checking if the mouse click is close by where the checkbox is rendered, then emulate a check on the box by changing its appearence in TreeCellRenderer), but still I want to know if this can be done more directly. Thanks!
Why did they decide to do that instead of having multiple instances of TreeCellRenderer, each responsible for one cell?
This is a nice example of the flyweight pattern.
For a check box tree, I like org.netbeans.swing.outline.Outline, mentioned here, but other examples are available.
Addendum: Reading your question more closely, you ask:
In some sense I want to separate selection of the TreeCell and the checking of the boxes.
This is the correct instinct: The data (checked or unchecked) should be stored in the model (TreeModel), not the view (JCheckBox). The example uses instances of CheckBoxNode in it's (implicit) model, accordingly.

What is the best way to manage application screens in SWT?

I'm creating a standalone SWT desktop application that has around 10 different screens (few wizards, help, forms, etc). Some elements on screen don't change at all (like header, background, etc) and there is a working area that changes depending on what is clicked, etc.
What is the best way to manage application screens? Do I need to create all screen at startup and then show/hide them depending on what is clicked? Or do I need to create those screens dynamically?
Also, I couldn't find any way to show/hide a Composite, do I need to dispose it and then create again?
What is the best practice? I'm new to SWT developing outside of Eclipse so any help would be beneficial.
Deciding whether to create screens up front or creating them the first time they need to be displayed is a decision that needs to be made on a per application basis. If there is a good chance that all the screens are going to need to be used on a particular application run and the number of screens is low (10 screens is relatively low) then you may want to create them at application startup so the UI is snappier once the application loads.
If you use bindings then you may need to come up with a dispose strategy (even if you only dispose the bindings) so you don't have too many events flying around.
Control has a setVisible(boolean) method (and Composite inherits from Control) which you can use to show and hide a component. Note this will only prevent the composite from being shown on the screen, the layout manager will still allocate a blank space for it. Many SWT layouts have a way to exclude a control from the layout which will get rid of the blank space. For example if you are using GridLayout then you would set the exclude variable on you GridData object to true when you hide that control.
Another option is to use StackLayout. This lets you stack a bunch of Composites on top of each other and then choose which on is on top. This might be a good fit for you if you have static areas plus a working area like you described. I would put the header, footer, and an empty composite with a StackLayout in a class file. I would then put each screen that will be displayed in the working area in their own classes. You can either have these screen classes extend Composite and then set up themselves in the constructor or you can use a factory method to setup the screen. Either one is a common and acceptable practice and comes down to a matter of taste.

"Fixing" the first few columns in an SWT table to prevent them from scrolling horizontally

We have implemented a table-based editor with an SWT tree table. It pretty much does what we want it to, except that we can't find a way to ensure that the first few columns remain at their position when the user scrolls horizontally (so that one can identify the row being edited).
There are a number of third-party table controls in various degrees of being incomplete or abandoned, and a snippet that shows how to use two tables (which get out of sync when they're being scrolled vertically).
What's the best way to solve this?
This 'official' SWT snippet does what you want to do, at least on my machine - it does not get out of sync on vertical scroll. But the price is a second scrollbar - way ugly. To prevent this, you can add the style SWT.NO_SCROLL in the constructor of the left table.
To improve the thing you will have to add a Listener on SWT.Traverse to both Tables, which syncs them if the user navigated using keys, something like this:
leftTable.addListener(SWT.Traverse, new Listener() {
public void handleEvent( Event event ) {
rightTable.setTopIndex(leftTable.getTopIndex());
}
});
I wouldn't go with another Table implementation, since you lose the biggest advantage you have with SWT: using a native widget, which looks and feels 'right' in each OS. If you want to do that anyway, Grid from the Nebula project is much more mature than the alpha tag implies. Don't know if it can do what you want, though.
the "syncing problem" only appears on MacOs based SWT. If your target platform is windows you should have no problem with the given SWT-Snippet. There will be more listeners to register on both tables to synchronise all occuring events (collapse, expand, mouse scroll, etc.)

Categories