OptionPane: fixed styling custom panel background in JOptionPane (issue #761)

This commit is contained in:
Karl Tauber
2023-11-14 10:38:28 +01:00
parent 61ba011c3b
commit 7d0bdf3b9e
3 changed files with 40 additions and 21 deletions

View File

@@ -13,6 +13,8 @@ FlatLaf Change Log
foreground color. (issue 756) foreground color. (issue 756)
- Table: Switching theme looses table grid and intercell spacing. (issues #733 - Table: Switching theme looses table grid and intercell spacing. (issues #733
and #750) and #750)
- OptionPane: Fixed styling custom panel background in `JOptionPane`. (issue
#761)
## 3.2.5 ## 3.2.5

View File

@@ -30,9 +30,7 @@ import javax.swing.JPanel;
import javax.swing.JRootPane; import javax.swing.JRootPane;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicHTML; import javax.swing.plaf.basic.BasicHTML;
import javax.swing.plaf.basic.BasicOptionPaneUI; import javax.swing.plaf.basic.BasicOptionPaneUI;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
@@ -115,13 +113,6 @@ public class FlatOptionPaneUI
sameSizeButtons = FlatUIUtils.getUIBoolean( "OptionPane.sameSizeButtons", true ); sameSizeButtons = FlatUIUtils.getUIBoolean( "OptionPane.sameSizeButtons", true );
} }
@Override
protected void installComponents() {
super.installComponents();
updateChildPanels( optionPane );
}
@Override @Override
protected PropertyChangeListener createPropertyChangeListener() { protected PropertyChangeListener createPropertyChangeListener() {
PropertyChangeListener superListener = super.createPropertyChangeListener(); PropertyChangeListener superListener = super.createPropertyChangeListener();
@@ -155,6 +146,13 @@ public class FlatOptionPaneUI
protected Container createMessageArea() { protected Container createMessageArea() {
Container messageArea = super.createMessageArea(); Container messageArea = super.createMessageArea();
// use non-UIResource OptionPane.messageAreaBorder to avoid that it is replaced when switching LaF
// and make panel non-opaque for OptionPane.background
updateAreaPanel( messageArea );
// make known sub-panels non-opaque for OptionPane.background
updateKnownChildPanels( messageArea );
// set icon-message gap // set icon-message gap
if( iconMessageGap > 0 ) { if( iconMessageGap > 0 ) {
Component iconMessageSeparator = SwingUtils.getComponentByName( messageArea, "OptionPane.separator" ); Component iconMessageSeparator = SwingUtils.getComponentByName( messageArea, "OptionPane.separator" );
@@ -169,6 +167,10 @@ public class FlatOptionPaneUI
protected Container createButtonArea() { protected Container createButtonArea() {
Container buttonArea = super.createButtonArea(); Container buttonArea = super.createButtonArea();
// use non-UIResource OptionPane.buttonAreaBorder to avoid that it is replaced when switching LaF
// and make panel non-opaque for OptionPane.background
updateAreaPanel( buttonArea );
// scale button padding and subtract focusWidth // scale button padding and subtract focusWidth
if( buttonArea.getLayout() instanceof ButtonAreaLayout ) { if( buttonArea.getLayout() instanceof ButtonAreaLayout ) {
ButtonAreaLayout layout = (ButtonAreaLayout) buttonArea.getLayout(); ButtonAreaLayout layout = (ButtonAreaLayout) buttonArea.getLayout();
@@ -218,22 +220,33 @@ public class FlatOptionPaneUI
super.addMessageComponents( container, cons, msg, maxll, internallyCreated ); super.addMessageComponents( container, cons, msg, maxll, internallyCreated );
} }
private void updateChildPanels( Container c ) { private void updateAreaPanel( Container area ) {
if( !(area instanceof JPanel) )
return;
// use non-UIResource border to avoid that it is replaced when switching LaF
// and make panel non-opaque for OptionPane.background
JPanel panel = (JPanel) area;
panel.setBorder( FlatUIUtils.nonUIResource( panel.getBorder() ) );
panel.setOpaque( false );
}
private void updateKnownChildPanels( Container c ) {
for( Component child : c.getComponents() ) { for( Component child : c.getComponents() ) {
if( child.getClass() == JPanel.class ) { if( child instanceof JPanel && child.getName() != null ) {
JPanel panel = (JPanel)child; switch( child.getName() ) {
case "OptionPane.realBody":
// make sub-panel non-opaque for OptionPane.background case "OptionPane.body":
panel.setOpaque( false ); case "OptionPane.separator":
case "OptionPane.break":
// use non-UIResource borders to avoid that they are replaced when switching LaF // make known sub-panels non-opaque for OptionPane.background
Border border = panel.getBorder(); ((JPanel)child).setOpaque( false );
if( border instanceof UIResource ) break;
panel.setBorder( FlatUIUtils.nonUIResource( border ) ); }
} }
if( child instanceof Container ) if( child instanceof Container )
updateChildPanels( (Container) child ); updateKnownChildPanels( (Container) child );
} }
} }

View File

@@ -41,11 +41,15 @@ public class FlatOptionPaneTest
FlatOptionPaneTest() { FlatOptionPaneTest() {
initComponents(); initComponents();
JPanel panel = new JPanel();
panel.setBackground( Color.green );
panel.add( new JLabel( "label in green panel" ) );
customOptionPane.setMessage( new Object[] { customOptionPane.setMessage( new Object[] {
"string", "string",
"multi-\nline string", "multi-\nline string",
new JCheckBox( "check box" ), new JCheckBox( "check box" ),
new JTextField( "text field" ), new JTextField( "text field" ),
panel,
"more text", "more text",
} ); } );
customOptionPane.setOptions( new Object[] { customOptionPane.setOptions( new Object[] {