Giter Site home page Giter Site logo

jformdesigner / flatlaf Goto Github PK

View Code? Open in Web Editor NEW
3.1K 40.0 251.0 17.35 MB

FlatLaf - Swing Look and Feel (with Darcula/IntelliJ themes support)

Home Page: https://www.formdev.com/flatlaf/

License: Apache License 2.0

Java 98.18% C++ 1.11% Swift 0.11% Objective-C 0.09% Objective-C++ 0.52%
look-and-feel swing java-swing flatlaf

flatlaf's People

Contributors

abextm avatar basix86 avatar bios-marcel avatar blanco27 avatar chrriis avatar cristatus avatar dar-dev avatar devcharly avatar dj-raven avatar geroyche avatar ingokegel avatar jesusaplsoft avatar jformdesigner avatar johnplatts avatar julien-fischer avatar kingthorin avatar klemendev avatar matt-pan avatar nroduit avatar plyha avatar sbodmer avatar schiopumatei avatar shadelessfox avatar syoon2 avatar uwemock avatar valerakostin avatar weisj avatar windchild292 avatar wisser avatar xdudssx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flatlaf's Issues

Wrong rollover color for buttons with a background color property

Using 0.16 and FlatDarculaLaf, buttons have a grey color when the mouse is over them, which is OK when there is no background color set for the button, but looks quite strange (sudden large color changes) when there is an explicitly set background color.

Instead the rollover color should be derived from the background color (if there is one), for example using a lighter or darker version of it (or leaving it as it is). java.awt.Color has brighter() and darker() methods for easily deriving such colors at runtime.

import com.formdev.flatlaf.FlatDarculaLaf;

import javax.swing.*;
import java.awt.Color;
import java.awt.FlowLayout;

public class ColoredButtonProblem {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> buildGUI());
    }

    private static void buildGUI() {
        try {
//            UIManager.setLookAndFeel(new javax.swing.plaf.nimbus.NimbusLookAndFeel());
            UIManager.setLookAndFeel(new FlatDarculaLaf());
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.setLayout(new FlowLayout());

        JButton blueButton = new JButton("Blue");
        blueButton.setBackground(new Color(13, 67, 159));
        f.add(blueButton);

        JButton uncoloredButton = new JButton("No color, no problem");
        f.add(uncoloredButton);

        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

Submenu rendering is jittery

This is not seen in the demo app since it doesn't have secondary level menus.

You'll need a couple of primary items that open secondary content, each one with different texts and icons. As you roll over the primary items, the newly opened secondary menu shows the old content (from the previously opened secondary menu) for a split second, and then shows the correct content.

Showing ScrollBar < and > buttons

Hi, is there a way or option to have the scrollbar prev/next button showing ?

I have a heavily customized JTable where in that case the prev < and > next button of the scrollbar were used to move by a specific amount.

Question: is close button for JTabbedPane available?

As the title says I'm wondering if there is a function or property to display a close button near the title of a tabbed pane, like the one Intellij uses when you open many files.
It would be nice to have so that we don't have to deal with different LaFs.
Reference:
githubq

Component.isBackgroundSet() and similar not respected

Hi,

I have a toggle button on which the background and foreground colors are forced, but it paints as if these were not set. It seems the code in Flat*ButtonUI does not get the background from the component even though they were explicitly set.

Am I missing something?

PS: very good work, I am impressed by the quality of FlatLaf!

JMenu submenu offset above parent

Screen Shot 2020-01-13 at 7 15 46 PM
Is this offset of a submenu normal? This is in a JPopupMenu on macos.
Screen Shot 2020-01-13 at 8 11 06 AM

I was expecting the submenu to be top aligned with its parent but its a few pixels higher. If there were cascading submenus this would keep going higher and higher I would think. Can this offset be removed?

I see theres not much custom code in the L&F menu UI so I guess maybe theres nothing to be done here.

HTML rendering problem

I am using version 0.13 from Maven. The following code illustrates the problem:

public class HTMLProblem {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(HTMLProblem::runOnEDT);
    }

    private static void runOnEDT() {
        try {
//            UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
            UIManager.setLookAndFeel("com.formdev.flatlaf.FlatDarculaLaf");
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        String msg = "<html>I like <b>bold</b>,"
                + "<br> and I like <i>italic</i>,"
                + "<br> and I like to have"
                + "<br> many lines."
                + "<br> Lots of lines.";
        JOptionPane.showMessageDialog(null, msg);
    }
}

Here's the result, notice how at the end HTML tags are not interpreted anymore:
flatlaf

Here's the correctly rendered result when using Nimbus:
nimbushtml

Look-and-feel-decorated JFrames do not render properly

(split from issue #39)

Modern applications that use flat widgets may want their frame decorations also to be flat.

Here is a test case of the current situation:

	public static void main(String[] args) throws Exception {
		UIManager.setLookAndFeel(new FlatLightLaf());
		JFrame frame = new JFrame("JFrame");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setUndecorated(true);
		frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
		JDesktopPane desktopPane = new JDesktopPane();
		JInternalFrame internalFrame1 = new JInternalFrame("JInternalFrame1", true, true, true, true);
		internalFrame1.setLocation(50, 30);
		internalFrame1.setSize(300, 200);
		desktopPane.add(internalFrame1);
		JInternalFrame internalFrame2 = new JInternalFrame("JInternalFrame2", true, true, true, true);
		internalFrame2.setLocation(60, 40);
		internalFrame2.setSize(300, 200);
		desktopPane.add(internalFrame2);
		frame.getContentPane().add(desktopPane);
		frame.setSize(400, 300);
		frame.setVisible(true);
		internalFrame1.setVisible(true);
		internalFrame2.setVisible(true);
		internalFrame2.setIcon(true);
	}

... and here is the result:
FrameDecorations

@DevCharly said:
Window decoration style looks similar to internal frames, but it seems that the implementation has nothing to do with internal frames. It is implemented in javax.swing.plaf.metal.MetalRootPaneUIand javax.swing.plaf.metal.MetalTitlePane.

Errors in Intellij themes

While playing with the demo application and choosing some Intellij Themes the following errors were print on the terminal:

Failed to parse: 'MenuBar.borderColor=##1a1721'
    invalid color '##1a1721'
Failed to parse: 'CheckBoxMenuItem.disabledBackground=#darkBackground'
    invalid color '#darkBackground'
Failed to parse: 'CompletionPopup.matchForeground=#42A5F52'
    invalid color '#42A5F52'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#42A5F52'
    invalid color '#42A5F52'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#2979ff2'
    invalid color '#2979ff2'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#2979ff2'
    invalid color '#2979ff2'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#2979ff2'
    invalid color '#2979ff2'
Failed to parse: 'List.selectionInactiveBackground=#DBDBDC8025'
    invalid color '#DBDBDC8025'
Failed to parse: 'Table.selectionInactiveBackground=#DBDBDC8025'
    invalid color '#DBDBDC8025'
Failed to parse: 'Tree.selectionInactiveBackground=#DBDBDC8025'
    invalid color '#DBDBDC8025'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#2979ff2'
    invalid color '#2979ff2'
Failed to parse: 'List.selectionInactiveBackground=#DBDBDC8025'
    invalid color '#DBDBDC8025'
Failed to parse: 'Table.selectionInactiveBackground=#DBDBDC8025'
    invalid color '#DBDBDC8025'
Failed to parse: 'Tree.selectionInactiveBackground=#DBDBDC8025'
    invalid color '#DBDBDC8025'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#FF79C52'
    invalid color '#FF79C52'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#FF79C52'
    invalid color '#FF79C52'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#79CB602'
    invalid color '#79CB602'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#79CB602'
    invalid color '#79CB602'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#2693862'
    invalid color '#2693862'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'
Failed to parse: 'CompletionPopup.matchForeground=#d336822'
    invalid color '#d336822'
Failed to parse: 'Viewport.foreground=#%fc'
    invalid color '#%fc'

It seems the included *.theme.json files contain wrong color definitions or missing color references.

I understand that maybe these should be reported to the original authors of the themes.

Underlined toggle button height

I want to use toggle buttons like tabs so I set the underline type. I also increase the size of the underline. The problem is that the line is too close from the text and I don't know if there is a way to have a taller button when the style is underline (something similar to the "TabbedPane.tabHeight" property).

Here is an example comparing tabs and toggle buttons:

	public static void main(String[] args) throws Exception {
		UIManager.setLookAndFeel(new FlatLightLaf());
		UIDefaults defaults = UIManager.getDefaults();
		defaults.put("ToggleButton.underline.underlineHeight", 3);
		defaults.put("TabbedPane.tabSelectionHeight", 3);
		defaults.put("TabbedPane.tabHeight", 22);
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JPanel centerPane = new JPanel(new BorderLayout());
		JToolBar toolBar = new JToolBar();
		toolBar.setFloatable(false);
		ButtonGroup buttonGroup = new ButtonGroup();
		JToggleButton button1 = new JToggleButton("My first button");
		button1.setSelected(true);
		button1.putClientProperty(FlatClientProperties.BUTTON_TYPE, FlatClientProperties.BUTTON_TYPE_UNDERLINE);
		buttonGroup.add(button1);
		toolBar.add(button1);
		JToggleButton button2 = new JToggleButton("My second button");
		button2.putClientProperty(FlatClientProperties.BUTTON_TYPE, FlatClientProperties.BUTTON_TYPE_UNDERLINE);
		buttonGroup.add(button2);
		toolBar.add(button2);
		centerPane.add(toolBar, BorderLayout.NORTH);
		JTabbedPane tabbedPane = new JTabbedPane();
		tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
		tabbedPane.addTab("My first tab", new JPanel());
		tabbedPane.addTab("My second tab", new JPanel());
		centerPane.add(tabbedPane);
		frame.getContentPane().add(centerPane);
		frame.setSize(400, 300);
		frame.setVisible(true);
	}

... and the result:
UnderlineToggleButtonsVsTabs

Way to show horizontal grid lines but not vertical ones

It is quite hard to follow the values of a given item (row) when tables have no lines at all.

Generally, tables in Flat design have, or allow activation of, horizontal lines (but not necessarily vertical lines). I did not find any way to do it with FlatLaf, so sadly I have to show all lines using:

UIDefaults defaults = UIManager.getDefaults();
defaults.put("Table.showGrid", Boolean.TRUE);
defaults.put("Table.intercellSpacing", 1);

Am I missing something? Is there a way to activate horizontal lines only, and that as a global L&F setting (not per table instance like the setShowHorizontalLines(b) method)?

Table sort arrow position

Hi,

With system L&F on Windows 10, the sort icon for tables is placed at the top of the header text.
This is actually very useful, because it does not change the minimum necessary width of the column to display the header text and thus allows more compact columns.

Here is a screenshot showing the behavior on Windows 10 L&F and with FlatLaf for comparison:
SortArrowPosition

Do you think it would be possible to implement a position attribute to specify left/right/top/bottom ? Note that I don't know if that would fit with right-to-left logic but you get the idea ๐Ÿ™‚

Colors in the tooltips of disabled buttons

I am using FlatDarculaLaf with version 0.14 from Maven, and I noticed that the tooltips of disabled buttons are using a bright yellow background and dark text, and this attracts the eye, while anything disabled should not attract it. The "real" Darcula from Intellij uses the same colors for tooltips of disabled buttons as for the enabled ones, and this is OK.

BTW the "real" Darcula has cool little triangles in the tooltip shapes pointing to the original mouse location, while FlatDarculaLaf doesn't have them, but this is not so important.

UI artefact at bottom right corner of scrollpane

Hi,

I noticed a visual glitch when a component in a scrollpane is focused: the bottom corner at the intersection of the 2 scroll bars has an additional edge. Note that it is more or less visible depending on the theme you are using.

Here is a screenshot:
BottomRightScrollArtefact

Tree full row selection

To do this:
Screen Shot 2020-01-13 at 6 03 41 AM

I am subclassing BasicTreeUI and calling setUI on JTree very simply with no change to the default cell renderer.
(Kotlin)

override fun paintRow(
       g: Graphics, clipBounds: Rectangle, insets: Insets, bounds: Rectangle,
       path: TreePath, row: Int, isExpanded: Boolean, hasBeenExpanded: Boolean, isLeaf: Boolean
   ) {
       if (tree.isRowSelected(row)) {
           g.color = if (tree.hasFocus()) ColorUtil.hex2Rgb("#2f65ca") else ColorUtil.hex2Rgb("#0d293e")
           g.fillRect(0, row * tree.rowHeight, tree.width, tree.rowHeight)

       }
       super.paintRow(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf)
       super.paintExpandControl(g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf)
   }

I see you have a UIDefault "Tree.wideSelection", but its not selecting the entire row for me (maybe I did something wrong) so Im not sure if thats what its intent was.

Is there any way to bake this in to the L&F? Its a common thing, its not hard to do with subclassing but could save folks some time.

Table headers do not paint borders and separators when it is a custom wrapper

Hi,

It is common to tweak default behaviors by creating wrappers that delegate to the original renderer.
When we do this with table headers in FlatLaf, then borders and separators are not painted anymore.

Here is sample code showing two tables, one standard and one with delegate:

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel(new FlatLightLaf());
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel centerPane = new JPanel(new GridLayout(2, 1));
        JTable table1 = new JTable(new Object[][] {{"Data_1_1", "Data_1_2"}, {"Data_2_1", "Data_2_2"}}, new String[] {"Col1", "Col2"});
        centerPane.add(new JScrollPane(table1));
        JTable table2 = new JTable(new Object[][] {{"Data_1_1", "Data_1_2"}, {"Data_2_1", "Data_2_2"}}, new String[] {"Col1", "Col2"});
        JTableHeader tableHeader = table2.getTableHeader();
        TableCellRenderer defaultRenderer = tableHeader.getDefaultRenderer();
        tableHeader.setDefaultRenderer(new TableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                return defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
            }
        });
        centerPane.add(new JScrollPane(table2));
        frame.getContentPane().add(centerPane);
        frame.setSize(400, 300);
        frame.setVisible(true);
    }

And here is a screenshot of the result:
TableHeaderOverride

The problem is because of magic code in "FlatTableHeaderUI.paint(g, c)" based on renderer class names.

Rounded buttons are opaque

The buttons don't seem to have real transparency at the corners and borders. Instead of the content behind them the panel color can be seen - this is only OK in simple cases when a button is on a panel.

In the following zoomed-in picture the red arrows indicate the problem areas. Here two buttons are placed on top of each other using a JLayeredPane in order to indicate the foreground and background colors that can be chosen. Such opaque areas don't appear when using Nimbus. Also the Intellij widgets have real transparency, this can be seen if you set a background picture in Idea.

flat_button_borders

JSplitPane no divider arrow Buttons

default i dont have any JSplitPane arrow buttons on my divider.

Is there extra customization i have to do or am i missing something?

regards

Nils G.

Table last vertical line is painted, although headers do not paint theirs

When resizing the table column automatically (i.e. not AUTO_RESIZE_OFF), you do not paint the last column separator of the table header. This is a good thing I think.
Now, if we display the table vertical lines, the cells do paint the last vertical line, which is odd.

Here is a test case:

	public static void main(String[] args) throws Exception {
		UIManager.setLookAndFeel(new FlatLightLaf());
		UIDefaults defaults = UIManager.getDefaults();
		defaults.put("Table.showVerticalLines", Boolean.TRUE);
		defaults.put("Table.showHorizontalLines", Boolean.TRUE);
		defaults.put("Table.intercellSpacing", new Dimension(1, 1));
		defaults.put("Table.gridColor", new Color(0xd9d9d9));
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JPanel centerPane = new JPanel(new BorderLayout());
		centerPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		JTable table = new JTable(new Object[][] { { "Cell 1_1", "Cell 1_2" }, { "Cell 2_1", "Cell 2_2" } }, new String[] { "Column1", "Column2" });
		table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
		JScrollPane scrollPane = new JScrollPane(table);
		centerPane.add(scrollPane);
		frame.getContentPane().add(centerPane);
		frame.setSize(400, 300);
		frame.setVisible(true);
	}

... and here is the result:
TableLastCellsVerticalBorder

Add support for JXTitledPanel

I'm still trying to see if I have my own border and options interfering with this control, but would an official addon for this component make it look better ?

Chevron arrows

besides the currently used triangle arrows, also support chevron arrows

TabbedPane improvements

I know TabScroller is private on BasicTabPaneUI but is there any hope of possibly getting rid of it? In your excellent look and feel this is one of the few things that detracts from the moderness and throws us back to old java L&Fs. I hate it completely.

SwingX's DatePickerUI as a table cell editor

There is a problem with a insets or a border when the DatePicker is used as a table cell editor. I think this has to be detected in the code and something removed when being used as a cell editor.

2019-11-25_13-06-21

Support RTL (right-to-left)

This is a hefty endeavor in general, as core look-and-feels vary greatly in how well they support RTL orientation across the core Swing components. For example, an RTL combobox should have:

  1. Items aligned to the right
  2. Arrow on the left
  3. Popup items aligned to the right
  4. Popup scrollbar on the left

Aqua only gets 4 right
Nimbus gets 1, 2, 3 right
Metal gets only 2 right
FlatLaf only gets 2 right at the present moment (but this goes well beyond JComboBox in general)

public class Test {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Throwable t) {
                    t.printStackTrace(System.err);
                }

                JComboBox comboHebrew = new JComboBox(new Object[] { "\u05e8\u05d0\u05e9\u05d9 1",
                        "\u05e8\u05d0\u05e9\u05d9 2", "\u05e8\u05d0\u05e9\u05d9 3",
                        "\u05e8\u05d0\u05e9\u05d9 4", "\u05e8\u05d0\u05e9\u05d9 5",
                        "\u05e8\u05d0\u05e9\u05d9 6", "\u05e8\u05d0\u05e9\u05d9 7",
                        "\u05e8\u05d0\u05e9\u05d9 8", "\u05e8\u05d0\u05e9\u05d9 9" });
                comboHebrew.setToolTipText("RTL combo");
                comboHebrew.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
                comboHebrew.setMaximumRowCount(6);

                JComboBox comboRegular = new JComboBox(new Object[] { "item 1",
                        "item 2", "item 3",
                        "item 4", "item 5",
                        "item 6", "item 7",
                        "item 8", "item 9" });
                comboRegular.setToolTipText("LTR combo");
                comboRegular.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
                comboRegular.setMaximumRowCount(6);

                JButton toFlat = new JButton("Set FlatDark!");
                toFlat.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    UIManager.setLookAndFeel("com.formdev.flatlaf.FlatDarkLaf");
                                    for (Window w : Window.getWindows()) {
                                        SwingUtilities.updateComponentTreeUI(w);
                                    }
                                } catch (Throwable t) {
                                    t.printStackTrace(System.err);
                                }
                            }
                        });
                    }
                });

                JButton toNimbus = new JButton("Set Nimbus!");
                toNimbus.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    UIManager.setLookAndFeel(new NimbusLookAndFeel());
                                    for (Window w : Window.getWindows()) {
                                        SwingUtilities.updateComponentTreeUI(w);
                                    }
                                } catch (Throwable t) {
                                    t.printStackTrace(System.err);
                                }
                            }
                        });
                    }
                });

                JButton toMetal = new JButton("Set Metal!");
                toMetal.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    UIManager.setLookAndFeel(new MetalLookAndFeel());
                                    for (Window w : Window.getWindows()) {
                                        SwingUtilities.updateComponentTreeUI(w);
                                    }
                                } catch (Throwable t) {
                                    t.printStackTrace(System.err);
                                }
                            }
                        });
                    }
                });

                JFrame frame = new JFrame("Combo test");
                frame.setLayout(new BorderLayout());

                JPanel flow = new JPanel(new FlowLayout());
                comboRegular.setPreferredSize(new Dimension(comboRegular.getPreferredSize().width + 50,
                        comboRegular.getPreferredSize().height));
                flow.add(comboRegular);
                comboHebrew.setPreferredSize(new Dimension(comboHebrew.getPreferredSize().width + 50,
                        comboHebrew.getPreferredSize().height));
                flow.add(comboHebrew);
                frame.add(flow, BorderLayout.NORTH);

                JPanel flowButtons = new JPanel(new FlowLayout());
                flowButtons.add(toNimbus);
                flowButtons.add(toMetal);
                flowButtons.add(toFlat);
                frame.add(flowButtons, BorderLayout.SOUTH);

                frame.setSize(400, 400);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

Theming of LaF components with JSON properties

It would be very nice, if we can have a config, which makes more fun for me as a frontend developer to style all the components easily by my own via CSS or maybe with a JSON config file. We are talking about stuff, that are already stylable like borders (color, width, style, shadow, etc.) inputs (color, size, margin, padding, etc.) and and and. Maybe with CSS it will be a bit hard to map the correct values to the correct fields but with a json config file, it would be nice to have smth like this:

CompletionPopup: {
   "matchForeground": "#fff",
   "disabledBackground": "#ccc"
}

That is first just fun to do that and very easy to create new look and feels and second, I hope it will be easy of switchting look and feels in Netbeans without a restart. Just guessing, beacuse it is just switchting properties and swing needs to updates it.

Question: Is smooth scrolling available out of the box?

The headline says it all: Is there a smooth scrolling feature which comes with the FlatLaf out of the box? When I use NetBeans with a nb-darcula theme for example the scrolling jumps to a specific number of rows. It is fixed. This features was implemented into NetBeans (one specific LaF) out of the box. It would be nice, if the FlatLaF will have it, if not :)

Cheers

Chris

Mnemonics in menus are always displayed

With the system L&F (Windows 10), mnemonics are not displayed in menus unless I press the Alt key. With FlatLaf, mnemonics are always displayed.

I see that the FlatLaf code triggers repainting on the hierarchy when Alt is pressed or released, but this has no visual impact.

Unless I am mistaken, FlatMenuUI extends BasicMenuUI, and BasicMenuUI always paints the mnemonic. WindowsMenuItemUI (for system L&F) also extends BasicMenuItemUI but overrides paintText to have the mnemonic show/hide logic.

Please, let me know if I did something wrong ๐Ÿ™‚

Add a security policy for the demo

A Java security policy file would be helpful for those who want to give the demo program a quick try but are reluctant to run software from outside their normal trusted sources. The security policy lets you run the demo under the Java Security Manager with each permission granted explicitly.

The security policy that works for the demo program is:

grant codeBase "file:///${user.home}/Downloads/flatlaf-demo-0.18.jar" {
    permission java.lang.RuntimePermission "accessClassInPackage.sun.swing";
    permission java.lang.RuntimePermission "getenv.KDE_FULL_SESSION";
    permission java.lang.RuntimePermission "preferences";

    permission java.util.PropertyPermission "apple.awt.graphics.UseQuartz", "read";
    permission java.util.PropertyPermission "flatlaf.uiScale", "read";
    permission java.util.PropertyPermission "hidpi", "read";
    permission java.util.PropertyPermission "sun.java2d.uiScale", "read";
};

You can run the demo under the Security Manager with a command like the following:

$ java -Djava.security.manager -Djava.security.policy=flatlaf.policy \
    -jar flatlaf-demo-0.18.jar

I suggest providing the file in the repository so that people can use it if they want. Otherwise, it's tedious to create because you have to go through each security exception one by one.

Switching from another look-and-feel sometimes creates inconsistent combobox visuals

image

See how the background behind the arrows is darker than the rest of the combobox fill.

public class Test {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Throwable t) {
                    t.printStackTrace(System.err);
                }

                JComboBox comboHebrew = new JComboBox(new Object[] { "\u05e8\u05d0\u05e9\u05d9 1",
                        "\u05e8\u05d0\u05e9\u05d9 2", "\u05e8\u05d0\u05e9\u05d9 3",
                        "\u05e8\u05d0\u05e9\u05d9 4", "\u05e8\u05d0\u05e9\u05d9 5",
                        "\u05e8\u05d0\u05e9\u05d9 6", "\u05e8\u05d0\u05e9\u05d9 7",
                        "\u05e8\u05d0\u05e9\u05d9 8", "\u05e8\u05d0\u05e9\u05d9 9" });
                comboHebrew.setToolTipText("RTL combo");
                comboHebrew.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
                comboHebrew.setMaximumRowCount(6);

                JComboBox comboRegular = new JComboBox(new Object[] { "item 1",
                        "item 2", "item 3",
                        "item 4", "item 5",
                        "item 6", "item 7",
                        "item 8", "item 9" });
                comboRegular.setToolTipText("LTR combo");
                comboRegular.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
                comboRegular.setMaximumRowCount(6);

                JButton toFlat = new JButton("Set FlatDark!");
                toFlat.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    UIManager.setLookAndFeel("com.formdev.flatlaf.FlatDarkLaf");
                                    for (Window w : Window.getWindows()) {
                                        SwingUtilities.updateComponentTreeUI(w);
                                    }
                                } catch (Throwable t) {
                                    t.printStackTrace(System.err);
                                }
                            }
                        });
                    }
                });

                JButton toNimbus = new JButton("Set Nimbus!");
                toNimbus.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    UIManager.setLookAndFeel(new NimbusLookAndFeel());
                                    for (Window w : Window.getWindows()) {
                                        SwingUtilities.updateComponentTreeUI(w);
                                    }
                                } catch (Throwable t) {
                                    t.printStackTrace(System.err);
                                }
                            }
                        });
                    }
                });

                JButton toMetal = new JButton("Set Metal!");
                toMetal.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    UIManager.setLookAndFeel(new MetalLookAndFeel());
                                    for (Window w : Window.getWindows()) {
                                        SwingUtilities.updateComponentTreeUI(w);
                                    }
                                } catch (Throwable t) {
                                    t.printStackTrace(System.err);
                                }
                            }
                        });
                    }
                });

                JFrame frame = new JFrame("Combo test");
                frame.setLayout(new BorderLayout());

                JPanel flow = new JPanel(new FlowLayout());
                comboRegular.setPreferredSize(new Dimension(comboRegular.getPreferredSize().width + 50,
                        comboRegular.getPreferredSize().height));
                flow.add(comboRegular);
                comboHebrew.setPreferredSize(new Dimension(comboHebrew.getPreferredSize().width + 50,
                        comboHebrew.getPreferredSize().height));
                flow.add(comboHebrew);
                frame.add(flow, BorderLayout.NORTH);

                JPanel flowButtons = new JPanel(new FlowLayout());
                flowButtons.add(toNimbus);
                flowButtons.add(toMetal);
                flowButtons.add(toFlat);
                frame.add(flowButtons, BorderLayout.SOUTH);

                frame.setSize(400, 400);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

Scroll in FileChooser does not scroll by block

In a FileChooser with native look and feel on Windows (my reference), using the scroll bar or the wheel mouse scrolls by block, always with the file names aligned on the left. With FlatLaf, file names can be anywhere which makes it quite hard to find a file in big folders.

Color of a Button

Hi ! I'm having difficulties with getting a colored background for a JButton or a JToggleButton depending on its state (red/green). I also just saw that version 0.22 changed this a little, but I feel we might need a way to specify a background color. I've tried many different combinations of opaque/etc but it seems hard. What do you think ?

Internal Frames do not have decorations corresponding to FlatLaf

(bug report split from issue #11)

Internal frame decorations are not correct for FlatLaf.
Here is a simple test case:

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel(new FlatLightLaf());
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JDesktopPane desktopPane = new JDesktopPane();
        JInternalFrame internalFrame = new JInternalFrame("Test", true, true, true, true);
        internalFrame.setLocation(50, 30);
        internalFrame.setSize(300, 200);
        desktopPane.add(internalFrame);
        frame.getContentPane().add(desktopPane);
        frame.setSize(400, 300);
        frame.setVisible(true);
        internalFrame.setVisible(true);
    }

And here is the result:
InternalFrame

Crash in combobox with custom renderer after switching to FlatLaf

public class Test {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(new NimbusLookAndFeel());
                } catch (Throwable t) {
                    t.printStackTrace(System.err);
                }

                JComboBox comboColors = new JComboBox<>(new Color[] {new Color(255, 128, 128),
                        new Color(128, 255, 128), new Color(128, 128, 255), new Color(255, 255, 128),
                        new Color(255, 128, 255), new Color(128, 255, 255)});

                comboColors.setRenderer(new DefaultListCellRenderer() {
                    @Override
                    public Component getListCellRendererComponent(JList list,
                            Object value, int index, boolean isSelected,
                            boolean cellHasFocus) {
                        Color color = (Color) value;
                        Component result = super.getListCellRendererComponent(list,
                                color.getRed() + ":" + color.getGreen() + ":" + color.getBlue(),
                                index, isSelected, cellHasFocus);
                            result.setBackground(color);
                        return result;
                    }
                });

                JButton toFlat = new JButton("Set FlatDark!");
                toFlat.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                try {
                                    UIManager.setLookAndFeel("com.formdev.flatlaf.FlatDarkLaf");
                                    for (Window w : Window.getWindows()) {
                                        SwingUtilities.updateComponentTreeUI(w);
                                    }
                                } catch (Throwable t) {
                                    t.printStackTrace(System.err);
                                }
                            }
                        });
                    }
                });

                JFrame frame = new JFrame("Combo test");
                frame.setLayout(new BorderLayout());
                frame.add(comboColors, BorderLayout.NORTH);
                frame.add(toFlat, BorderLayout.SOUTH);
                frame.setSize(400, 400);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

Click the "Set FlatDark!" button and then click the combo at the top. Result:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at java.desktop/javax.swing.plaf.basic.BasicComboPopup.getPopupHeightForRowCount(BasicComboPopup.java:1283)
	at java.desktop/javax.swing.plaf.basic.BasicComboPopup.getPopupLocation(BasicComboPopup.java:1369)
	at java.desktop/javax.swing.plaf.basic.BasicComboPopup.show(BasicComboPopup.java:234)
	at java.desktop/javax.swing.plaf.basic.BasicComboPopup.togglePopup(BasicComboPopup.java:1218)
	at java.desktop/javax.swing.plaf.basic.BasicComboPopup$Handler.mousePressed(BasicComboPopup.java:897)
	at java.desktop/java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:287)
	at java.desktop/java.awt.Component.processMouseEvent(Component.java:6633)

This is on 0.14

StackOverflowError

I am using version 0.13 from Maven. The following code throws StackOverflowError apparently because of an infinite loop. As I explained in the comments, this can be reproduced only if pack is not called.

import com.formdev.flatlaf.FlatDarculaLaf;
import com.formdev.flatlaf.FlatIntelliJLaf;

import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Window;

public class UpdateComponentTreeProblem {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(UpdateComponentTreeProblem::runOnEDT);
    }

    private static void runOnEDT() {
        setLaf(new FlatDarculaLaf());

        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.setLayout(new BorderLayout());

        JComboBox<String> themeChooser = new JComboBox<>(new String[]{"Light", "Dark"});
        themeChooser.setName("themeChooser");
        themeChooser.setSelectedItem("Dark");

        themeChooser.addActionListener(e -> {
            String themeName = (String) themeChooser.getSelectedItem();
            if(themeName.equals("Light")) {
                setLaf(new FlatIntelliJLaf());
            }
        });
        f.add(themeChooser, BorderLayout.NORTH);
        f.add(new JLabel("Change the theme to \"Light\"!"));

        // In order to reproduce the problem,
        // it is crucial NOT to call pack().
        // In a real app the window size could be read
        // from the saved preferences and set manually.
//        f.pack();
        f.setSize(600, 400);

        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static void setLaf(LookAndFeel laf) {
        try {
            UIManager.setLookAndFeel(laf);
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }

        Window[] windows = Window.getWindows();
        for (Window window : windows) {
            SwingUtilities.updateComponentTreeUI(window);
        }
    }
}

Menus do not react when mouse hovers, unlike all other clickable components

Under FlatLaf, components change style on mouse hover: buttons get a different border, tabs get a gray background, etc. It makes the application feel "alive" too.
Menus do not react and feel "dead". I think they should get a gray background, like tabs.

I also wonder if an "tab" style would be appropriate, like toggle buttons.

Simple test case of a menu bar:

	public static void main(String[] args) throws Exception {
		UIManager.setLookAndFeel(new FlatLightLaf());
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		JMenuBar menuBar = new JMenuBar();
		JMenu menu1 = new JMenu("Menu 1");
		menu1.setMnemonic('m');
		JMenuItem subMenu1_1 = new JMenuItem("Sub Menu 1.1");
		subMenu1_1.setMnemonic('s');
		menu1.add(subMenu1_1);
		menuBar.add(menu1);
		JMenu menu2 = new JMenu("Menu 2");
		menu2.setMnemonic('n');
		JMenuItem subMenu2_1 = new JMenuItem("Sub Menu 2.1");
		subMenu2_1.setMnemonic('u');
		menu2.add(subMenu2_1);
		menuBar.add(menu2);
		frame.setJMenuBar(menuBar);
		frame.setContentPane(new JScrollPane(new JTextArea()));
		frame.setSize(400, 300);
		frame.setVisible(true);
	}

Border instance should not change depending on parent

When a button is placed in a toolbar, the appearance of its border changes. I found that the border is replaced when parenting to the toolbar, while it should be the same instance with a different painting logic. Otherwise, compounding the default border with another border does not work.

Here is a simple test case to illustrate:

    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel(new FlatLightLaf());
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        JToolBar toolBar = new JToolBar();
        JButton button1 = new JButton(new FlatFileViewFloppyDriveIcon());
        toolBar.add(button1);
        JButton button2 = new JButton(new FlatFileViewFloppyDriveIcon());
        button2.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10), button2.getBorder()));
        toolBar.add(button2);
        panel.add(toolBar);
        frame.getContentPane().add(panel);
        frame.setSize(400, 300);
        frame.setVisible(true);
    }

Here is a screenshot of the result:
BorderCompounding

Notice that the second button has a border that is painted, which it should not have.

Underlined toggle buttons with per-instance properties

Using toggle buttons that look like tabs is great for the L&F harmony of the application. This allows to create task bar buttons for example.

Now, depending on the context, the buttons will be adjusted in different ways (important bar may have bigger buttons, bold font, etc.). The problem is that the size of the underline and its related attributes are global. If I am not mistaken, there are no client properties to have a per-instance definition.

Question: customizing JTabbedPane

I have a question on customizing JTabbedPane. Can I customize the selectedBackground?

I am using FlatIntelliJLaf and do the following:

FlatIntelliJLaf.install();
UIManager.put("TabbedPane.selectedBackground", Color.BLUE);

// UI initialization here

This does not seem to have any effect. I see that the property is actually respected:
https://github.com/JFormDesigner/FlatLaf/blob/master/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java

However, no luck. Am I doing something wrong?

cannot find symbol symbol: variable FlatLightLaf location: class xxx

Whenn adding the line "FlatLightLaf.install();" to my java-classes, I receiv the error
"cannot find symbol
symbol: variable FlatLightLaf
location: class CarolaHartmannMilesVerlag"
although I addes the jar-file to my classpath.
I am using Netbeans 11.00.
What do I missing?
Kind regards
Thomas

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.