From 28cdde3f17f31c425af518cc74ad3b15256fa167 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 2 Feb 2023 11:50:13 +0100 Subject: [PATCH] Tree: fixed truncated node text and too small painted non-wide node background if custom cell renderer sets icon, but not disabled icon, and tree is disabled (issue #640) --- CHANGELOG.md | 3 ++ .../com/formdev/flatlaf/ui/FlatTreeUI.java | 17 ++++++- .../flatlaf/testing/FlatComponents2Test.java | 44 +++++++++++++++---- .../flatlaf/testing/FlatComponents2Test.jfd | 5 ++- 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74653744..99d6b0a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,9 @@ FlatLaf Change Log - Updated "Hiberbee Dark" and "Material Theme UI Lite" themes. - Styling: Fixed resolving of UI variables in styles that use other variables. - MenuItem: Fixed horizontal alignment of icons. (issue #631) +- Tree: Fixed truncated node text and too small painted non-wide node background + if custom cell renderer sets icon, but not disabled icon, and tree is + disabled. (issue #640) ## 3.0 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java index 381d3c85..db52cd36 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTreeUI.java @@ -310,6 +310,21 @@ public class FlatTreeUI tree.revalidate(); tree.repaint(); break; + + case "enabled": + // if default icons are not shown and the renderer is a subclass + // of DefaultTreeCellRenderer, then invalidate tree node sizes + // because the custom renderer may use an icon for enabled state + // but none for disabled state + if( !showDefaultIcons && + currentCellRenderer instanceof DefaultTreeCellRenderer && + currentCellRenderer.getClass() != DefaultTreeCellRenderer.class && + treeState != null ) + { + treeState.invalidateSizes(); + updateSize(); + } + break; } } }; @@ -695,7 +710,7 @@ public class FlatTreeUI if( rendererComponent instanceof JLabel ) { JLabel label = (JLabel) rendererComponent; - Icon icon = label.getIcon(); + Icon icon = label.isEnabled() ? label.getIcon() : label.getDisabledIcon(); imageOffset = (icon != null && label.getText() != null) ? icon.getIconWidth() + Math.max( label.getIconTextGap() - 1, 0 ) : 0; diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.java index 7aae5a27..74836658 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.java @@ -439,6 +439,11 @@ public class FlatComponents2Test tree.setCellRenderer( new TestDefaultTreeCellRenderer() ); break; + case "defaultWithIcon": + for( JTree tree : trees ) + tree.setCellRenderer( new TestDefaultWithIconTreeCellRenderer() ); + break; + case "label": for( JTree tree : trees ) tree.setCellRenderer( new TestLabelTreeCellRenderer() ); @@ -495,11 +500,13 @@ public class FlatComponents2Test tree.setEditable( editable ); } - private void showDefaultIcons() { - boolean showDefaultIcons = showDefaultIconsCheckBox.isSelected(); + private void treeShowDefaultIconsChanged() { + boolean showDefaultIcons = treeShowDefaultIconsCheckBox.isSelected(); UIManager.put( "Tree.showDefaultIcons", showDefaultIcons ? true : null ); for( JTree tree : allTrees ) tree.updateUI(); + + treeRendererChanged(); } private void treeMouseClicked( MouseEvent e ) { @@ -601,7 +608,7 @@ public class FlatComponents2Test treePaintLinesCheckBox = new JCheckBox(); treeRedLinesCheckBox = new JCheckBox(); treeEditableCheckBox = new JCheckBox(); - showDefaultIconsCheckBox = new JCheckBox(); + treeShowDefaultIconsCheckBox = new JCheckBox(); JPanel tableOptionsPanel = new JPanel(); JLabel autoResizeModeLabel = new JLabel(); autoResizeModeField = new JComboBox<>(); @@ -953,6 +960,7 @@ public class FlatComponents2Test treeRendererComboBox.setModel(new DefaultComboBoxModel<>(new String[] { "default", "defaultSubclass", + "defaultWithIcon", "label", "swingxDefault", "jideCheckBox", @@ -988,10 +996,10 @@ public class FlatComponents2Test treeEditableCheckBox.addActionListener(e -> treeEditableChanged()); treeOptionsPanel.add(treeEditableCheckBox, "cell 0 4"); - //---- showDefaultIconsCheckBox ---- - showDefaultIconsCheckBox.setText("show default icons"); - showDefaultIconsCheckBox.addActionListener(e -> showDefaultIcons()); - treeOptionsPanel.add(showDefaultIconsCheckBox, "cell 0 4"); + //---- treeShowDefaultIconsCheckBox ---- + treeShowDefaultIconsCheckBox.setText("show default icons"); + treeShowDefaultIconsCheckBox.addActionListener(e -> treeShowDefaultIconsChanged()); + treeOptionsPanel.add(treeShowDefaultIconsCheckBox, "cell 0 4"); } add(treeOptionsPanel, "cell 0 4 4 1"); @@ -1128,7 +1136,7 @@ public class FlatComponents2Test private JCheckBox treePaintLinesCheckBox; private JCheckBox treeRedLinesCheckBox; private JCheckBox treeEditableCheckBox; - private JCheckBox showDefaultIconsCheckBox; + private JCheckBox treeShowDefaultIconsCheckBox; private JComboBox autoResizeModeField; private JComboBox sortIconPositionComboBox; private JCheckBox showHorizontalLinesCheckBox; @@ -1604,6 +1612,26 @@ public class FlatComponents2Test } } + //---- class TestDefaultWithIconTreeCellRenderer -------------------------- + + private static class TestDefaultWithIconTreeCellRenderer + extends TestDefaultTreeCellRenderer + { + @Override + public Component getTreeCellRendererComponent( JTree tree, Object value, boolean sel, boolean expanded, + boolean leaf, int row, boolean hasFocus ) + { + super.getTreeCellRendererComponent( tree, value, sel, expanded, leaf, row, hasFocus ); + + // set icon for enabled state, but not for disabled state, + // which allows testing whether tree node layout is updated correctly + // when enabled state changes + setIcon( UIManager.getIcon( "FileView.floppyDriveIcon" ) ); + + return this; + } + } + //---- class TestLabelTreeCellRenderer ------------------------------------ private static class TestLabelTreeCellRenderer diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.jfd index 7155ba51..d2a79ac5 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatComponents2Test.jfd @@ -411,6 +411,7 @@ new FormModel { selectedItem: "default" addElement( "default" ) addElement( "defaultSubclass" ) + addElement( "defaultWithIcon" ) addElement( "label" ) addElement( "swingxDefault" ) addElement( "jideCheckBox" ) @@ -476,12 +477,12 @@ new FormModel { "value": "cell 0 4" } ) add( new FormComponent( "javax.swing.JCheckBox" ) { - name: "showDefaultIconsCheckBox" + name: "treeShowDefaultIconsCheckBox" "text": "show default icons" auxiliary() { "JavaCodeGenerator.variableLocal": false } - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showDefaultIcons", false ) ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "treeShowDefaultIconsChanged", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 4" } )