1
votes

I'm facing a problem when applying a native Look & Feel to my JFrame, all text (except HTML formatted JLabel) have an ugly bold font.

The very simple UI in the following code sum up all the differences I can see with this L&F :

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;

public class HelloWorld extends JFrame {
    public HelloWorld() {
        Box b = Box.createVerticalBox();

        // Labels
        JLabel bold = new JLabel("I'm bold !");
        JLabel notBold = new JLabel("<html><em>I'm not bold !</em></html>");
        b.add(bold);
        b.add(notBold);

        // Scrollbars example
        JPanel scrollViewPort = new JPanel();
        scrollViewPort.setPreferredSize(new Dimension(400, 400));

        JScrollPane scroll = new JScrollPane(scrollViewPort);
        b.add(scroll);

        add(b, BorderLayout.CENTER);

        // Bold menu
        JMenuBar menubar = new JMenuBar();
        JMenu menu = new JMenu("Menu");
        JMenuItem item = new JMenuItem("Item");
        menu.add(item);
        menubar.add(menu);

        setJMenuBar(menubar);
        setPreferredSize(new Dimension(200, 200));
        pack();
    }

    public static void setNativeLAF() {
        // Native L&F
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            System.out.println("Unable to set native look and feel: " + e);
        }
    }

    public static void main(String[] args) {
        // setNativeLAF();

        HelloWorld app = new HelloWorld();
        app.setVisible(true);
    }
}

See the difference :

with native L&F (GTK+)

with native L&F (GTK+)

with Metal L&F

with Metal L&F

by commenting out the setNativeLAF() call.

I'm applying the native look and feel right when my application starts, before any window appears. The UIManager gives me GTK+ (com.sun.java.swing.plaf.gtk.GTKLookAndFeel) as the native look and feel, which is ok since i'm using a Gnome 3 desktop.

I have three problems with this right now :

  1. The GTK+ look and feel doesn't looks like the GTK theme (see the scrollbars)
  2. The JMenuBar seems disabled (not the case with the Metal L&F)
  3. The font is bold ! (same problem with Metal L&F, but fixable)

Any help or explanation about why the GTK+ L&F does that on my system whould be appreciated.

Edit: Here is what a "classic" application looks like on my system in eclipse.

eclipse

1
As for the eclipse screenshot, what 'labels'? I see a title, menus, tabs, icons, buttons. Where are the labels? What text do they contain, and why do I need to ask you? Your GUI - same basic questions. Are you referring to the "Click on a.." or "10x10 blocks"? Also, for better help sooner, post an SSCCE. And by that I mean code added to your question, as opposed to a screenshot of it in your IDE. ;)Andrew Thompson
please whats happens when you set JFrame.setDefaultLookAndFeelDecorated(true); is there any difference, as Andrew mentioned your 2nd. screenshot is shot to the dark, on ecplipse sited is described used look and feel for concrete native osmKorbel
Since I cannot put more than two links in my question for spam previention, here is the link to show what a "classic" application looks like on my system : eclipse, which correctly use the GTK3 system themestrnk

1 Answers

3
votes

I see several things worth mentioning:

  1. You can apply a derived font to a label, as shown below.

  2. The relevant specification for HTML in a component sys "EM basic emphasis typically rendered in an italic font".

  3. See also Initial Threads.

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.Box;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class HelloWorld extends JFrame {

    public HelloWorld() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        Box b = Box.createVerticalBox();

        // Labels
        JLabel bold = new JLabel("I'm bold !");
        bold.setFont(bold.getFont().deriveFont(Font.BOLD));
        JLabel notBold = new JLabel("<html><em>I'm not bold !</em></html>");
        b.add(bold);
        b.add(notBold);

        // Scrollbars example
        JPanel scrollViewPort = new JPanel();
        scrollViewPort.setPreferredSize(new Dimension(400, 200));
        JScrollPane scroll = new JScrollPane(scrollViewPort);
        b.add(scroll);
        add(b, BorderLayout.CENTER);

        // Bold menu
        JMenuBar menubar = new JMenuBar();
        JMenu menu = new JMenu("Menu");
        JMenuItem item = new JMenuItem("Item");
        menu.add(item);
        menubar.add(menu);
        setJMenuBar(menubar);

        pack();
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                HelloWorld app = new HelloWorld();
                app.setVisible(true);
            }
        });
    }
}