How to make part tab inactive (disable) in Eclipse RCP? - java

I have partStack with a lot of parts in tabs. I'd like to know how can I make tabs inactive when I don't need them and active when I need.
By inactive I mean tab which is visible but I can't click on it and it is like disable function (for example text on it is gray instead of black).
I use an e4 RCP (with Application.e4xmi).
Thanks for help.

Handling of the selection of parts in a part stack is handled by the part stack renderer org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer which basically uses a CTabFolder.
You can use a renderer factory to override the stack renderer see here
You can extend the existing StackRenderer class and override methods to change its behavior. In this case probably the hookControllerLogic method. But you are going to have to study the source carefully to see what needs to be done.

You can try using using EPartService to manipulate a part but I think active/inactive part just means visible or not.
Or you can just loop and disable all swt controls yourself manually 😄

Use Renderer factory to override the stack renderer.
Extend the existing StackRenderer class and override hookControllerLogic() or activate() methods with empty implementation.
Example-
public class MyE4Part extends ContributedPartRenderer {
/*
* Don't activate the Part on part selection. part should not be gain the focus on any
* selection on part .
*/
#Override
public void hookControllerLogic( MUIElement me )
{
//Don't do anything.
//super.hookControllerLogic( me );
}
}

Related

Making several synth LookAndFeels coexist at the same time in a java swing application

I am working on a java swing application using synth Look and Feel.
There are already styles for every possible swing component
I must change the whole application's LookAndFeel, redefining different styles for every possible swing component.
I am now working on a sandbox, launched outside of the application. The sandbox loads my new set of styles, while the application still loads the old ones. No problems for now
However, I must then integrate it 'progressively' in the application. Meaning that in the same java application, some HMIs must use the old set of styles, while some must use the new ones
The difficulty being that each set of styles define synth "region" styles that automatically apply to the corresponding component, and I don't know how deal with several region styles that correspond to the same component type
Anybody has an idea of how I can do this ?
I saw that in swing's UIManager, one can change the LookAndFeel, but it then changes for the whole application
Only workaround I saw on the internet was to change the LookAndFeel before instanciating a Component, then change it back, which looks like an awful solution
Thanks in advance
Only workaround I saw on the internet was to change the LookAndFeel before instanciating a Component, then change it back, which looks like an awful solution
This is a very very very x 10 times bad solution.
I'm the author of the material-ui-swing and with the material style, you need to work with this concept of different style, and this is the main focus that I had during my development with the library, also because at the same time we integrate the library in one of the famous swing application called JMars where we need to respect a design system given by the UX team.
To make an example, material-ui-swing give two types of API:
one it the Material Theme System to define in a declarative way the theme around the App, and
the second is to give the lower-level API to implement the UI component with a different style.
In your case, we need the second power of material-ui-swing which is the lower-level API, and I will add an example also reported inside the repository online at the following link, and the complete doc is available here
A possible example of customization is the following on
public class ContainedButtonUI extends MaterialButtonUI {
//The propriety order inside the method installUI is important
//because some propriety should be override
#Override
public void installUI(JComponent c) {
super.mouseHoverEnabled = false;
super.installUI(c);
super.mouseHoverEnabled = true;
super.colorMouseHoverNormalButton = MaterialColors.PURPLE_500;
super.background = MaterialColors.PURPLE_700;
c.setBackground(super.background);
if(super.mouseHoverEnabled){
c.addMouseListener(
MaterialUIMovement.getMovement(c, this.colorMouseHoverNormalButton)
);
}
//If you want use this style also for Default button
// super.defaultBackground = MaterialColors.PURPLE_700;
//super.colorMouseHoverDefaultButton = MaterialColors.PURPLE_500;
super.borderEnabled = false;
}
After that to keep all your app architecture clean you can add the following specialization of JButton
/** #author https://github.com/vincenzopalazzo */
public class ContainedButton extends JButton {
public ContainedButton() {}
public ContainedButton(Icon icon) {
super(icon);
}
public ContainedButton(String text) {
super(text);
}
public ContainedButton(Action a) {
super(a);
}
public ContainedButton(String text, Icon icon) {
super(text, icon);
}
#Override
protected void init(String text, Icon icon) {
super.init(text, icon);
// When you don't want anymore you just delete the
// following line
setUI(new ContainedButtonUI());
}
Of curse, maybe the library can not help you in all your component styles, but nobody said that the library can not evolve with the help of the community.
A not complete description of components can be found here
Thank you all for your answers and sorry for my lack of reactivity during the holidays
I think I found a solution, which is not exactly what I asked for but answers my problem :
I will not make several LookAndFeels coexist.
Instead, I will load all styles, new and old, in the same LookAndFeel, and use different setName() for new and old components
For region styles (which was the problematic here), I will make a custom SynthStyleFactory which will redirect to the correct region style
Once all HMIs are migrated, I will delete the old styles and the custom factory which won't be needed anymore

Create a MultipageEditor for XML

I am working on an eclipse Plugin, and I would like to use an Editor, set some listeners on the current page(good terminology?), and remove these listeners when the user switches on another page (basically, the user is editing several files, as you could do with the default JAVA editor).
For the moment I have written a class extending StructuredTextEditor. The behavior of the plugin was the one expected, but when I try to work on several files, many problems occur. The main problem, according to me, is that I am not able to get notified when the user opens another page.
I read (and tested) a few things about MultiPageEditor, but it seems like it doesn't integrate an XML editor as default editor. How should I proceed in order to get a MultiPageEditor, with XML syntax coloring, and get notified when the user changes the current page to adjust my listeners ?
Thanks for reading.
the code is not perfect but at least you will have an example of a MultiPageEditor integrating an XMLEditor: https://github.com/fusesource/fuseide/blob/8.0.0.Beta2/editor/plugins/org.fusesource.ide.camel.editor/src/org/fusesource/ide/camel/editor/CamelEditor.java
The idea is to call addPage(new StructuredTextEditor()) inside createPages() method.
regards,
In your editor you can listen to selection changes in the editor text using:
getSelectionProvider().addSelectionChangedListener(listener);
where listener implements ISelectionChangedListener.
This applies to any editor derived from AbstractTextEditor (which includes StructuredTextEditor.
You need to do this fairly late in the editor creation. In the createPartControl method works:
#Override
public void createPartControl(final Composite parent)
{
super.createPartControl(parent);
getSelectionProvider().addSelectionChangedListener(listener);
}

Best way to use additional components in wicket behaviors

I've create a new subclass of a wicket behavior which can be attached to form components. If a validation error occurs for such a component, the behaviors shows/hides a specific error label. My code looks similar to this:
public MyErrorBehavior(Component errorComponent) {
// show/hide errorComponent within onUpdate() or
// onError() based on getComponent().isValid()
}
My questions is: Is it ok to pass a component to a behaviors constructor?
Cheers,
Andreas
Yes, a behavior is allowed to keep references to components, please see EqualInputValidator as an example.
Take care if you remove these components from your component tree: you should remove the behavior too, otherwise you'll have dangling references of components which are no longer detached.
There is no need to keep a reference to the component because Wicket will pass the component in the callback method, e.g.
#Override
public void onComponentTag(Component component, ComponentTag tag)
{
// cast component to FormComponent and make the check here
}
This way there is no need to clean up and you can add the same Behavior instance to more than one (Form)Component.

actionCommand in Swing Action seems to be dependent of I18N

Here on Stack Overflow I read a lot about using Swing Actions rather than ActionListeners, so I started to use them within the application's menu.
Everything worked out nice until I introduces I18N, only to find out that the actionCommand of the MenuItem changes accordingly to the language.
Here is what I do:
class ExitAction extends AbstractAction {
public void init() {
putValue(Action.NAME, messageSource.getMessage("app.gui.action.exitApplication"));
}
}
My guess is, that I did understand something wrong and this is not the way to do what I want to do.
Can you please help me?
Two things...
Firstly, NAME affects the text of button, but if not specified, will also set the actionCommand. Property. Instead I think you're after the ACTION_COMMAND_KEY property
Secondly, there should actually be little need for it, as the Action is self contained, hat is, it is it's own ActionListener, so when actionPerformed is called on your Action, you are guaranteed the association

How to not render a component in wicket

I have table of player in html: [table]
How I can hide or not render this table when it is empty? I try to add if conditional in java code and add this table to the page only if there is some value but then wicket throws an exception that he cant find component with this id. So how I can do this?
It throws the exception because the html markup expects the component to exist. Ie you must add it.
If it's an entire panel you want to hide then using EmptyPanel is the will hide the entire panel.
You can also use component.setVisible(false) to hide it if its only one component in the panel.
You can override the isVisible() function and return false if no date is available. But, this function will be called a few times, so if determining if data is available(like, hitting a database) you can call the setVisible(boolean) function.
Another option is to exchange the Repeater with an EmptyPanel if no data is available.
You can use the same condition you already use in java, but instead of not adding the table to the page, use table.setVisible(false).
Another way to do it would be to override the setVisible() and isVisible() methods, but i don't think it is recommended (see here)
Hope this helps
As the other users have pointed out, overriding isVisible() is not recommended because this function is called many times before component is rendered.
You should instead override onConfigure() and put inside it the code that decides if your table must be visible or not. onConfigure() is called just once per request.

Categories