mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 22:47:13 -06:00
Merge main into system-file-chooser
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright 2025 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.testing;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* java -classpath "<FlatLaf-root>/flatlaf-testing/bin/main" com.formdev.flatlaf.testing.FlatClassLoaderTest
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatClassLoaderTest
|
||||
extends JPanel
|
||||
{
|
||||
public static void main( String[] args ) {
|
||||
try {
|
||||
Class.forName( "com.formdev.flatlaf.FlatDarkLaf" );
|
||||
System.err.println( "Run without FlatLaf on classpath" );
|
||||
return;
|
||||
} catch( ClassNotFoundException ex ) {
|
||||
// continue
|
||||
} catch( Exception ex ) {
|
||||
ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
if( FlatClassLoaderTest.class.getResource( "/META-INF/services/com.formdev.flatlaf.FlatDefaultsAddon" ) != null ) {
|
||||
System.err.println( "Remove file 'META-INF/services/com.formdev.flatlaf.FlatDefaultsAddon'" );
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
@SuppressWarnings( "resource" )
|
||||
URLClassLoader cl = new URLClassLoader( new URL[] {
|
||||
new URL( "file", null, "../flatlaf-core/bin/main/" )
|
||||
}, FlatClassLoaderTest.class.getClassLoader() );
|
||||
|
||||
Class<?> lafClass = cl.loadClass( "com.formdev.flatlaf.FlatDarkLaf" );
|
||||
LookAndFeel laf = (LookAndFeel) lafClass.getDeclaredConstructor().newInstance();
|
||||
UIManager.setLookAndFeel( laf );
|
||||
|
||||
JFrame frame = new JFrame( "FlatClassloaderTest" );
|
||||
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
|
||||
frame.add( new FlatClassLoaderTest() );
|
||||
frame.setBounds( 100, 100, 600, 400 );
|
||||
frame.setVisible( true );
|
||||
} catch( Exception ex ) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private FlatClassLoaderTest() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
JLabel label1 = new JLabel();
|
||||
JTextField textField1 = new JTextField();
|
||||
JComboBox<String> comboBox1 = new JComboBox<>();
|
||||
JButton button1 = new JButton();
|
||||
JCheckBox checkBox1 = new JCheckBox();
|
||||
JRadioButton radioButton1 = new JRadioButton();
|
||||
JToggleButton toggleButton1 = new JToggleButton();
|
||||
JScrollPane scrollPane1 = new JScrollPane();
|
||||
JTextArea textArea1 = new JTextArea();
|
||||
JFormattedTextField formattedTextField1 = new JFormattedTextField();
|
||||
JPasswordField passwordField1 = new JPasswordField();
|
||||
JScrollPane scrollPane2 = new JScrollPane();
|
||||
JTextPane textPane1 = new JTextPane();
|
||||
JScrollPane scrollPane3 = new JScrollPane();
|
||||
JEditorPane editorPane1 = new JEditorPane();
|
||||
JSpinner spinner1 = new JSpinner();
|
||||
JScrollPane scrollPane4 = new JScrollPane();
|
||||
JList<String> list1 = new JList<>();
|
||||
JScrollPane scrollPane5 = new JScrollPane();
|
||||
JTable table1 = new JTable();
|
||||
JScrollPane scrollPane6 = new JScrollPane();
|
||||
JTree tree1 = new JTree();
|
||||
JProgressBar progressBar1 = new JProgressBar();
|
||||
JScrollBar scrollBar1 = new JScrollBar();
|
||||
JSeparator separator1 = new JSeparator();
|
||||
JSlider slider1 = new JSlider();
|
||||
JPanel panel1 = new JPanel();
|
||||
JTabbedPane tabbedPane1 = new JTabbedPane();
|
||||
JSplitPane splitPane1 = new JSplitPane();
|
||||
JToolBar toolBar1 = new JToolBar();
|
||||
JMenuBar menuBar1 = new JMenuBar();
|
||||
JMenu menu1 = new JMenu();
|
||||
JMenuItem menuItem1 = new JMenuItem();
|
||||
JCheckBoxMenuItem checkBoxMenuItem1 = new JCheckBoxMenuItem();
|
||||
JRadioButtonMenuItem radioButtonMenuItem1 = new JRadioButtonMenuItem();
|
||||
|
||||
//======== this ========
|
||||
setLayout(new FlowLayout());
|
||||
|
||||
//---- label1 ----
|
||||
label1.setText("text");
|
||||
add(label1);
|
||||
add(textField1);
|
||||
add(comboBox1);
|
||||
|
||||
//---- button1 ----
|
||||
button1.setText("text");
|
||||
add(button1);
|
||||
|
||||
//---- checkBox1 ----
|
||||
checkBox1.setText("text");
|
||||
add(checkBox1);
|
||||
|
||||
//---- radioButton1 ----
|
||||
radioButton1.setText("text");
|
||||
add(radioButton1);
|
||||
|
||||
//---- toggleButton1 ----
|
||||
toggleButton1.setText("text");
|
||||
add(toggleButton1);
|
||||
|
||||
//======== scrollPane1 ========
|
||||
{
|
||||
scrollPane1.setViewportView(textArea1);
|
||||
}
|
||||
add(scrollPane1);
|
||||
add(formattedTextField1);
|
||||
add(passwordField1);
|
||||
|
||||
//======== scrollPane2 ========
|
||||
{
|
||||
scrollPane2.setViewportView(textPane1);
|
||||
}
|
||||
add(scrollPane2);
|
||||
|
||||
//======== scrollPane3 ========
|
||||
{
|
||||
scrollPane3.setViewportView(editorPane1);
|
||||
}
|
||||
add(scrollPane3);
|
||||
add(spinner1);
|
||||
|
||||
//======== scrollPane4 ========
|
||||
{
|
||||
scrollPane4.setViewportView(list1);
|
||||
}
|
||||
add(scrollPane4);
|
||||
|
||||
//======== scrollPane5 ========
|
||||
{
|
||||
|
||||
//---- table1 ----
|
||||
table1.setPreferredScrollableViewportSize(new Dimension(100, 80));
|
||||
scrollPane5.setViewportView(table1);
|
||||
}
|
||||
add(scrollPane5);
|
||||
|
||||
//======== scrollPane6 ========
|
||||
{
|
||||
|
||||
//---- tree1 ----
|
||||
tree1.setVisibleRowCount(6);
|
||||
scrollPane6.setViewportView(tree1);
|
||||
}
|
||||
add(scrollPane6);
|
||||
add(progressBar1);
|
||||
add(scrollBar1);
|
||||
add(separator1);
|
||||
add(slider1);
|
||||
|
||||
//======== panel1 ========
|
||||
{
|
||||
panel1.setLayout(new BoxLayout(panel1, BoxLayout.X_AXIS));
|
||||
}
|
||||
add(panel1);
|
||||
add(tabbedPane1);
|
||||
add(splitPane1);
|
||||
|
||||
//======== toolBar1 ========
|
||||
{
|
||||
toolBar1.addSeparator();
|
||||
}
|
||||
add(toolBar1);
|
||||
|
||||
//======== menuBar1 ========
|
||||
{
|
||||
|
||||
//======== menu1 ========
|
||||
{
|
||||
menu1.setText("text");
|
||||
|
||||
//---- menuItem1 ----
|
||||
menuItem1.setText("text");
|
||||
menu1.add(menuItem1);
|
||||
|
||||
//---- checkBoxMenuItem1 ----
|
||||
checkBoxMenuItem1.setText("text");
|
||||
menu1.add(checkBoxMenuItem1);
|
||||
|
||||
//---- radioButtonMenuItem1 ----
|
||||
radioButtonMenuItem1.setText("text");
|
||||
menu1.add(radioButtonMenuItem1);
|
||||
menu1.addSeparator();
|
||||
}
|
||||
menuBar1.add(menu1);
|
||||
}
|
||||
add(menuBar1);
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
root: new FormRoot {
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.defaultVariableLocal": true
|
||||
}
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "this"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label1"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "textField1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
name: "comboBox1"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.typeParameters": "String"
|
||||
}
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button1"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "checkBox1"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||
name: "radioButton1"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
||||
name: "toggleButton1"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane1"
|
||||
add( new FormComponent( "javax.swing.JTextArea" ) {
|
||||
name: "textArea1"
|
||||
} )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JFormattedTextField" ) {
|
||||
name: "formattedTextField1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JPasswordField" ) {
|
||||
name: "passwordField1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane2"
|
||||
add( new FormComponent( "javax.swing.JTextPane" ) {
|
||||
name: "textPane1"
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane3"
|
||||
add( new FormComponent( "javax.swing.JEditorPane" ) {
|
||||
name: "editorPane1"
|
||||
} )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSpinner" ) {
|
||||
name: "spinner1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane4"
|
||||
add( new FormComponent( "javax.swing.JList" ) {
|
||||
name: "list1"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.typeParameters": "String"
|
||||
}
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane5"
|
||||
add( new FormComponent( "javax.swing.JTable" ) {
|
||||
name: "table1"
|
||||
"preferredScrollableViewportSize": new java.awt.Dimension( 100, 80 )
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||
name: "scrollPane6"
|
||||
add( new FormComponent( "javax.swing.JTree" ) {
|
||||
name: "tree1"
|
||||
"visibleRowCount": 6
|
||||
} )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JProgressBar" ) {
|
||||
name: "progressBar1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JScrollBar" ) {
|
||||
name: "scrollBar1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSeparator" ) {
|
||||
name: "separator1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSlider" ) {
|
||||
name: "slider1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class javax.swing.BoxLayout ) {
|
||||
"axis": 0
|
||||
} ) {
|
||||
name: "panel1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) {
|
||||
name: "tabbedPane1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JSplitPane", new FormLayoutManager( class javax.swing.JSplitPane ) ) {
|
||||
name: "splitPane1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
||||
name: "toolBar1"
|
||||
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
|
||||
name: "separator2"
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenuBar", new FormLayoutManager( class javax.swing.JMenuBar ) ) {
|
||||
name: "menuBar1"
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "menu1"
|
||||
"text": "text"
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "menuItem1"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
|
||||
name: "checkBoxMenuItem1"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JRadioButtonMenuItem" ) {
|
||||
name: "radioButtonMenuItem1"
|
||||
"text": "text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
|
||||
name: "separator3"
|
||||
} )
|
||||
} )
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 425, 460 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,10 @@ import java.awt.event.MouseEvent;
|
||||
import java.util.Random;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.event.PopupMenuEvent;
|
||||
import javax.swing.event.PopupMenuListener;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
import com.formdev.flatlaf.util.Animator;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
import net.miginfocom.swing.*;
|
||||
@@ -43,6 +47,8 @@ public class FlatPopupTest
|
||||
|
||||
FlatPopupTest() {
|
||||
initComponents();
|
||||
addPopupMenuListener( popupMenu1, "popupMenu1" );
|
||||
addPopupMenuListener( popupMenu2, "popupMenu2" );
|
||||
}
|
||||
|
||||
private void showPopupMenu() {
|
||||
@@ -114,6 +120,46 @@ public class FlatPopupTest
|
||||
}
|
||||
}
|
||||
|
||||
private void showDirectPopup() {
|
||||
DirectPopupContent content = new DirectPopupContent();
|
||||
content.putClientProperty( FlatClientProperties.POPUP_FORCE_HEAVY_WEIGHT, true );
|
||||
Point pt = showDirectPopupButton.getLocationOnScreen();
|
||||
|
||||
System.setProperty( FlatSystemProperties.USE_ROUNDED_POPUP_BORDER, "false" );
|
||||
UIManager.put( "Popup.dropShadowColor", Color.red );
|
||||
UIManager.put( "Popup.dropShadowInsets", new Insets( 5, 5, 5, 5 ) );
|
||||
UIManager.put( "Popup.dropShadowOpacity", 1f );
|
||||
|
||||
Popup popup = PopupFactory.getSharedInstance().getPopup( showDirectPopupButton,
|
||||
content, pt.x, pt.y + showDirectPopupButton.getHeight() + 10 );
|
||||
content.popup = popup;
|
||||
popup.show();
|
||||
|
||||
System.clearProperty( FlatSystemProperties.USE_ROUNDED_POPUP_BORDER );
|
||||
UIManager.put( "Popup.dropShadowColor", null );
|
||||
UIManager.put( "Popup.dropShadowInsets", null );
|
||||
UIManager.put( "Popup.dropShadowOpacity", null );
|
||||
}
|
||||
|
||||
private void addPopupMenuListener( JPopupMenu popupMenu, String name ) {
|
||||
popupMenu.addPopupMenuListener( new PopupMenuListener() {
|
||||
@Override
|
||||
public void popupMenuWillBecomeVisible( PopupMenuEvent e ) {
|
||||
System.out.println( "popupMenuWillBecomeVisible " + name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuWillBecomeInvisible( PopupMenuEvent e ) {
|
||||
System.out.println( "popupMenuWillBecomeInvisible " + name );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popupMenuCanceled( PopupMenuEvent e ) {
|
||||
System.out.println( "popupMenuCanceled " + name );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUI() {
|
||||
super.updateUI();
|
||||
@@ -128,15 +174,12 @@ public class FlatPopupTest
|
||||
}
|
||||
}
|
||||
|
||||
private void countChanged() {
|
||||
// TODO add your code here
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
label1 = new JLabel();
|
||||
label2 = new JLabel();
|
||||
showPopupMenuButton = new JButton();
|
||||
showDirectPopupButton = new JButton();
|
||||
showLargePopupMenuButton = new JButton();
|
||||
showPopupButton = new JButton();
|
||||
hidePopupButton = new JButton();
|
||||
@@ -209,6 +252,11 @@ public class FlatPopupTest
|
||||
showPopupMenuButton.addActionListener(e -> showPopupMenu());
|
||||
add(showPopupMenuButton, "cell 0 2");
|
||||
|
||||
//---- showDirectPopupButton ----
|
||||
showDirectPopupButton.setText("show direct move/resize popup");
|
||||
showDirectPopupButton.addActionListener(e -> showDirectPopup());
|
||||
add(showDirectPopupButton, "cell 2 2 2 1");
|
||||
|
||||
//---- showLargePopupMenuButton ----
|
||||
showLargePopupMenuButton.setText("show heavy-weight JPopupMenu");
|
||||
showLargePopupMenuButton.addActionListener(e -> showLargePopupMenu());
|
||||
@@ -240,7 +288,6 @@ public class FlatPopupTest
|
||||
|
||||
//---- countField ----
|
||||
countField.setModel(new SpinnerNumberModel(1, 1, null, 1));
|
||||
countField.addChangeListener(e -> countChanged());
|
||||
add(countField, "cell 5 4");
|
||||
|
||||
//---- label4 ----
|
||||
@@ -366,6 +413,7 @@ public class FlatPopupTest
|
||||
private JLabel label1;
|
||||
private JLabel label2;
|
||||
private JButton showPopupMenuButton;
|
||||
private JButton showDirectPopupButton;
|
||||
private JButton showLargePopupMenuButton;
|
||||
private JButton showPopupButton;
|
||||
private JButton hidePopupButton;
|
||||
@@ -444,4 +492,69 @@ public class FlatPopupTest
|
||||
private JLabel label6;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on
|
||||
}
|
||||
|
||||
//---- class MyPopupContent -----------------------------------------------
|
||||
|
||||
private static class DirectPopupContent
|
||||
extends JPanel
|
||||
{
|
||||
Popup popup;
|
||||
|
||||
DirectPopupContent() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
private void resizePopup() {
|
||||
Window popupWindow = SwingUtilities.windowForComponent( this );
|
||||
popupWindow.setSize( popupWindow.getWidth() + 20, popupWindow.getHeight() + 50 );
|
||||
}
|
||||
|
||||
private void movePopup() {
|
||||
Window popupWindow = SwingUtilities.windowForComponent( this );
|
||||
popupWindow.setLocation( popupWindow.getX() + 20, popupWindow.getY() + 50 );
|
||||
}
|
||||
|
||||
private void hidePopup() {
|
||||
popup.hide();
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents @formatter:off
|
||||
resizeButton = new JButton();
|
||||
moveButton = new JButton();
|
||||
hideButton = new JButton();
|
||||
|
||||
//======== this ========
|
||||
setLayout(new MigLayout(
|
||||
"hidemode 3",
|
||||
// columns
|
||||
"[fill]" +
|
||||
"[fill]" +
|
||||
"[fill]",
|
||||
// rows
|
||||
"[]"));
|
||||
|
||||
//---- resizeButton ----
|
||||
resizeButton.setText("Resize");
|
||||
resizeButton.addActionListener(e -> resizePopup());
|
||||
add(resizeButton, "cell 0 0");
|
||||
|
||||
//---- moveButton ----
|
||||
moveButton.setText("Move");
|
||||
moveButton.addActionListener(e -> movePopup());
|
||||
add(moveButton, "cell 1 0");
|
||||
|
||||
//---- hideButton ----
|
||||
hideButton.setText("Hide");
|
||||
hideButton.addActionListener(e -> hidePopup());
|
||||
add(hideButton, "cell 2 0");
|
||||
// JFormDesigner - End of component initialization //GEN-END:initComponents @formatter:on
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables @formatter:off
|
||||
private JButton resizeButton;
|
||||
private JButton moveButton;
|
||||
private JButton hideButton;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables @formatter:on
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "8.2.3.0.386" Java: "21" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -30,6 +30,13 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "showDirectPopupButton"
|
||||
"text": "show direct move/resize popup"
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showDirectPopup", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 2 2 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "showLargePopupMenuButton"
|
||||
"text": "show heavy-weight JPopupMenu"
|
||||
@@ -77,7 +84,6 @@ new FormModel {
|
||||
minimum: 1
|
||||
value: 1
|
||||
}
|
||||
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "countChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 5 4"
|
||||
} )
|
||||
@@ -215,5 +221,39 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 5, 505 )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "hidemode 3"
|
||||
"$columnConstraints": "[fill][fill][fill]"
|
||||
"$rowConstraints": "[]"
|
||||
} ) {
|
||||
name: "panel1"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.className": "DirectPopupContent"
|
||||
}
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "resizeButton"
|
||||
"text": "Resize"
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "resizePopup", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "moveButton"
|
||||
"text": "Move"
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "movePopup", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "hideButton"
|
||||
"text": "Hide"
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hidePopup", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 0"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 180, 395 )
|
||||
"size": new java.awt.Dimension( 270, 100 )
|
||||
} )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +142,9 @@ public class FlatSingleComponentTest
|
||||
// register Alt+Shift+F1, F2, ... keys to change system scale factor
|
||||
DemoPrefs.registerSystemScaleFactors( this );
|
||||
|
||||
// register Alt+Shift+S to enable/disable interprocess Laf sync
|
||||
DemoPrefs.initLafSync( this );
|
||||
|
||||
// register Alt+R key to toggle component orientation
|
||||
registerKey( "alt R", () -> {
|
||||
applyComponentOrientation( getComponentOrientation().isLeftToRight()
|
||||
|
||||
@@ -176,6 +176,9 @@ public class FlatTestFrame
|
||||
// register Alt+Shift+F1, F2, ... keys to change system scale factor
|
||||
DemoPrefs.registerSystemScaleFactors( this );
|
||||
|
||||
// register Alt+Shift+S to enable/disable interprocess Laf sync
|
||||
DemoPrefs.initLafSync( this );
|
||||
|
||||
// register Ctrl+0, Ctrl++ and Ctrl+- to change font size
|
||||
registerKey( SystemInfo.isMacOS ? "meta 0" : "ctrl 0", () -> restoreFont() );
|
||||
registerKey( SystemInfo.isMacOS ? "meta PLUS" : "ctrl PLUS", () -> incrFont() );
|
||||
@@ -579,7 +582,7 @@ public class FlatTestFrame
|
||||
UIManager.put( "defaultFont", null );
|
||||
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
IntelliJTheme theme = (lookAndFeel instanceof IntelliJTheme.ThemeLaf)
|
||||
IntelliJTheme theme = (lookAndFeel.getClass() == IntelliJTheme.ThemeLaf.class)
|
||||
? ((IntelliJTheme.ThemeLaf)lookAndFeel).getTheme()
|
||||
: null;
|
||||
String nameForProperties = null;
|
||||
|
||||
@@ -24,6 +24,9 @@ import javax.swing.table.*;
|
||||
import net.miginfocom.swing.*;
|
||||
import org.jdesktop.swingx.*;
|
||||
import org.jdesktop.swingx.table.DatePickerCellEditor;
|
||||
import org.jdesktop.swingx.tips.DefaultTip;
|
||||
import org.jdesktop.swingx.tips.DefaultTipOfTheDayModel;
|
||||
import org.jdesktop.swingx.tips.TipOfTheDayModel.Tip;
|
||||
import com.formdev.flatlaf.testing.FlatTestFrame;
|
||||
import com.formdev.flatlaf.testing.FlatTestPanel;
|
||||
|
||||
@@ -69,6 +72,10 @@ public class FlatSwingXTest
|
||||
JProgressBar statusProgressBar = new JProgressBar();
|
||||
statusProgressBar.setValue( 50 );
|
||||
statusBar1.add( statusProgressBar, new JXStatusBar.Constraint( JXStatusBar.Constraint.ResizeBehavior.FILL ) );
|
||||
|
||||
xTipOfTheDay1.setModel( new DefaultTipOfTheDayModel( new Tip[] {
|
||||
new DefaultTip( "testTip", "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." )
|
||||
} ) );
|
||||
}
|
||||
|
||||
private void busyChanged() {
|
||||
@@ -77,6 +84,11 @@ public class FlatSwingXTest
|
||||
xBusyLabel2.setBusy( busy );
|
||||
}
|
||||
|
||||
private void showTipOfTheDayDialog() {
|
||||
JXTipOfTheDay tipOfTheDay = new JXTipOfTheDay( xTipOfTheDay1.getModel() );
|
||||
tipOfTheDay.showDialog( this );
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
JLabel label1 = new JLabel();
|
||||
@@ -138,6 +150,9 @@ public class FlatSwingXTest
|
||||
JXSearchField xSearchField4 = new JXSearchField();
|
||||
JLabel label12 = new JLabel();
|
||||
statusBar1 = new JXStatusBar();
|
||||
JLabel label13 = new JLabel();
|
||||
xTipOfTheDay1 = new JXTipOfTheDay();
|
||||
JButton showTipOfTheDayDialogButton = new JButton();
|
||||
JButton button1 = new JButton();
|
||||
JButton button2 = new JButton();
|
||||
|
||||
@@ -163,6 +178,7 @@ public class FlatSwingXTest
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[top]" +
|
||||
"[37]"));
|
||||
|
||||
//---- label1 ----
|
||||
@@ -354,14 +370,14 @@ public class FlatSwingXTest
|
||||
//---- table ----
|
||||
table.setModel(new DefaultTableModel(
|
||||
new Object[][] {
|
||||
{new Date(1574636400000L) /* 25.11.2019, 00:00:00 */},
|
||||
{new Date(1517439600000L) /* 01.02.2018, 00:00:00 */},
|
||||
{new Date(1574636400000L) /* 2019-11-25 */},
|
||||
{new Date(1517439600000L) /* 2018-02-01 */},
|
||||
},
|
||||
new String[] {
|
||||
"Date"
|
||||
}
|
||||
) {
|
||||
Class<?>[] columnTypes = new Class<?>[] {
|
||||
Class<?>[] columnTypes = {
|
||||
Date.class
|
||||
};
|
||||
@Override
|
||||
@@ -471,6 +487,16 @@ public class FlatSwingXTest
|
||||
add(label12, "cell 0 11");
|
||||
add(statusBar1, "cell 1 11 3 1,grow");
|
||||
|
||||
//---- label13 ----
|
||||
label13.setText("JXTipOfTheDay:");
|
||||
add(label13, "cell 0 12");
|
||||
add(xTipOfTheDay1, "cell 1 12 3 1");
|
||||
|
||||
//---- showTipOfTheDayDialogButton ----
|
||||
showTipOfTheDayDialogButton.setText("Show Dialog...");
|
||||
showTipOfTheDayDialogButton.addActionListener(e -> showTipOfTheDayDialog());
|
||||
add(showTipOfTheDayDialogButton, "cell 1 12 3 1");
|
||||
|
||||
//---- button1 ----
|
||||
button1.setText("<");
|
||||
|
||||
@@ -492,5 +518,6 @@ public class FlatSwingXTest
|
||||
private JCheckBox busyCheckBox;
|
||||
private JTable table;
|
||||
private JXStatusBar statusBar1;
|
||||
private JXTipOfTheDay xTipOfTheDay1;
|
||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.5.0.404" Java: "17" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -9,7 +9,7 @@ new FormModel {
|
||||
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[left][][][][fill]"
|
||||
"$rowConstraints": "[]0[][]0[top][][][][][][][][][37]"
|
||||
"$rowConstraints": "[]0[][]0[top][][][][][][][][][top][37]"
|
||||
} ) {
|
||||
name: "this"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
@@ -402,9 +402,30 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 11 3 1,grow"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "label13"
|
||||
"text": "JXTipOfTheDay:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 12"
|
||||
} )
|
||||
add( new FormComponent( "org.jdesktop.swingx.JXTipOfTheDay" ) {
|
||||
name: "xTipOfTheDay1"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 12 3 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "showTipOfTheDayDialogButton"
|
||||
"text": "Show Dialog..."
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTipOfTheDayDialog", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 12 3 1"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 795, 600 )
|
||||
"size": new java.awt.Dimension( 900, 820 )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button1"
|
||||
|
||||
@@ -38,6 +38,7 @@ import java.lang.reflect.Field;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -45,6 +46,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Predicate;
|
||||
import javax.swing.*;
|
||||
import javax.swing.UIDefaults.ActiveValue;
|
||||
@@ -58,11 +60,13 @@ import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicLookAndFeel;
|
||||
import javax.swing.table.JTableHeader;
|
||||
import com.formdev.flatlaf.*;
|
||||
import com.formdev.flatlaf.demo.intellijthemes.IJThemesDump;
|
||||
import com.formdev.flatlaf.intellijthemes.FlatAllIJThemes;
|
||||
import com.formdev.flatlaf.testing.FlatTestLaf;
|
||||
import com.formdev.flatlaf.themes.*;
|
||||
import com.formdev.flatlaf.ui.FlatLineBorder;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.ColorFunctions;
|
||||
import com.formdev.flatlaf.util.ColorFunctions.ColorFunction;
|
||||
import com.jidesoft.plaf.LookAndFeelFactory;
|
||||
import com.formdev.flatlaf.util.DerivedColor;
|
||||
@@ -102,9 +106,9 @@ public class UIDefaultsDump
|
||||
|
||||
dump( FlatMacLightLaf.class.getName(), dir, false );
|
||||
dump( FlatMacDarkLaf.class.getName(), dir, false );
|
||||
}
|
||||
|
||||
dump( FlatTestLaf.class.getName(), dir, false );
|
||||
dump( FlatTestLaf.class.getName(), dir, false );
|
||||
}
|
||||
|
||||
// dump( MyBasicLookAndFeel.class.getName(), dir, false );
|
||||
// dump( MetalLookAndFeel.class.getName(), dir, false );
|
||||
@@ -152,6 +156,8 @@ public class UIDefaultsDump
|
||||
private static void dumpIntelliJThemes( File dir ) {
|
||||
dir = new File( dir, "intellijthemes" );
|
||||
|
||||
IJThemesDump.enablePropertiesRecording();
|
||||
|
||||
for( LookAndFeelInfo info : FlatAllIJThemes.INFOS ) {
|
||||
String lafClassName = info.getClassName();
|
||||
String relativeLafClassName = StringUtils.removeLeading( lafClassName, "com.formdev.flatlaf.intellijthemes." );
|
||||
@@ -164,6 +170,8 @@ public class UIDefaultsDump
|
||||
}
|
||||
|
||||
private static void dump( String lookAndFeelClassName, File dir, boolean jide ) {
|
||||
System.out.println( "---- "+lookAndFeelClassName+" -------------------------------" );
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel( lookAndFeelClassName );
|
||||
if( jide )
|
||||
@@ -181,20 +189,32 @@ public class UIDefaultsDump
|
||||
// the lazy color InternalFrame.closeHoverBackground is resolved)
|
||||
defaults = (UIDefaults) defaults.clone();
|
||||
|
||||
dump( dir, "", lookAndFeel, defaults, key -> !key.contains( "InputMap" ) );
|
||||
dump( dir, "", lookAndFeel, defaults, key -> !key.contains( "InputMap" ), true );
|
||||
|
||||
if( lookAndFeel.getClass() == FlatLightLaf.class || !(lookAndFeel instanceof FlatLaf) ) {
|
||||
dump( dir, "_InputMap", lookAndFeel, defaults, key -> key.contains( "InputMap" ) );
|
||||
dumpActionMaps( dir, "_ActionMap", lookAndFeel, defaults );
|
||||
if( SystemInfo.isWindows || SystemInfo.isMacOS )
|
||||
dump( dir, "_InputMap", lookAndFeel, defaults, key -> key.contains( "InputMap" ), false );
|
||||
|
||||
if( SystemInfo.isWindows )
|
||||
dumpActionMaps( dir, "_ActionMap", lookAndFeel, defaults );
|
||||
}
|
||||
|
||||
if( lookAndFeel instanceof IntelliJTheme.ThemeLaf ) {
|
||||
File cdir = new File( dir.getPath().replace( "intellijthemes", "intellijthemes-colors" ) );
|
||||
dumpColorsToProperties( cdir, lookAndFeel, defaults );
|
||||
|
||||
// dump as .properties
|
||||
File pdir = new File( dir.getPath().replace( "intellijthemes", "intellijthemes-properties" ) );
|
||||
IJThemesDump.dumpProperties( pdir, lookAndFeel.getClass().getSimpleName(), defaults );
|
||||
}
|
||||
}
|
||||
|
||||
private static void dump( File dir, String nameSuffix,
|
||||
LookAndFeel lookAndFeel, UIDefaults defaults, Predicate<String> keyFilter )
|
||||
LookAndFeel lookAndFeel, UIDefaults defaults, Predicate<String> keyFilter, boolean contrastRatios )
|
||||
{
|
||||
// dump to string
|
||||
StringWriter stringWriter = new StringWriter( 100000 );
|
||||
new UIDefaultsDump( lookAndFeel, defaults ).dump( new PrintWriter( stringWriter ), keyFilter );
|
||||
new UIDefaultsDump( lookAndFeel, defaults ).dump( new PrintWriter( stringWriter ), keyFilter, contrastRatios );
|
||||
|
||||
String name = lookAndFeel instanceof MyBasicLookAndFeel
|
||||
? BasicLookAndFeel.class.getSimpleName()
|
||||
@@ -226,8 +246,8 @@ public class UIDefaultsDump
|
||||
if( origFile != null ) {
|
||||
try {
|
||||
Map<String, String> defaults1 = parse( new InputStreamReader(
|
||||
new FileInputStream( origFile ), StandardCharsets.UTF_8 ) );
|
||||
Map<String, String> defaults2 = parse( new StringReader( stringWriter.toString() ) );
|
||||
new FileInputStream( origFile ), StandardCharsets.UTF_8 ), false );
|
||||
Map<String, String> defaults2 = parse( new StringReader( stringWriter.toString() ), false );
|
||||
|
||||
content = diff( defaults1, defaults2 );
|
||||
} catch( Exception ex ) {
|
||||
@@ -275,6 +295,45 @@ public class UIDefaultsDump
|
||||
}
|
||||
}
|
||||
|
||||
private static void dumpColorsToProperties( File dir, LookAndFeel lookAndFeel, UIDefaults defaults ) {
|
||||
// dump to string
|
||||
StringWriter stringWriter = new StringWriter( 100000 );
|
||||
new UIDefaultsDump( lookAndFeel, defaults ).dumpColorsAsProperties( new PrintWriter( stringWriter ) );
|
||||
|
||||
String name = lookAndFeel instanceof MyBasicLookAndFeel
|
||||
? BasicLookAndFeel.class.getSimpleName()
|
||||
: lookAndFeel.getClass().getSimpleName();
|
||||
File file = new File( dir, name + ".properties" );
|
||||
|
||||
// build and append differences
|
||||
if( file.exists() ) {
|
||||
try {
|
||||
Map<String, String> defaults1 = parse( new InputStreamReader(
|
||||
new FileInputStream( file ), StandardCharsets.UTF_8 ), true );
|
||||
Map<String, String> defaults2 = parse( new StringReader( stringWriter.toString() ), true );
|
||||
|
||||
String diff = diff( defaults1, defaults2 );
|
||||
if( !diff.isEmpty() ) {
|
||||
stringWriter.write( "\n\n\n\n#==== Differences ==============================================================\n\n" );
|
||||
stringWriter.write( diff );
|
||||
}
|
||||
} catch( Exception ex ) {
|
||||
ex.printStackTrace();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// write to file
|
||||
file.getParentFile().mkdirs();
|
||||
try( Writer fileWriter = new OutputStreamWriter(
|
||||
new FileOutputStream( file ), StandardCharsets.UTF_8 ) )
|
||||
{
|
||||
fileWriter.write( stringWriter.toString().replace( "\r", "" ) );
|
||||
} catch( IOException ex ) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static String diff( Map<String, String> defaults1, Map<String, String> defaults2 ) {
|
||||
TreeSet<String> keys = new TreeSet<>();
|
||||
keys.addAll( defaults1.keySet() );
|
||||
@@ -350,19 +409,25 @@ public class UIDefaultsDump
|
||||
buf.append( '\n' );
|
||||
}
|
||||
|
||||
private static Map<String, String> parse( Reader in ) throws IOException {
|
||||
private static Map<String, String> parse( Reader in, boolean ignoreDiffs ) throws IOException {
|
||||
Map<String, String> defaults = new LinkedHashMap<>();
|
||||
try( BufferedReader reader = new BufferedReader( in ) ) {
|
||||
String lastKey = null;
|
||||
boolean inContrastRatios = false;
|
||||
|
||||
String line;
|
||||
while( (line = reader.readLine()) != null ) {
|
||||
String trimmedLine = line.trim();
|
||||
if( trimmedLine.isEmpty() || trimmedLine.startsWith( "#" ) ) {
|
||||
lastKey = null;
|
||||
if( trimmedLine.contains( "#-------- Contrast Ratios --------" ) )
|
||||
inContrastRatios = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if( ignoreDiffs && (trimmedLine.startsWith( "- " ) || trimmedLine.startsWith( "+ " )) )
|
||||
continue;
|
||||
|
||||
if( Character.isWhitespace( line.charAt( 0 ) ) ) {
|
||||
String value = defaults.get( lastKey );
|
||||
value += '\n' + line;
|
||||
@@ -374,6 +439,8 @@ public class UIDefaultsDump
|
||||
|
||||
String key = line.substring( 0, sep );
|
||||
String value = line.substring( sep );
|
||||
if( inContrastRatios )
|
||||
key = "contrast ratio: " + key;
|
||||
defaults.put( key, value );
|
||||
|
||||
lastKey = key;
|
||||
@@ -403,12 +470,12 @@ public class UIDefaultsDump
|
||||
out.printf( "OS %s%n", System.getProperty( "os.name" ) );
|
||||
}
|
||||
|
||||
private void dump( PrintWriter out, Predicate<String> keyFilter ) {
|
||||
private void dump( PrintWriter out, Predicate<String> keyFilter, boolean contrastRatios ) {
|
||||
dumpHeader( out );
|
||||
|
||||
defaults.entrySet().stream()
|
||||
.sorted( (key1, key2) -> {
|
||||
return String.valueOf( key1 ).compareTo( String.valueOf( key2 ) );
|
||||
.sorted( (e1, e2) -> {
|
||||
return String.valueOf( e1.getKey() ).compareTo( String.valueOf( e2.getKey() ) );
|
||||
} )
|
||||
.forEach( entry -> {
|
||||
Object key = entry.getKey();
|
||||
@@ -428,6 +495,33 @@ public class UIDefaultsDump
|
||||
dumpValue( out, strKey, value );
|
||||
out.println();
|
||||
} );
|
||||
|
||||
if( contrastRatios )
|
||||
dumpContrastRatios( out );
|
||||
}
|
||||
|
||||
private void dumpColorsAsProperties( PrintWriter out ) {
|
||||
defaults.keySet().stream()
|
||||
.sorted( (key1, key2) -> {
|
||||
return String.valueOf( key1 ).compareTo( String.valueOf( key2 ) );
|
||||
} )
|
||||
.forEach( key -> {
|
||||
Color color = defaults.getColor( key );
|
||||
if( color == null )
|
||||
return;
|
||||
|
||||
String strKey = String.valueOf( key );
|
||||
String prefix = keyPrefix( strKey );
|
||||
if( !prefix.equals( lastPrefix ) ) {
|
||||
lastPrefix = prefix;
|
||||
out.printf( "%n%n#---- %s ----%n%n", prefix );
|
||||
}
|
||||
|
||||
out.printf( "%-50s = #%06x", strKey, color.getRGB() & 0xffffff );
|
||||
if( color.getAlpha() != 255 )
|
||||
out.printf( "%02x", (color.getRGB() >> 24) & 0xff );
|
||||
out.println();
|
||||
} );
|
||||
}
|
||||
|
||||
private void dumpActionMaps( PrintWriter out ) {
|
||||
@@ -829,6 +923,161 @@ public class UIDefaultsDump
|
||||
return new Color( newColor.getRGB(), true );
|
||||
}
|
||||
|
||||
private void dumpContrastRatios( PrintWriter out ) {
|
||||
out.printf( "%n%n#-------- Contrast Ratios --------%n%n" );
|
||||
out.println( "# WCAG 2 Contrast Requirements: minimum 4.5; enhanced 7.0" );
|
||||
out.println( "# https://webaim.org/articles/contrast/#sc143" );
|
||||
out.println();
|
||||
|
||||
HashMap<String, String> fg2bgMap = new HashMap<>();
|
||||
defaults.keySet().stream()
|
||||
.filter( key -> key instanceof String && ((String)key).endsWith( "ackground" ) )
|
||||
.map( key -> (String) key )
|
||||
.forEach( bgKey -> {
|
||||
String fgKey = bgKey.replace( "Background", "Foreground" ).replace( "background", "foreground" );
|
||||
fg2bgMap.put( fgKey, bgKey );
|
||||
} );
|
||||
|
||||
// special cases
|
||||
fg2bgMap.remove( "Button.disabledForeground" );
|
||||
fg2bgMap.put( "Button.disabledText", "Button.disabledBackground" );
|
||||
fg2bgMap.remove( "ToggleButton.disabledForeground" );
|
||||
fg2bgMap.put( "ToggleButton.disabledText", "ToggleButton.disabledBackground" );
|
||||
fg2bgMap.put( "CheckBox.foreground", "Panel.background" );
|
||||
fg2bgMap.put( "CheckBox.disabledText", "Panel.background" );
|
||||
fg2bgMap.put( "Label.foreground", "Panel.background" );
|
||||
fg2bgMap.put( "Label.disabledForeground", "Panel.background" );
|
||||
fg2bgMap.remove( "ProgressBar.foreground" );
|
||||
fg2bgMap.put( "ProgressBar.selectionForeground", "ProgressBar.foreground" );
|
||||
fg2bgMap.put( "ProgressBar.selectionBackground", "ProgressBar.background" );
|
||||
fg2bgMap.put( "RadioButton.foreground", "Panel.background" );
|
||||
fg2bgMap.put( "RadioButton.disabledText", "Panel.background" );
|
||||
fg2bgMap.remove( "ScrollBar.foreground" );
|
||||
fg2bgMap.remove( "ScrollBar.hoverButtonForeground" );
|
||||
fg2bgMap.remove( "ScrollBar.pressedButtonForeground" );
|
||||
fg2bgMap.remove( "ScrollPane.foreground" );
|
||||
fg2bgMap.remove( "Separator.foreground" );
|
||||
fg2bgMap.remove( "Slider.foreground" );
|
||||
fg2bgMap.remove( "SplitPane.foreground" );
|
||||
fg2bgMap.remove( "TextArea.disabledForeground" );
|
||||
fg2bgMap.put( "TextArea.inactiveForeground", "TextArea.disabledBackground" );
|
||||
fg2bgMap.remove( "TextPane.disabledForeground" );
|
||||
fg2bgMap.put( "TextPane.inactiveForeground", "TextPane.disabledBackground" );
|
||||
fg2bgMap.remove( "EditorPane.disabledForeground" );
|
||||
fg2bgMap.put( "EditorPane.inactiveForeground", "EditorPane.disabledBackground" );
|
||||
fg2bgMap.remove( "TextField.disabledForeground" );
|
||||
fg2bgMap.put( "TextField.inactiveForeground", "TextField.disabledBackground" );
|
||||
fg2bgMap.remove( "FormattedTextField.disabledForeground" );
|
||||
fg2bgMap.put( "FormattedTextField.inactiveForeground", "FormattedTextField.disabledBackground" );
|
||||
fg2bgMap.remove( "PasswordField.disabledForeground" );
|
||||
fg2bgMap.put( "PasswordField.inactiveForeground", "PasswordField.disabledBackground" );
|
||||
fg2bgMap.remove( "ToolBar.dockingForeground" );
|
||||
fg2bgMap.remove( "ToolBar.floatingForeground" );
|
||||
fg2bgMap.remove( "ToolBar.foreground" );
|
||||
fg2bgMap.remove( "ToolBar.hoverButtonGroupForeground" );
|
||||
fg2bgMap.remove( "Viewport.foreground" );
|
||||
|
||||
fg2bgMap.remove( "InternalFrame.closeHoverForeground" );
|
||||
fg2bgMap.remove( "InternalFrame.closePressedForeground" );
|
||||
fg2bgMap.remove( "TabbedPane.closeHoverForeground" );
|
||||
fg2bgMap.remove( "TabbedPane.closePressedForeground" );
|
||||
fg2bgMap.remove( "TitlePane.closeHoverForeground" );
|
||||
fg2bgMap.remove( "TitlePane.closePressedForeground" );
|
||||
|
||||
// non-text
|
||||
HashMap<String, String> nonTextMap = new HashMap<>();
|
||||
nonTextMap.put( "Menu.icon.arrowColor", "Panel.background" );
|
||||
nonTextMap.put( "Menu.icon.disabledArrowColor", "Panel.background" );
|
||||
nonTextMap.put( "CheckBoxMenuItem.icon.checkmarkColor", "Panel.background" );
|
||||
nonTextMap.put( "CheckBoxMenuItem.icon.disabledCheckmarkColor", "Panel.background" );
|
||||
nonTextMap.put( "ProgressBar.foreground", "Panel.background" );
|
||||
nonTextMap.put( "ProgressBar.background", "Panel.background" );
|
||||
nonTextMap.put( "Separator.foreground", "Separator.background" );
|
||||
nonTextMap.put( "Slider.trackColor", "Panel.background" );
|
||||
nonTextMap.put( "Slider.trackValueColor", "Panel.background" );
|
||||
nonTextMap.put( "Slider.disabledTrackColor", "Panel.background" );
|
||||
nonTextMap.put( "TabbedPane.contentAreaColor", "Panel.background" );
|
||||
nonTextMap.put( "ToolBar.separatorColor", "ToolBar.background" );
|
||||
|
||||
|
||||
// out.println();
|
||||
// fg2bgMap.entrySet().stream()
|
||||
// .sorted( (e1, e2) -> e1.getKey().compareTo( e2.getKey() ) )
|
||||
// .forEach( e -> {
|
||||
// out.printf( "%-50s %s%n", e.getKey(), e.getValue() );
|
||||
// } );
|
||||
// out.println();
|
||||
|
||||
AtomicReference<String> lastSubkey = new AtomicReference<>();
|
||||
|
||||
fg2bgMap.entrySet().stream()
|
||||
.sorted( (e1, e2) -> {
|
||||
String key1 = e1.getKey();
|
||||
String key2 = e2.getKey();
|
||||
int dot1 = key1.lastIndexOf( '.' );
|
||||
int dot2 = key2.lastIndexOf( '.' );
|
||||
if( dot1 < 0 || dot2 < 0 )
|
||||
return key1.compareTo( key2 );
|
||||
int r = key1.substring( dot1 + 1 ).compareTo( key2.substring( dot2 + 1 ) );
|
||||
if( r != 0 )
|
||||
return r;
|
||||
return key1.substring( 0, dot1 ).compareTo( key2.substring( 0, dot2 ) );
|
||||
} )
|
||||
.forEach( e -> {
|
||||
dumpContrastRatio( out, e.getKey(), e.getValue(), lastSubkey );
|
||||
} );
|
||||
|
||||
out.println();
|
||||
out.println( "#-- non-text --" );
|
||||
nonTextMap.entrySet().stream()
|
||||
.sorted( (e1, e2) -> {
|
||||
return e1.getKey().compareTo( e2.getKey() );
|
||||
} )
|
||||
.forEach( e -> {
|
||||
dumpContrastRatio( out, e.getKey(), e.getValue(), null );
|
||||
} );
|
||||
}
|
||||
|
||||
private void dumpContrastRatio( PrintWriter out, String fgKey, String bgKey, AtomicReference<String> lastSubkey ) {
|
||||
Color background = defaults.getColor( bgKey );
|
||||
Color foreground = defaults.getColor( fgKey );
|
||||
if( background == null || foreground == null )
|
||||
return;
|
||||
|
||||
String subkey = fgKey.substring( fgKey.lastIndexOf( '.' ) + 1 );
|
||||
if( lastSubkey != null && !subkey.equals( lastSubkey.get() ) ) {
|
||||
lastSubkey.set( subkey );
|
||||
out.println();
|
||||
out.println( "#-- " + subkey + " --" );
|
||||
}
|
||||
|
||||
Color translucentForeground = null;
|
||||
if( foreground.getAlpha() != 255 ) {
|
||||
translucentForeground = foreground;
|
||||
float weight = foreground.getAlpha() / 255f;
|
||||
foreground = ColorFunctions.mix( new Color( foreground.getRGB() ), background, weight );
|
||||
}
|
||||
|
||||
float luma1 = ColorFunctions.luma( background );
|
||||
float luma2 = ColorFunctions.luma( foreground );
|
||||
float contrastRatio = (luma1 > luma2)
|
||||
? (luma1 + 0.05f) / (luma2 + 0.05f)
|
||||
: (luma2 + 0.05f) / (luma1 + 0.05f);
|
||||
String rateing =
|
||||
contrastRatio < 1.95f ? " !!!!!!" :
|
||||
contrastRatio < 2.95f ? " !!!!!" :
|
||||
contrastRatio < 3.95f ? " !!!!" :
|
||||
contrastRatio < 4.95f ? " !!!" :
|
||||
contrastRatio < 5.95f ? " !!" :
|
||||
contrastRatio < 6.95f ? " !" :
|
||||
"";
|
||||
|
||||
out.printf( "%-50s #%06x #%06x %4.1f%s%s%n", fgKey,
|
||||
foreground.getRGB() & 0xffffff, background.getRGB() & 0xffffff,
|
||||
contrastRatio, rateing,
|
||||
translucentForeground != null ? " " + dumpColorHex( translucentForeground ) : "" );
|
||||
}
|
||||
|
||||
//---- class MyBasicLookAndFeel -------------------------------------------
|
||||
|
||||
public static class MyBasicLookAndFeel
|
||||
|
||||
@@ -463,6 +463,24 @@ TitlePane.foreground = #00f
|
||||
TitlePane.inactiveForeground = #fff
|
||||
TitlePane.borderColor = #f00
|
||||
|
||||
TitlePane.buttonBackground = #fff
|
||||
TitlePane.buttonForeground = #000
|
||||
TitlePane.buttonInactiveBackground = #ddd
|
||||
TitlePane.buttonInactiveForeground = #00f
|
||||
TitlePane.buttonHoverBackground = #bbb
|
||||
TitlePane.buttonHoverForeground = #0f0
|
||||
TitlePane.buttonPressedBackground = #999
|
||||
TitlePane.buttonPressedForeground = #f00
|
||||
|
||||
TitlePane.closeBackground = #f00
|
||||
TitlePane.closeForeground = #000
|
||||
TitlePane.closeInactiveBackground = #d00
|
||||
TitlePane.closeInactiveForeground = #0ff
|
||||
TitlePane.closeHoverBackground = #b00
|
||||
TitlePane.closeHoverForeground = #f0f
|
||||
TitlePane.closePressedBackground = #900
|
||||
TitlePane.closePressedForeground = #0f0
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
|
||||
Reference in New Issue
Block a user