Java Look and Feel (L&F)

Java Look and Feel (L&F)

There is a lot of possibilities for LaFs :

  • The native for your system
  • The nimbus LaF
  • Web LaF
  • The substance project (forked into the Insubstantial project)
  • Napkin LaF
  • Synthetica
  • Quaqua (looks like aqua from MacOS X)
  • Seaglass
  • JGoodies
  • Liquidlnf
  • The Alloy Look and Feel
  • PgsLookAndFeel
  • JTatoo
  • Jide look and feel
  • etc.


Resources :

  • Best Java Swing Look and Feel Themes | Top 10 (A lot of the preview images on this page are now missing)
  • oracle.com - Modifying the Look and Feel
  • wikipedia.org - Pluggable look and feel
  • Java2s.com - Look and feel

Related topics :

  • Java gui look and feel changes
  • Open source laf[look n feel] for java swing application

Java: Look and Feel

I am using Netbeans on a Windows machine, what happens is that if I
run the main java file the look and feel I get is different than in
the case I run the whole program.

When you run a Swing application the default Look and Feel is set to a cross-platform L&F also called Metal. On the other hand when you create a new JFrame from NetBeans New file wizard it also includes a main method just for test purposes, making developers able to "run" the top-level container. Within this main method the Look and Feel is set to Nimbus as you have included in your Update 1.

This is well explained in this Q&A: How can I change the default look and feel of Jframe? (Not theme of Netbeans). As stated there you can modify the template associated to JFrame form to set the L&F you wish. However be aware of this line:

A Java application only needs one main class so this test-only main
methods should be deleted when you will deploy your application. [...]
the L&F should be established only once at the start-up, not in every
top-level container (JFrame, JDialog...).

You also might to take a look to Programatically Setting the Look and Feel of How to Set the Look and Feel article.

Edit

I just did not understand one thing which test-only main methods do i
need to delete and if i delete them how will my prg run properly?

A Java application must have only one main method that inits the execution. The class which has this main method is defined within MANIFEST.MF file when you deploy your JAR. So, having a main method in each top-level container (JFrame or JDialog) is not needed and it's not a good practice.

However sometimes you don't want to run the whole application to test how a particular frame/dialog works. That's why NetBeans includes this main method on JFrame or JDialog creation. But as stated above when you will deploy your JAR you should delete those "extra" main methods.

and yah, in that you have given how to do it when i create new
jframes, but i already have 20s of them

A Swing application tipically has a single JFrame and multiple JDialog's. Take a look to this topic for further details: The Use of Multiple JFrames, Good/Bad Practice?

And anyways it is nimbus in there and it is what i want, but that is
not what is opening

You just need to programatically set the L&F to Nimbus in your main class (the one that is executed when you run the whole application). You can copy-paste the code you've included in your Update 1 there.

Edit 2

When you create a new project in NetBeans it ask you for create a main class too. Let's say I create a new project called Test, it will ask me for create a main class like this:

Sample Image

This generated Test class will have the main method that triggers the application execution:

Sample Image

Within this main method you have to put the code you've included in your Update 1:

public class Test {

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
try {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
} catch (ClassNotFoundException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnsupportedLookAndFeelException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
});
}

}

Then when you run your application the L&F will be set to Nimbus overriding the default cross-platform L&F. Henceforth all created Swing components will have Nimbus as L&F.

Note: The reason of SwingUtilities.invokeLater() call is explained in Initial Threads article.

How to change the look and feel of a single part of a java program

All that is needed is to change the UIManager while creating the JFileChooser Object, then setting it back to what it was previously, alternatively you could just catch Exception, but that is bad practice.

public void stuff(){
JFileChooser chooser = null;
LookAndFeel previousLF = UIManager.getLookAndFeel();
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
chooser = new JFileChooser();
UIManager.setLookAndFeel(previousLF);
} catch (IllegalAccessException | UnsupportedLookAndFeelException | InstantiationException | ClassNotFoundException e) {}
//Add whatever other settings you want to the method
chooser.showOpenDialog(frame);
}

Changing look and feel of specific window

As a general rule it is not a good idea to mix LAF's. This problem is an example of why.

There is something in the Nimbus LAF that may not allow you to do this. Run the code as is. It will set the LAF to the System LAF and then reset the LAF. In my case the system is Windows and it appear to work fine. Then change the code to use the Nimbus LAF. It appears to work initially, but try resizing the frame and you get the errors. So it would appear that the Nimbus frame does not work completely independent of the current LAF.

import java.awt.*;
import java.awt.event.*;
import java.awt.GridBagLayout;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;

public class GUI2 extends JFrame {
private static LookAndFeel originalLookAndFeel = UIManager.getLookAndFeel();
/*
private GridBagLayout gridBag = new GridBagLayout();
private JTabbedPane tabs = new JTabbedPane();
private JPanel selectionPanel = new JPanel(gridBag);
private JPanel infoPanel = new JPanel(gridBag);
private JPanel settingsPanel = new JPanel(gridBag);
*/
private GridBagLayout gridBag;
private JTabbedPane tabs;
private JPanel selectionPanel;
private JPanel infoPanel;
private JPanel settingsPanel;

public GUI2() {
System.out.println("At start, look and feel is " + UIManager.getLookAndFeel().getName());
try {
// setNimbusLookAndFeel();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Look and feel changed to " + UIManager.getLookAndFeel().getName()
+ " before component creation");

gridBag = new GridBagLayout();
setLayout(gridBag);
tabs = new JTabbedPane();
selectionPanel = new JPanel(gridBag);
infoPanel = new JPanel(gridBag);
settingsPanel = new JPanel(gridBag);

setUpComponents();
addComponents();
setWindowProperties();

Action reset = new AbstractAction()
{
public void actionPerformed(ActionEvent ae)
{
try {
System.out.println("Setting to original, which is " + originalLookAndFeel.getName());
UIManager.setLookAndFeel(originalLookAndFeel);
System.out.println("Current look and feel is " + UIManager.getLookAndFeel().getName());
} catch (UnsupportedLookAndFeelException e) {
//e.printStackTrace();
System.out.println(e.getMessage());
}

}
};

Timer timer = new Timer(500, reset);
timer.setRepeats(false);
timer.start();
}

private void setWindowProperties() {
// setLayout(gridBag);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("fAmos Quester");
// setResizable(false);
pack();
setLocationRelativeTo(null);
}

private void setNimbusLookAndFeel() {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
}
}
} catch (Exception e) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e2) {
}
}
}

public void setUpComponents() {
tabs.addTab("Quest selection", selectionPanel);
tabs.addTab("Quest info", infoPanel);
tabs.addTab("Settings", settingsPanel);

selectionPanel.setPreferredSize(new Dimension(650, 500));
infoPanel.setPreferredSize(new Dimension(650, 500));
settingsPanel.setPreferredSize(new Dimension(650, 500));
}

private void addComponents() {
add(tabs);
}

public static void main(String[] args) {
new GUI2().setVisible(true);
}
}

Maybe a solution would be to create the component using the Nimbus LAF as is done above. However, don't reset the LAF until the frame is deactivated. Then you could try resetting the LAF every time the frame is activated. You would use a WindowListener to handle the activated/deactivated events.

Is it possible to set different look and feel for different components?

I have a number of components on panel and I want to apply different look and feel to different components. Is it possible?

Yes is possible, don't do it, because most of Look and Feel have got different

  • Color, Font, Foreground, Background

  • Size or PreferredSize on the screen

  • use another methods from API for LayoutManager

  • implemented various methods in the JCOmponents APIs e.g. Color, Font, Foreground, Background

  • simple answer ---> is possible to create a awfull mess on the screeen

I'd suggest to use todays Java Look and Feels, most of them have various colors themes, part of them seperates themes and with option to change Colors themes, then there you can mixing built-in themes or/and with Color themes for each of JComponents

I think that with success you can to set Color, Font, Foreground, Background only, Look and Feels required basic knowledge about how JComponents and/with LayoutManagers together works

Is there a java look and feel based on the flat design concept?

There isn't a pre-built one, and UIs in Swing are...well...one of the most painful experiences in development I've ever had. UI is so inherently platform-specific that cross-platform UIs are a pipe dream for any semi-complex UI. The only place it works is if your UI is basically a menu bar and a surface onto which you draw your own UI.

That said, I think long-term you're probably looking into custom UI and widget work on some level, and though that would be a lot of custom UI tool work, the tradeoff is that at least you would control the UI from that point forward, could keep it up-to-date as you go along, and you wouldn't have to worry as much about what Java decides is good UI design.

Some possible options, none of which are going to be without major pain:

  1. Choose one of the two built-in L&F options, or set it to be the platform default (your app looks like the native platform), though you will have to debug the app on every platform separately to make sure the UI works consistently. At least with this option, if you set it to use the platform default, the app will look approximately like a native app on whatever OS it's on.
  2. Look into SWT - probably not worth it in the long run - you're just trading one set of less-than-idea situations for another, I think, but good to at least be educated about your options.
  3. Style the L&F with CSS - never tried this myself - but maybe worth a look. But personally, I would avoid investing any more time binding your application to Swing if you can avoid it. It's just one of those atrocious desktop experiences, as you've seen.
  4. Deliver your app as a web application, which I'm sure is a major re-architecting, and just have users access it through a browser. I realize that this is probably the "nuclear option", and totally unrealistic, but just throwing it out there.
  5. Suck it up and let your app continue to look like crap. There are worse fates in the world.


Related Topics



Leave a reply



Submit