Java: Look and Feel
Asked Answered
H

6

10

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. Meaning if I do this: enter image description here

I get

enter image description here

But if I do this

enter image description here

I get enter image description here

Did you see the difference in the look and feel of both the java outputs? Why is it there? I want that when I export it to Jar it should open like the 1st case, nice looking buttons. How?

Update 1: I found the following code in the starting of my main:

public static void main(String args[]) {
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(FormTTS.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(FormTTS.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(FormTTS.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(FormTTS.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }

    //Some code here...
}

So it should set the nimbus look and feel but the problem is that when I open the jar the Nimbus look and feel is not there

Update 2: A look of my Navigator

enter image description here

Update 3: File Structure

enter image description here

Hedgehop answered 31/3, 2014 at 9:47 Comment(10)
Do you change the LAF in your code? If so could you please show it to us.Atony
What about NOTE: Main function doesnt work in JAR!?Nabataean
I have noticed that Java applications (UI) somehow inherits ( if thats the correct word to use here ?) look and feel of your OSDivisible
@ThorstenDittmar That is just a printf I was doing, it is not relatedHedgehop
@MaciejCygan So how to make it use the one I wantHedgehop
@Atony I do not remember as such, I mainly use netbeans only to do all my work. Where will I find that code in my project?Hedgehop
@DakshShah There might be a line like UIManager.setLookAndFeel(...);Atony
@Atony Yah i found that line but why does it not have any effect when i open the jar?Hedgehop
@Daksh Shah never seen that, one potential issue is setting for compile on save in Netbeans, but then this question couldn't be aksed, nor upvotedGondola
@Gondola Sorry, i did not get you :PHedgehop
D
5

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:

enter image description here

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

enter image description here

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.

Damiandamiani answered 31/3, 2014 at 11:25 Comment(13)
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?Hedgehop
and yah, in that you have given how to do it when i create new jframes, but i already have 20s of themHedgehop
And anyways it is nimbus in there and it is what i want, but that is not what is opening :(Hedgehop
Please see my edit :) Let me know if you still have doubts. @DakshShahDamiandamiani
That upd1 code is what i really have still there is the problem , and i have not deleted the other mains as yet cauz i m still in developing stage as well as distribution stage so i do not want to delete the extra mains as of now. But how does that matter? all i am doing is just making a jar and opening it and checking tha laf on the first thing that opens, and also everywhere the laf is nimbus onlyHedgehop
all i am doing is just making a jar and opening it and checking tha laf on the first thing that opens, and also everywhere the laf is nimbus only That's what I mean when I say you need to explicitly set the L&F in the class which inits your application execution (don't know how to put it in other words) because if you don't then the UIManager class will load Metal L&F by default which is illustrated in your 3rd and 4th picutures. @DakshShahDamiandamiani
'need to explicitly set the L&F in the class which inits your application execution' How to achieve this? Delete other mains?Hedgehop
How is your main class called? The one that starts your application's execution? I guess it also opens the first frame you show to the users. @DakshShahDamiandamiani
Man i have no idea what you are talking about! Forgive me I am just 15 yrs old + new to java. Could you pls care 2 elaborate?Hedgehop
No need to apologize, we all started programming once and know it's difficult when we're beginners. Please see my Edit 2. Hope you get it now, but don't hesitate in ask for clarification if needed :) @DakshShahDamiandamiani
See update 3 once, in that i think that the main class would be FreeTTS.java, so i changed it into this: pastebin.com/EH1kCUKS Still the same problem. If you free could u pls look at it once from teamviewer?(teamviewer is a software from which u will b able to see my screen and use ur mouse n keyboard on it, as if you were literaly operating my machine)Hedgehop
You're welcome! :D I think you've figured out that you had to add those lines but not replace what you already have and it's working now. Glad to help! @DakshShahDamiandamiani
I figured out that it had to go in freetts and not the other one :P :DHedgehop
S
3

Possible problem.

If you have a main class that you launch your application from, say a Main class. If the look and feel is not set in that class, the result will be what you are experiencing.

Say you have Main where you launch MyFrame from. (forgive the second main method, this is only for example, as in the OP's case)

public class Main {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new MyFrame().setVisible(true);
            }
        });
    }
}

public class MyFrame extends JFrame {
    public static void main(String[] args) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
         ...

    }

You will get the result (even though the look and feel is set the MyFrame:

enter image description here


If I just run MyFrame I get:

enter image description here


So if you add the look and feel to you Main, it will get this result

public class Main {
    public static void main(String[] args) {
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
         ...

        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new MyFrame().setVisible(true);
            }
        });
    }
}

enter image description here

Spillage answered 31/3, 2014 at 12:37 Comment(1)
please see this once: #21697841Hedgehop
A
2

I would recommend to try to change your LAF in your main method, like:

public static void main(String[] args){
  Frame f; // Your (J)Frame or GUI-Class.
  // some code here...
  try{
    UIManager.setLookAndFeel(new NimbusLookAndFeel()) // Because it seems to be Nimbus what you want.
    SwingUtilities.updateComponentTreeUI(f); // To refresh your GUI
  }catch(Exception e){
    // Do whatever you want if a problem occurs like LAF not supported.
  }
}

Or you could do it without SwingUtilities.updateComponentTreeUI(f); if you call

f.setVisible(true);

after the change of your LAF.

Atony answered 31/3, 2014 at 10:8 Comment(16)
@DakshShah Is your Frame set to be visible before or after your change of LAF?Atony
I would suggest to try adding following to the end of your main: try{ SwingUtilities.updateComponentTreeUI(f); }catch(Exception e){/*Do what you want*/}Atony
Exactly this code at the end of main? and should i leave the one at the start as it is?Hedgehop
Just take the try-catch from the comment and paste it to the end of your main, so yes. But alter the f to your variable containing your Frame.Atony
i do not know the name, can you figure it out from the code i have given?Hedgehop
@DakshShah No sorry, your given code does not contain it.Atony
So how do i figure it out? i tried 'this' but it does not workHedgehop
Look through your main for keywords like JFrame, Frame or Window .Atony
My main code: pastebin.com/avfJ9NHT and a view of my navigator is in upd2 in quesHedgehop
So out of this code take the line new FormTTS().setVisible(true); and change it to FormTTS f = new FormTTS(); /* HERE add the code I have given you before the try-catch*/f.setVisible(f);Atony
Now I am confused.. But I found this in your code System.out.println("NOTE: Main function doesnt work in JAR!"); That is somehow strange...Atony
That is just a line I had added earlier as I was facing some problems that I added some code in the main but that was not coming up in opening of jar, i do not remember clearly but that is why i had added it, but how is it revelant?Hedgehop
@DakshShah The last idea I have is to drag the try-cazch block from the comment above (try{ SwingUtilities.updateComponentTreeUI(f); }catch(Exception e){/*Do what you want*/}) to the constructor of your FormTTS class.Atony
it gives an error saying cannot find symbol. symbol: variable fHedgehop
Do you want to my pc and see it (via teamviewer) and try it for yourself?Hedgehop
Oh that I should have said. Then you have to change the f to thisAtony
D
2

Maybe you can try these ones ?

UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); 
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

edit:

UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
Divisible answered 31/3, 2014 at 10:24 Comment(10)
Where should i add these?Hedgehop
in your main class, try one of these two. Remove your for loop in your try-catch, and just add one of the lines above. And see what the output is. Ps make sure you compile new jar after any changesDivisible
So i have to try these one by one? and in the try block right? I have to leave the ctach block as is?Hedgehop
Both the lines give me the same bad looking UIHedgehop
try the aboves aswell. Also did you recompile the jar file ?Divisible
Yes i did recompile the jar, wait lemme try these and yah there must not be problem with netbeans 8 as this was there earlier tooHedgehop
yes i know, just checked - nimbus was introduced in java 6Divisible
Still no luck both the things give the same outputHedgehop
Gave you upvote for question as i am also interested to see the answer to this one, as i don't have a clue hmmDivisible
Thanks for helping (I upvoted your answer as you tried to help me a lot ;))Hedgehop
E
2

If the app. is running in Java 1.6 on the system (outside the IDE) it would not have access to Nimbus (scroll to the bottom for the @since element). Nimbus only became available in 1.7.

Episternum answered 31/3, 2014 at 11:38 Comment(3)
I checked on cmd java -version it told me that the version of java i am running on is 1.7.0_51-b13Hedgehop
again this isn't possible, again 1) whats setting for compile on save (run project is from compiled Jar, that doesn't contains any changes), 2) eeeeeerhgt there is source/binary format, whats JDK is there, but by default run project and run file uses the same settting, everything is from project propertiesGondola
Actually @Andrew, Nimbus according to Oracle docs became available in 1.6 ?Divisible
I
1

to determine the look and feel you can read the current used Look And Feel with UIManager.getSystemLookAndFeelClassName()

If you know your preferred look and feel you can set it with UIManager.setLookAndFeel(look) (prior creating your GUI elements!)

But remember: you should check if this look and feel is available (prior setting it on another operating system with other look and feels installed)

Further information:

EDIT: To determine installed look and feels:

UIManager.LookAndFeelInfo plaf[] = UIManager.getInstalledLookAndFeels();
Intorsion answered 31/3, 2014 at 9:54 Comment(3)
Can you tell me which look and feel is the first one? and how to set that now not Prior But after creating evrythingHedgehop
Just add the code System.out.println(UIManager.getSystemLookAndFeelClassName()); to your code and execute it - it will be displayed on the console and you are fine to go. The UIManager.setLookAndFeel(..) can be called in the main method before you create your windows - this setting is then set for the whole runtimeIntorsion
@AndrewThompson Y do i need to check the installed ones? because nimbus is running on my machine in some case so it must be installed :PHedgehop

© 2022 - 2024 — McMap. All rights reserved.