wilbut
wilbut

Reputation: 34

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

Upvotes: 0

Views: 101

Answers (2)

wilbut
wilbut

Reputation: 34

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

Upvotes: 0

vincenzopalazzo
vincenzopalazzo

Reputation: 1645

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

Upvotes: 1

Related Questions