I've written an Eclipse plugin that adds a second SourceViewer beside the standard Python editor window. I can detect when either window is scrolled vertically as follows:
displayViewer = new SourceViewer(liveDisplay, ruler, styles);
displayViewer.addViewportListener(new IViewportListener() {
#Override
public void viewportChanged(int verticalOffset) {
// respond to scroll event
}
});
Is there any equivalent to detect horizontal scrolling? I tried adding a control listener, but that doesn't detect scroll events.
Related
This is a weird question so I'll make my best to explain myself properly.
What I'd like is to trigger an event when a Tab in a TabPane get clicked, and by "clicked" I mean just clicked, not necessarily selected.
I already tried using the selectedProperty of the Tab, but that does call the event only if the Tab is clicked when it's not selected, not even if it's clicked when it's already selected.
The reason why I'm doing this is that I'm trying to make a collapsible tab pane that hides the content of the TabPane if you click again on the opened tab, I've already wrote the code for collapsing the TabPane and that works but... I have no idea on how to get a click event from the tab header.
I've even looked into TabPane source code too hoping that I could find the tab header container but I didn't find it there.
No need for a completely new skin - we can access the header nodes by lookup. Beware: implies relying on implementation details, which might change across versions.
The (undocumented!) style id to look for is ".tab-container" - that's the only child of the TabHeaderSkin (== region for a single tab header). It contains the label, the close button (if any) and the focus marker. This "skin" keeps a reference to its tab in its properties (undocumented, of course ;)
So the basic approach is to
lookup all tab-containers after the skin is installed
for each, register an appropriate mouse handler on its parent
on the respective mouseEvent, do whatever is needed
Note that the listeners have to be removed/added when the list of tabs is modified (not included in the snippet below).
In example code:
/**
* looks up the styled part of tab header and installs a mouseHandler
* which calls the work load method.
*
* #param tabPane
*/
private void installTabHandlers(TabPane tabPane) {
Set<Node> headers = tabPane.lookupAll(".tab-container");
headers.forEach(node -> {
// implementation detail: header of tabContainer is the TabHeaderSkin
Parent parent = node.getParent();
parent.setOnMouseClicked(ev -> handleHeader(parent));
});
}
/**
* Workload for tab.
* #param tabHeaderSkin
*/
private void handleHeader(Node tabHeaderSkin) {
// implementation detail: skin keeps reference to associated Tab
Tab tab = (Tab) tabHeaderSkin.getProperties().get(Tab.class);
System.out.println("do stuff for tab: " + tab.getText());
}
Is there a way to change the style of a Shell at runtime?
I would like to have a shell not resizable but capable to fill, with its content, the whole screen, when it's in fullscreen. Is there a way to accomplish that?
In other words, when a Shell is not resizable and it has for example a Background Image I get this in full screen :
On the other hand when the Shell is resizable and I go in full screen I get this:
So would like to obtain the second effect but with a not resizable Shell.
Any help would be appreciated.
Following Stefan's comment, I was able to do it listening to the resize event and checking the fullscreen flag, resizing appropriately the shell's size to the monitor size when it's in full screen and to normal size when is not. Here the code that does the trick:
shell.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(Event arg0) {
if (shell.getFullScreen()) {
Rectangle r = getMonitorSize(shell);
shell.setSize(r.width, r.height);
shell.redraw();
} else {
shell.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
shell.redraw();
}
}
});
I have found various solutions on how to add Buttons inside a Tab or overlay on the TabPane, which however did not satisfy me.
What I want is to have a button beside the most right tab, like e.g. my browser offers it:
What I have tried now is instead of adding a Button using the setGraph(Node) on this Tab, I have added a Tab that is treated different if selected.
addTab = new Tab("+");
addTab.setClosable(false);
TabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() {
#Override
public void changed(ObservableValue<? extends Tab> ov, Tab oldValue, Tab newValue) {
if (newValue == addTab) {
groupTabPane.getSelectionModel().select(oldValue);
DO_ADD_TAB();
}
}
});
To keep it the right most Tab I have a listener on the Tablist and always remove / add it again if the list is modified (maybe this can be done more elegantly)
However the problem I face is that the TabPane always needs a selection, if a Tab is present. Therefore on startup DO_ADD_TAB() is always executed. I can work around that using a boolean variable, but then the Tab is selected, and can not be selected again to add a new Tab. TabPane.getSelectionModel().clearSelection() does not work.
Can somebody advise how to add such a button more elegantly or how to make the TabPane accept no Selection if only this one Tab is present?
When I'm setting the button to be disabled using this:
jButton.setEnabled(false);
then there is this visual effect visible on the second element ->
How can I disable the button, but keep the the look of the first element?
how to get rid of visual effect when disabling buttons
Companies spend millions of dollars to develop a UI can is common and can be used by all users.
How is the user suppose to know that the button is disabled if there is no visual indication?
Anyway, (rant finished) you can manually set the disabled icon:
button.setDisabledIcon( button.getIcon());
If you also happen to have text on the button the text will still be disabled so instead of a disabled icon you can use a custom ButtonModel:
button.setModel( new DefaultButtonModel()
{
#Override
public boolean isArmed()
{
return false;
}
#Override
public boolean isPressed()
{
return false;
}
});
I have implemented a JFace Wizard with 2 WizardPages.
By default, the first WizardPage has these 4 Buttons:
Back (disabled)
Next (focused)
Cancel
Finish (disabled)
Now I want to set the default focus on the Cancel Button. How do I do that?
Removing the focus and setting it to some Control of the page's content would also be ok.
I tried setting the focus to a Button in the content layout of the WizardPage, but this only sets me a second focus on the immediateButton. The focus on the Next button is still there, and the Next button reacts to pressing enter, which is what I want to avoid.
#Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
immediateButton.setFocus();
}
}
How can I access the Dialog buttons and change their focus?
The Next button does not actually have focus, rather it is the Shell Default button.
The logic in WizardDialog makes either Next or Finish the default button and there does not seem to be a way to change this.
You may be able to override this by calling getShell().setDefaultButton(button) in your wizard page.
Update: Testing this you can do it in setVisible but you need to use Display.asyncExec to make the code run at the right time:
final Shell shell = getShell();
shell.getDisplay().asyncExec(() -> shell.setDefaultButton(immediateButton));
above is for Java 8, for Java 7 or earlier:
shell.getDisplay().asyncExec(new Runnable()
{
#Override
public void run()
{
shell.setDefaultButton(immediateButton);
}
});