Browse Source

Fixed paint loop for JButton.

Added option to convert all buttons that are icon only to shadow variants.
pull/75/head
weisj 5 years ago
parent
commit
792e987e82
  1. 4
      core/src/main/java/com/github/weisj/darklaf/components/ArrowButton.java
  2. 7
      core/src/main/java/com/github/weisj/darklaf/components/ClosableTabComponent.java
  3. 50
      core/src/main/java/com/github/weisj/darklaf/components/uiresource/JButtonUIResource.java
  4. 87
      core/src/main/java/com/github/weisj/darklaf/ui/button/AbstractButtonLayoutDelegate.java
  5. 17
      core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonBorder.java
  6. 217
      core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonUI.java
  7. 3
      core/src/main/java/com/github/weisj/darklaf/ui/colorchooser/DarkColorChooserPanel.java
  8. 7
      core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFileChooserUI.java
  9. 4
      core/src/main/java/com/github/weisj/darklaf/ui/internalframe/DarkDesktopIconUI.java
  10. 3
      core/src/main/java/com/github/weisj/darklaf/ui/internalframe/DarkInternalFrameTitlePane.java
  11. 3
      core/src/main/java/com/github/weisj/darklaf/ui/scrollpane/DarkScrollBarUI.java
  12. 1
      core/src/main/java/com/github/weisj/darklaf/ui/tabbedpane/DarkHandler.java
  13. 19
      core/src/main/java/com/github/weisj/darklaf/ui/tabbedpane/DarkTabbedPaneScrollLayout.java
  14. 9
      core/src/main/java/com/github/weisj/darklaf/ui/tabbedpane/NewTabButton.java
  15. 1
      core/src/main/java/com/github/weisj/darklaf/ui/tabbedpane/TabbedPaneScrollLayout.java
  16. 57
      core/src/main/java/com/github/weisj/darklaf/ui/toolbar/DarkToolBarBorder.java
  17. 1
      core/src/main/java/com/github/weisj/darklaf/ui/toolbar/DarkToolBarUI.java
  18. 1
      core/src/main/resources/com/github/weisj/darklaf/properties/overwrites.properties
  19. 1
      core/src/main/resources/com/github/weisj/darklaf/properties/ui/button.properties
  20. 4
      core/src/main/resources/com/github/weisj/darklaf/properties/ui/text.properties
  21. 1
      core/src/test/java/ui/tabbedPane/TabbedPaneDemo.java
  22. 2
      windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java

4
core/src/main/java/com/github/weisj/darklaf/components/ArrowButton.java

@ -70,6 +70,10 @@ public final class ArrowButton implements SwingConstants {
final int orientation, final boolean center, final int orientation, final boolean center,
final boolean applyInsetsOnSize, final Insets insets) { final boolean applyInsetsOnSize, final Insets insets) {
return new BasicArrowButton(orientation, null, null, null, null) { return new BasicArrowButton(orientation, null, null, null, null) {
{
putClientProperty("JButton.noShadowOverwrite", true);
}
@Override @Override
public void paint(final Graphics g) { public void paint(final Graphics g) {
int x = (getWidth() - getIcon().getIconWidth()) / 2; int x = (getWidth() - getIcon().getIconWidth()) / 2;

7
core/src/main/java/com/github/weisj/darklaf/components/ClosableTabComponent.java

@ -28,11 +28,7 @@ import com.github.weisj.darklaf.ui.tabbedpane.DarkTabbedPaneUI;
import javax.swing.*; import javax.swing.*;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import java.awt.*; import java.awt.*;
import java.awt.event.ActionEvent; import java.awt.event.*;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/** /**
* @author Jannis Weis * @author Jannis Weis
@ -96,6 +92,7 @@ public class ClosableTabComponent extends JPanel {
protected TabButton(final ClosableTabComponent tabComponent) { protected TabButton(final ClosableTabComponent tabComponent) {
this.tabComponent = tabComponent; this.tabComponent = tabComponent;
putClientProperty("JButton.variant", "onlyLabel"); putClientProperty("JButton.variant", "onlyLabel");
putClientProperty("JButton.noShadowOverwrite", true);
setOpaque(false); setOpaque(false);
setRolloverEnabled(true); setRolloverEnabled(true);
setIcon(UIManager.getIcon("TabbedPane.tabCloseIcon")); setIcon(UIManager.getIcon("TabbedPane.tabCloseIcon"));

50
core/src/main/java/com/github/weisj/darklaf/components/uiresource/JButtonUIResource.java

@ -0,0 +1,50 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.weisj.darklaf.components.uiresource;
import javax.swing.*;
import javax.swing.plaf.UIResource;
public class JButtonUIResource extends JButton implements UIResource {
public JButtonUIResource() {
super(null, null);
}
public JButtonUIResource(final Icon icon) {
super(null, icon);
}
public JButtonUIResource(final String text) {
super(text, null);
}
public JButtonUIResource(final Action a) {
super(a);
}
public JButtonUIResource(final String text, final Icon icon) {
super(text, icon);
}
}

87
core/src/main/java/com/github/weisj/darklaf/ui/button/AbstractButtonLayoutDelegate.java

@ -0,0 +1,87 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.weisj.darklaf.ui.button;
import javax.swing.*;
import java.awt.*;
public class AbstractButtonLayoutDelegate extends AbstractButton {
protected AbstractButton delegate;
public void setDelegate(final AbstractButton delegate) {
this.delegate = delegate;
if (delegate != null) putClientProperty("html", delegate.getClientProperty("html"));
}
@Override
public Icon getIcon() {
return delegate.getIcon();
}
@Override
public String getText() {
return delegate.getText();
}
@Override
public Font getFont() {
return delegate.getFont();
}
@Override
public FontMetrics getFontMetrics(final Font font) {
return delegate.getFontMetrics(font);
}
@Override
public int getVerticalAlignment() {
return delegate.getVerticalAlignment();
}
@Override
public int getHorizontalAlignment() {
return delegate.getHorizontalAlignment();
}
@Override
public int getVerticalTextPosition() {
return delegate.getVerticalTextPosition();
}
@Override
public int getHorizontalTextPosition() {
return delegate.getHorizontalTextPosition();
}
@Override
public Insets getInsets() {
return delegate.getInsets();
}
@Override
public ComponentOrientation getComponentOrientation() {
return delegate.getComponentOrientation();
}
}

17
core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonBorder.java

@ -177,22 +177,17 @@ public class DarkButtonBorder implements Border, UIResource {
if (DarkButtonUI.isLabelButton(c)) { if (DarkButtonUI.isLabelButton(c)) {
return new InsetsUIResource(labelInsets.top, labelInsets.left, labelInsets.bottom, labelInsets.right); return new InsetsUIResource(labelInsets.top, labelInsets.left, labelInsets.bottom, labelInsets.right);
} }
int shadow = DarkButtonUI.isShadowVariant(c) ? 0 : getShadowSize(); boolean shadowVariant = DarkButtonUI.isShadowVariant(c);
int shadow = shadowVariant ? 0 : getShadowSize();
boolean square = DarkButtonUI.isSquare(c); boolean square = DarkButtonUI.isSquare(c);
Insets pad = isThin(c) ? square ? squareThinInsets Insets pad = DarkButtonUI.isThin(c) ? square ? squareThinInsets
: thinInsets : thinInsets
: square ? squareInsets : square ? squareInsets
: insets; : insets;
return new InsetsUIResource(pad.top, pad.left, pad.bottom + shadow, pad.right); return new InsetsUIResource(pad.top, pad.left, pad.bottom + shadow, pad.right);
} }
public boolean isBorderOpaque() { public boolean isBorderOpaque() {
return false; return false;
} }
public static boolean isThin(final Component c) {
return c instanceof JButton
&& Boolean.TRUE.equals(((JButton) c).getClientProperty("JButton.thin"));
}
} }

217
core/src/main/java/com/github/weisj/darklaf/ui/button/DarkButtonUI.java

@ -68,15 +68,24 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene
private int arc; private int arc;
private int squareArc; private int squareArc;
protected final AbstractButtonLayoutDelegate layoutDelegate = new AbstractButtonLayoutDelegate() {
@Override
public Font getFont() {
return delegate != null ? delegate.getFont().deriveFont(Font.BOLD) : null;
}
};
protected boolean oldRolloverEnabled;
protected boolean oldThin;
protected boolean oldSquare;
protected boolean oldAltArc;
public static ComponentUI createUI(final JComponent c) { public static ComponentUI createUI(final JComponent c) {
return new DarkButtonUI(); return new DarkButtonUI();
} }
@Override public static boolean chooseAlternativeArc(final Component c) {
public void installUI(final JComponent c) { return c instanceof JButton
button = (AbstractButton) c; && Boolean.TRUE.equals(((JButton) c).getClientProperty("JButton.alternativeArc"));
super.installUI(c);
} }
@Override @Override
@ -101,11 +110,6 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene
squareArc = UIManager.getInt("Button.squareArc"); squareArc = UIManager.getInt("Button.squareArc");
} }
public static boolean isSquare(final Component c) {
return c instanceof JButton && Boolean.TRUE.equals(((JButton) c).getClientProperty("JButton.square"));
}
@Override @Override
protected void installListeners(final AbstractButton b) { protected void installListeners(final AbstractButton b) {
super.installListeners(b); super.installListeners(b);
@ -118,6 +122,11 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene
b.removePropertyChangeListener(this); b.removePropertyChangeListener(this);
} }
public static boolean isLabelButton(final Component c) {
return c instanceof JButton
&& "onlyLabel".equals(((JButton) c).getClientProperty("JButton.variant"));
}
@Override @Override
protected void paintText(final Graphics g, final JComponent c, protected void paintText(final Graphics g, final JComponent c,
final Rectangle textRect, final String text) { final Rectangle textRect, final String text) {
@ -137,34 +146,18 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene
config.restore(); config.restore();
} }
@Override public static boolean isShadowVariant(final Component c) {
public Dimension getPreferredSize(final JComponent c) { if (isFullShadow(c)) return true;
AbstractButton b = (AbstractButton) c; if (c instanceof JButton) {
Font oldFont = b.getFont(); JButton b = (JButton) c;
b.setFont(b.getFont().deriveFont(Font.BOLD)); return (isIconOnly(b) && convertIconButtonToShadow(b))
Dimension size = BasicGraphicsUtils.getPreferredButtonSize(b, b.getIconTextGap()); || "shadow".equals(b.getClientProperty("JButton.variant"));
b.setFont(oldFont);
return size;
}
@Override
public void paint(final Graphics g, final JComponent c) {
GraphicsContext config = new GraphicsContext(g);
AbstractButton b = (AbstractButton) c;
paintButton(g, c);
if (isDefaultButton(b)) {
g.setFont(g.getFont().deriveFont(Font.BOLD));
} else if (g.getFont().isBold()) {
g.setFont(g.getFont().deriveFont(Font.PLAIN));
} }
return false;
}
String text = layout(b, c, SwingUtilities2.getFontMetrics(b, g), protected static boolean isIconOnly(final AbstractButton b) {
b.getWidth(), b.getHeight()); return b.getIcon() != null && (b.getText() == null || b.getText().isEmpty());
paintIcon(g, b, c);
paintText(g, b, c, text);
config.restore();
} }
protected boolean isDefaultButton(final JComponent c) { protected boolean isDefaultButton(final JComponent c) {
@ -179,36 +172,9 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene
return fg; return fg;
} }
protected void paintButton(final Graphics g, final JComponent c) { public static boolean isFullShadow(final Component c) {
Graphics2D g2 = (Graphics2D) g; return c instanceof JButton
if (shouldDrawBackground(c)) { && "fullShadow".equals(((JButton) c).getClientProperty("JButton.variant"));
AbstractButton b = (AbstractButton) c;
Insets margin = b.getMargin();
int arc = getArc(c);
if (isShadowVariant(c)) {
if (b.isEnabled() && b.getModel().isRollover()) {
GraphicsUtil.setupAAPainting(g2);
g.setColor(getShadowColor(b));
if (isFullShadow(c)) {
g.fillRect(0, 0, c.getWidth(), c.getHeight());
} else {
margin.set(0, 0, 0, 0);
DarkUIUtil.fillRoundRect((Graphics2D) g, margin.left, margin.top,
c.getWidth() - margin.left - margin.right,
c.getHeight() - margin.top - margin.bottom, arc);
}
}
} else {
g2.setColor(getBackgroundColor(c));
if (isSquare(c) && !chooseAlternativeArc(c)) {
g2.fillRect(borderSize, borderSize, c.getWidth() - 2 * borderSize,
c.getHeight() - 2 * borderSize - shadowHeight);
} else {
DarkUIUtil.fillRoundRect((Graphics2D) g, borderSize, borderSize, c.getWidth() - 2 * borderSize,
c.getHeight() - 2 * borderSize - shadowHeight, arc);
}
}
}
} }
private boolean shouldDrawBackground(final JComponent c) { private boolean shouldDrawBackground(final JComponent c) {
@ -260,13 +226,6 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene
return square ? alt ? arc : squareArc : alt ? squareArc : arc; return square ? alt ? arc : squareArc : alt ? squareArc : arc;
} }
public static boolean isShadowVariant(final Component c) {
if (isFullShadow(c)) return true;
return c instanceof JButton
&& "shadow".equals(((JButton) c).getClientProperty("JButton.variant"));
}
protected String layout(final AbstractButton b, final JComponent c, final FontMetrics fm, protected String layout(final AbstractButton b, final JComponent c, final FontMetrics fm,
final int width, final int height) { final int width, final int height) {
Insets i = b.getInsets(); Insets i = b.getInsets();
@ -287,12 +246,6 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene
b.getText() == null ? 0 : b.getIconTextGap()); b.getText() == null ? 0 : b.getIconTextGap());
} }
public static boolean isFullShadow(final Component c) {
return c instanceof JButton
&& "fullShadow".equals(((JButton) c).getClientProperty("JButton.variant"));
}
protected void paintText(final Graphics g, final AbstractButton b, final JComponent c, final String text) { protected void paintText(final Graphics g, final AbstractButton b, final JComponent c, final String text) {
GraphicsContext context = GraphicsUtil.setupAntialiasing(g); GraphicsContext context = GraphicsUtil.setupAntialiasing(g);
g.setClip(textRect); g.setClip(textRect);
@ -314,22 +267,112 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene
} }
} }
public static boolean isNoArc(final Component c) {
public static boolean chooseAlternativeArc(final Component c) {
return c instanceof JButton return c instanceof JButton
&& Boolean.TRUE.equals(((JButton) c).getClientProperty("JButton.alternativeArc")); && Boolean.TRUE.equals(((JButton) c).getClientProperty("JButton.noArc"));
} }
public static boolean isSquare(final Component c) {
return c instanceof JButton && Boolean.TRUE.equals(((JButton) c).getClientProperty("JButton.square"));
}
public static boolean isLabelButton(final Component c) { public static boolean isThin(final Component c) {
return c instanceof JButton return c instanceof JButton
&& "onlyLabel".equals(((JButton) c).getClientProperty("JButton.variant")); && Boolean.TRUE.equals(((JButton) c).getClientProperty("JButton.thin"));
} }
protected static boolean convertIconButtonToShadow(final AbstractButton b) {
return !(b instanceof UIResource)
&& UIManager.getBoolean("Button.convertIconOnlyToShadow")
&& !Boolean.TRUE.equals(b.getClientProperty("JButton.noShadowOverwrite"));
}
public static boolean isNoArc(final Component c) { @Override
return c instanceof JButton public void installUI(final JComponent c) {
&& Boolean.TRUE.equals(((JButton) c).getClientProperty("JButton.noArc")); button = (AbstractButton) c;
super.installUI(c);
oldRolloverEnabled = button.isRolloverEnabled();
updateRolloverEnabled();
}
public void updateRolloverEnabled() {
if (isIconOnly(button) && convertIconButtonToShadow(button)) {
oldRolloverEnabled = button.isRolloverEnabled();
oldThin = isThin(button);
oldSquare = isSquare(button);
oldAltArc = chooseAlternativeArc(button);
button.setRolloverEnabled(true);
button.putClientProperty("JButton.square", true);
button.putClientProperty("JButton.thin", true);
button.putClientProperty("JButton.alternativeArc", true);
} else {
button.setRolloverEnabled(oldRolloverEnabled);
button.putClientProperty("JButton.square", oldSquare);
button.putClientProperty("JButton.thin", oldThin);
button.putClientProperty("JButton.alternativeArc", oldAltArc);
}
}
@Override
public Dimension getPreferredSize(final JComponent c) {
AbstractButton b = (AbstractButton) c;
layoutDelegate.setDelegate(b);
return BasicGraphicsUtils.getPreferredButtonSize(layoutDelegate, b.getIconTextGap());
}
@Override
public void paint(final Graphics g, final JComponent c) {
GraphicsContext config = new GraphicsContext(g);
AbstractButton b = (AbstractButton) c;
paintButton(g, c);
if (isDefaultButton(b)) {
g.setFont(g.getFont().deriveFont(Font.BOLD));
} else if (g.getFont().isBold()) {
g.setFont(g.getFont().deriveFont(Font.PLAIN));
}
String text = layout(b, c, SwingUtilities2.getFontMetrics(b, g),
b.getWidth() + 2, b.getHeight());
paintIcon(g, b, c);
paintText(g, b, c, text);
config.restore();
}
protected void paintButton(final Graphics g, final JComponent c) {
Graphics2D g2 = (Graphics2D) g;
if (shouldDrawBackground(c)) {
AbstractButton b = (AbstractButton) c;
int arc = getArc(c);
Insets margin = b.getMargin();
if (margin instanceof UIResource) margin = new Insets(0, 0, 0, 0);
if (isShadowVariant(c)) {
if (b.isEnabled() && b.getModel().isRollover()) {
GraphicsUtil.setupAAPainting(g2);
g.setColor(getShadowColor(b));
if (isFullShadow(c)) {
g.fillRect(margin.left, margin.top,
c.getWidth() - margin.left - margin.right,
c.getHeight() - margin.top - margin.bottom);
} else {
g.fillRoundRect(margin.left, margin.top,
c.getWidth() - margin.left - margin.right,
c.getHeight() - margin.top - margin.bottom,
arc, arc);
}
}
} else {
g2.setColor(getBackgroundColor(c));
if (isSquare(c) && !chooseAlternativeArc(c)) {
g2.fillRect(borderSize, borderSize, c.getWidth() - 2 * borderSize,
c.getHeight() - 2 * borderSize - shadowHeight);
} else {
DarkUIUtil.fillRoundRect((Graphics2D) g, borderSize, borderSize, c.getWidth() - 2 * borderSize,
c.getHeight() - 2 * borderSize - shadowHeight, arc);
}
}
}
} }
@Override @Override
@ -361,6 +404,8 @@ public class DarkButtonUI extends BasicButtonUI implements PropertyChangeListene
if (key.startsWith("JButton.")) { if (key.startsWith("JButton.")) {
button.repaint(); button.repaint();
button.revalidate(); button.revalidate();
} else if (JButton.TEXT_CHANGED_PROPERTY.equals(key)) {
updateRolloverEnabled();
} }
} }
} }

3
core/src/main/java/com/github/weisj/darklaf/ui/colorchooser/DarkColorChooserPanel.java

@ -26,6 +26,7 @@ package com.github.weisj.darklaf.ui.colorchooser;
import com.github.weisj.darklaf.color.DarkColorModel; import com.github.weisj.darklaf.color.DarkColorModel;
import com.github.weisj.darklaf.components.DefaultColorPipette; import com.github.weisj.darklaf.components.DefaultColorPipette;
import com.github.weisj.darklaf.components.uiresource.JButtonUIResource;
import com.github.weisj.darklaf.decorators.AncestorAdapter; import com.github.weisj.darklaf.decorators.AncestorAdapter;
import com.github.weisj.darklaf.util.ColorUtil; import com.github.weisj.darklaf.util.ColorUtil;
@ -190,7 +191,7 @@ public class DarkColorChooserPanel extends AbstractColorChooserPanel implements
final JPanel previewPanel = new JPanel(new BorderLayout()); final JPanel previewPanel = new JPanel(new BorderLayout());
if (enablePipette && pipette != null) { if (enablePipette && pipette != null) {
JButton pipetteButton = new JButton(); JButton pipetteButton = new JButtonUIResource();
pipetteButton.putClientProperty("JButton.variant", "onlyLabel"); pipetteButton.putClientProperty("JButton.variant", "onlyLabel");
pipetteButton.putClientProperty("JButton.thin", Boolean.TRUE); pipetteButton.putClientProperty("JButton.thin", Boolean.TRUE);
pipetteButton.setRolloverEnabled(true); pipetteButton.setRolloverEnabled(true);

7
core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFileChooserUI.java

@ -102,6 +102,7 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge {
// Up Button // Up Button
JButton upFolderButton = new TooltipAwareButton(getChangeToParentDirectoryAction()); JButton upFolderButton = new TooltipAwareButton(getChangeToParentDirectoryAction());
upFolderButton.putClientProperty("JButton.noShadowOverwrite", true);
upFolderButton.setText(null); upFolderButton.setText(null);
upFolderButton.setIcon(upFolderIcon); upFolderButton.setIcon(upFolderIcon);
upFolderButton.setToolTipText(upFolderToolTipText); upFolderButton.setToolTipText(upFolderToolTipText);
@ -120,6 +121,7 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge {
JButton b = new TooltipAwareButton(homeFolderIcon); JButton b = new TooltipAwareButton(homeFolderIcon);
b.putClientProperty("JButton.noShadowOverwrite", true);
b.setToolTipText(toolTipText); b.setToolTipText(toolTipText);
b.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, b.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
homeFolderAccessibleName); homeFolderAccessibleName);
@ -134,6 +136,7 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge {
// New Directory Button // New Directory Button
if (!UIManager.getBoolean("FileChooser.readOnly")) { if (!UIManager.getBoolean("FileChooser.readOnly")) {
b = new TooltipAwareButton(filePane.getNewFolderAction()); b = new TooltipAwareButton(filePane.getNewFolderAction());
b.putClientProperty("JButton.noShadowOverwrite", true);
b.setText(null); b.setText(null);
b.setIcon(newFolderIcon); b.setIcon(newFolderIcon);
b.setToolTipText(newFolderToolTipText); b.setToolTipText(newFolderToolTipText);
@ -151,6 +154,7 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge {
// List Button // List Button
listViewButton = new TooltipAwareToggleButton(listViewIcon); listViewButton = new TooltipAwareToggleButton(listViewIcon);
listViewButton.putClientProperty("JButton.noShadowOverwrite", true);
listViewButton.putClientProperty("JButton.square", Boolean.TRUE); listViewButton.putClientProperty("JButton.square", Boolean.TRUE);
listViewButton.setToolTipText(listViewButtonToolTipText); listViewButton.setToolTipText(listViewButtonToolTipText);
listViewButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, listViewButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
@ -168,6 +172,7 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge {
// Details Button // Details Button
detailsViewButton = new TooltipAwareToggleButton(detailsViewIcon); detailsViewButton = new TooltipAwareToggleButton(detailsViewIcon);
detailsViewButton.putClientProperty("JButton.noShadowOverwrite", true);
detailsViewButton.putClientProperty("JButton.square", Boolean.TRUE); detailsViewButton.putClientProperty("JButton.square", Boolean.TRUE);
detailsViewButton.setToolTipText(detailsViewButtonToolTipText); detailsViewButton.setToolTipText(detailsViewButtonToolTipText);
detailsViewButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, detailsViewButton.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
@ -281,12 +286,14 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge {
getButtonPanel().setLayout(new DarkButtonAreaLayout()); getButtonPanel().setLayout(new DarkButtonAreaLayout());
approveButton = new TooltipAwareButton(getApproveButtonText(fc)); approveButton = new TooltipAwareButton(getApproveButtonText(fc));
approveButton.putClientProperty("JButton.noShadowOverwrite", true);
// Note: Metal does not use mnemonics for approve and cancel // Note: Metal does not use mnemonics for approve and cancel
approveButton.addActionListener(getApproveSelectionAction()); approveButton.addActionListener(getApproveSelectionAction());
approveButton.setToolTipText(getApproveButtonToolTipText(fc)); approveButton.setToolTipText(getApproveButtonToolTipText(fc));
getButtonPanel().add(approveButton); getButtonPanel().add(approveButton);
cancelButton = new TooltipAwareButton(cancelButtonText); cancelButton = new TooltipAwareButton(cancelButtonText);
cancelButton.putClientProperty("JButton.noShadowOverwrite", true);
cancelButton.setToolTipText(cancelButtonToolTipText); cancelButton.setToolTipText(cancelButtonToolTipText);
cancelButton.addActionListener(getCancelSelectionAction()); cancelButton.addActionListener(getCancelSelectionAction());
getButtonPanel().add(cancelButton); getButtonPanel().add(cancelButton);

4
core/src/main/java/com/github/weisj/darklaf/ui/internalframe/DarkDesktopIconUI.java

@ -23,6 +23,8 @@
*/ */
package com.github.weisj.darklaf.ui.internalframe; package com.github.weisj.darklaf.ui.internalframe;
import com.github.weisj.darklaf.components.uiresource.JButtonUIResource;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.MatteBorder; import javax.swing.border.MatteBorder;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
@ -50,7 +52,7 @@ public class DarkDesktopIconUI extends BasicDesktopIconUI {
Icon icon = frame.getFrameIcon(); Icon icon = frame.getFrameIcon();
String title = frame.getTitle(); String title = frame.getTitle();
button = new JButton(title, icon); button = new JButtonUIResource(title, icon);
button.setOpaque(false); button.setOpaque(false);
button.putClientProperty("JButton.variant", "fullShadow"); button.putClientProperty("JButton.variant", "fullShadow");
button.putClientProperty("JButton.shadow.hover", UIManager.getColor("DesktopIcon.hoverColor")); button.putClientProperty("JButton.shadow.hover", UIManager.getColor("DesktopIcon.hoverColor"));

3
core/src/main/java/com/github/weisj/darklaf/ui/internalframe/DarkInternalFrameTitlePane.java

@ -23,6 +23,7 @@
*/ */
package com.github.weisj.darklaf.ui.internalframe; package com.github.weisj.darklaf.ui.internalframe;
import com.github.weisj.darklaf.components.uiresource.JButtonUIResource;
import com.github.weisj.darklaf.icons.EmptyIcon; import com.github.weisj.darklaf.icons.EmptyIcon;
import com.github.weisj.darklaf.icons.ToggleIcon; import com.github.weisj.darklaf.icons.ToggleIcon;
import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2;
@ -209,7 +210,7 @@ public class DarkInternalFrameTitlePane extends BasicInternalFrameTitlePane {
private static JButton createButton(final String accessibleName) { private static JButton createButton(final String accessibleName) {
JButton button = new JButton(); JButton button = new JButtonUIResource();
button.setFocusable(false); button.setFocusable(false);
button.setOpaque(true); button.setOpaque(true);
button.setRolloverEnabled(true); button.setRolloverEnabled(true);

3
core/src/main/java/com/github/weisj/darklaf/ui/scrollpane/DarkScrollBarUI.java

@ -30,6 +30,7 @@ import com.github.weisj.darklaf.util.DarkUIUtil;
import javax.swing.*; import javax.swing.*;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicScrollBarUI; import javax.swing.plaf.basic.BasicScrollBarUI;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
@ -633,7 +634,7 @@ public class DarkScrollBarUI extends BasicScrollBarUI {
return bounds != null && bounds.contains(p); return bounds != null && bounds.contains(p);
} }
private static final class EmptyButton extends JButton { private static final class EmptyButton extends JButton implements UIResource {
private EmptyButton() { private EmptyButton() {
setFocusable(false); setFocusable(false);
setRequestFocusEnabled(false); setRequestFocusEnabled(false);

1
core/src/main/java/com/github/weisj/darklaf/ui/tabbedpane/DarkHandler.java

@ -83,6 +83,7 @@ public class DarkHandler extends TabbedPaneHandler {
ui.scrollableTabSupport.newTabButton.setVisible(show); ui.scrollableTabSupport.newTabButton.setVisible(show);
} }
ui.tabPane.doLayout(); ui.tabPane.doLayout();
ui.tabPane.repaint();
} else if ("JTabbedPane.leadingComponent".equals(key)) { } else if ("JTabbedPane.leadingComponent".equals(key)) {
ui.tabPane.remove(ui.leadingComp); ui.tabPane.remove(ui.leadingComp);
Object val = e.getNewValue(); Object val = e.getNewValue();

19
core/src/main/java/com/github/weisj/darklaf/ui/tabbedpane/DarkTabbedPaneScrollLayout.java

@ -388,7 +388,6 @@ public class DarkTabbedPaneScrollLayout extends TabbedPaneScrollLayout {
} }
} }
ui.tabScroller.tabPanel.setPreferredSize(tabBounds.getSize()); ui.tabScroller.tabPanel.setPreferredSize(tabBounds.getSize());
ui.tabScroller.tabPanel.invalidate();
} }
@ -456,23 +455,29 @@ public class DarkTabbedPaneScrollLayout extends TabbedPaneScrollLayout {
if (horizontal) { if (horizontal) {
if (leftToRight) { if (leftToRight) {
if (ui.rects[tabCount - 1].x + ui.rects[tabCount - 1].width + buttonBounds.width > maxVal) { if (ui.rects[tabCount - 1].x + ui.rects[tabCount - 1].width + buttonBounds.width > maxVal) {
ui.tabPane.add(button); if (button.getParent() != ui.tabPane) ui.tabPane.add(button);
} else { } else {
ui.scrollableTabSupport.tabPanel.add(button); if (button.getParent() != ui.scrollableTabSupport.tabPanel) {
ui.scrollableTabSupport.tabPanel.add(button);
}
} }
} else { } else {
int x = ui.rects[tabCount - 1].x; int x = ui.rects[tabCount - 1].x;
if (x - buttonBounds.width < minVal) { if (x - buttonBounds.width < minVal) {
ui.tabPane.add(button); if (button.getParent() != ui.tabPane) ui.tabPane.add(button);
} else { } else {
ui.scrollableTabSupport.tabPanel.add(button); if (button.getParent() != ui.scrollableTabSupport.tabPanel) {
ui.scrollableTabSupport.tabPanel.add(button);
}
} }
} }
} else { } else {
if (ui.rects[tabCount - 1].y + ui.rects[tabCount - 1].height + buttonBounds.height > maxVal) { if (ui.rects[tabCount - 1].y + ui.rects[tabCount - 1].height + buttonBounds.height > maxVal) {
ui.tabPane.add(button); if (button.getParent() != ui.tabPane) ui.tabPane.add(button);
} else { } else {
ui.scrollableTabSupport.tabPanel.add(button); if (button.getParent() != ui.scrollableTabSupport.tabPanel) {
ui.scrollableTabSupport.tabPanel.add(button);
}
} }
} }
} }

9
core/src/main/java/com/github/weisj/darklaf/ui/tabbedpane/NewTabButton.java

@ -23,6 +23,8 @@
*/ */
package com.github.weisj.darklaf.ui.tabbedpane; package com.github.weisj.darklaf.ui.tabbedpane;
import com.github.weisj.darklaf.components.uiresource.JButtonUIResource;
import javax.swing.*; import javax.swing.*;
import javax.swing.plaf.UIResource; import javax.swing.plaf.UIResource;
import java.awt.*; import java.awt.*;
@ -47,15 +49,16 @@ public class NewTabButton extends JPanel implements UIResource {
} }
protected JButton createButton() { protected JButton createButton() {
JButton button = new JButton(); JButton button = new JButtonUIResource();
button.setIcon(ui.getNewTabIcon()); button.setIcon(ui.getNewTabIcon());
button.putClientProperty("JButton.variant", "shadow"); button.putClientProperty("JButton.variant", "shadow");
button.putClientProperty("JButton.square", true); button.putClientProperty("JButton.square", Boolean.TRUE);
button.putClientProperty("JButton.alternativeArc", Boolean.TRUE); button.putClientProperty("JButton.alternativeArc", Boolean.TRUE);
button.putClientProperty("JButton.thin", Boolean.TRUE); button.putClientProperty("JButton.thin", Boolean.TRUE);
button.setRolloverEnabled(true); button.setRolloverEnabled(true);
button.setOpaque(false); button.setOpaque(false);
button.setMargin(UIManager.getInsets("TabbedPane.newTabButton.insets")); Insets margin = UIManager.getInsets("TabbedPane.newTabButton.insets");
button.setMargin(new Insets(margin.top, margin.left, margin.bottom, margin.right));
return button; return button;
} }

1
core/src/main/java/com/github/weisj/darklaf/ui/tabbedpane/TabbedPaneScrollLayout.java

@ -129,7 +129,6 @@ abstract class TabbedPaneScrollLayout extends TabbedPaneLayout {
} }
} }
ui.tabScroller.tabPanel.setPreferredSize(new Dimension(totalWidth, totalHeight)); ui.tabScroller.tabPanel.setPreferredSize(new Dimension(totalWidth, totalHeight));
ui.tabScroller.tabPanel.invalidate();
} }
protected int preferredTabAreaWidth(final int tabPlacement, final int height) { protected int preferredTabAreaWidth(final int tabPlacement, final int height) {

57
core/src/main/java/com/github/weisj/darklaf/ui/toolbar/DarkToolBarBorder.java

@ -36,17 +36,18 @@ public class DarkToolBarBorder extends AbstractBorder implements UIResource, Swi
protected Icon horizontalGrip; protected Icon horizontalGrip;
protected Icon verticalGrip; protected Icon verticalGrip;
protected Color borderColor;
public DarkToolBarBorder() { public DarkToolBarBorder() {
horizontalGrip = UIManager.getIcon("ToolBar.horizontalGrip.icon"); horizontalGrip = UIManager.getIcon("ToolBar.horizontalGrip.icon");
verticalGrip = UIManager.getIcon("ToolBar.verticalGrip.icon"); verticalGrip = UIManager.getIcon("ToolBar.verticalGrip.icon");
borderColor = UIManager.getColor("ToolBar.borderColor");
} }
public void paintBorder(final Component c, final Graphics g, public void paintBorder(final Component c, final Graphics g,
final int x, final int y, final int w, final int h) { final int x, final int y, final int w, final int h) {
g.translate(x, y); g.translate(x, y);
if (isFloatable(c)) { if (isFloatable(c)) {
if (((JToolBar) c).getOrientation() == HORIZONTAL) { if (((JToolBar) c).getOrientation() == HORIZONTAL) {
Icon icon = getHorizontalGrip(); Icon icon = getHorizontalGrip();
@ -62,9 +63,45 @@ public class DarkToolBarBorder extends AbstractBorder implements UIResource, Swi
icon.paintIcon(c, g, xIcon, 0); icon.paintIcon(c, g, xIcon, 0);
} }
} }
if (isDocked(c)) {
String constraints = getDockedConstrains(c);
JToolBar toolBar = (JToolBar) c;
g.setColor(borderColor);
if (toolBar.getOrientation() == JToolBar.HORIZONTAL) {
if (BorderLayout.NORTH.equals(constraints)) {
g.fillRect(0, toolBar.getHeight() - 1, toolBar.getWidth(), 1);
} else if (BorderLayout.SOUTH.equals(constraints)) {
g.fillRect(0, 0, toolBar.getWidth(), 1);
}
} else {
if (BorderLayout.WEST.equals(constraints)) {
g.fillRect(toolBar.getWidth() - 1, 0, 1, toolBar.getHeight());
} else if (BorderLayout.EAST.equals(constraints)) {
g.fillRect(0, 0, 1, toolBar.getHeight());
}
}
}
g.translate(-x, -y); g.translate(-x, -y);
} }
private boolean isDocked(final Component c) {
if (c instanceof JToolBar && ((JToolBar) c).getUI() instanceof DarkToolBarUI) {
return !((DarkToolBarUI) ((JToolBar) c).getUI()).isFloating();
}
return false;
}
private String getDockedConstrains(final Component c) {
if (c instanceof JComponent) {
Component parent = c.getParent();
if (parent instanceof JComponent && ((JComponent) parent).getLayout() instanceof BorderLayout) {
BorderLayout layout = (BorderLayout) ((JComponent) parent).getLayout();
Object constraints = layout.getConstraints(c);
if (constraints != null) return constraints.toString();
}
}
return "";
}
private boolean isFloatable(final Component c) { private boolean isFloatable(final Component c) {
return c instanceof JToolBar && ((JToolBar) c).isFloatable(); return c instanceof JToolBar && ((JToolBar) c).isFloatable();
@ -101,6 +138,22 @@ public class DarkToolBarBorder extends AbstractBorder implements UIResource, Swi
newInsets.bottom += margin.bottom; newInsets.bottom += margin.bottom;
} }
} }
if (c instanceof JToolBar && isDocked(c)) {
String constraints = getDockedConstrains(c);
if (((JToolBar) c).getOrientation() == JToolBar.HORIZONTAL) {
if (BorderLayout.NORTH.equals(constraints)) {
newInsets.bottom++;
} else if (BorderLayout.SOUTH.equals(constraints)) {
newInsets.top++;
}
} else {
if (BorderLayout.WEST.equals(constraints)) {
newInsets.right++;
} else if (BorderLayout.EAST.equals(constraints)) {
newInsets.left++;
}
}
}
return newInsets; return newInsets;
} }
} }

1
core/src/main/java/com/github/weisj/darklaf/ui/toolbar/DarkToolBarUI.java

@ -51,7 +51,6 @@ public class DarkToolBarUI extends DarkToolBarUIBridge {
return new DarkToolBarUI(); return new DarkToolBarUI();
} }
private static Robot createRobot() { private static Robot createRobot() {
try { try {
return new Robot(); return new Robot();

1
core/src/main/resources/com/github/weisj/darklaf/properties/overwrites.properties

@ -25,3 +25,4 @@ SplitPane.defaultDividerStyle = spDividerStyle
Table.renderBooleanAsCheckBox = tableBooleanRenderer Table.renderBooleanAsCheckBox = tableBooleanRenderer
Tree.renderBooleanAsCheckBox = treeBooleanRenderer Tree.renderBooleanAsCheckBox = treeBooleanRenderer
TextComponent.roundedSelection = roundedSelection TextComponent.roundedSelection = roundedSelection
Button.convertIconOnlyToShadow = shadowIconButtons

1
core/src/main/resources/com/github/weisj/darklaf/properties/ui/button.properties

@ -59,3 +59,4 @@ Button.shadow.hover = %hoverHighlight
Button.shadow.click = %clickHighlight Button.shadow.click = %clickHighlight
Button.defaultButtonFollowsFocus = false Button.defaultButtonFollowsFocus = false
Button.convertIconOnlyToShadow = false

4
core/src/main/resources/com/github/weisj/darklaf/properties/ui/text.properties

@ -53,6 +53,7 @@ TextPane.selectionForeground = %textSelectionForeground
TextPane.background = %textBackground TextPane.background = %textBackground
TextPane.disabledBackground = %textBackgroundInactive TextPane.disabledBackground = %textBackgroundInactive
TextPane.inactiveBackground = %textBackgroundInactive TextPane.inactiveBackground = %textBackgroundInactive
TextPane.border = null
EditorPane.selectionBackground = %textSelectionBackground EditorPane.selectionBackground = %textSelectionBackground
@ -61,6 +62,7 @@ EditorPane.inactiveForeground = %textForegroundInactive
EditorPane.background = %textBackground EditorPane.background = %textBackground
EditorPane.disabledBackground = %textBackgroundInactive EditorPane.disabledBackground = %textBackgroundInactive
EditorPane.inactiveBackground = %textBackgroundInactive EditorPane.inactiveBackground = %textBackgroundInactive
EditorPane.border = null
TextArea.selectionBackground = %textSelectionBackground TextArea.selectionBackground = %textSelectionBackground
@ -68,7 +70,7 @@ TextArea.selectionForeground = %textSelectionForeground
TextArea.background = %textBackground TextArea.background = %textBackground
TextArea.disabledBackground = %textBackgroundInactive TextArea.disabledBackground = %textBackgroundInactive
TextArea.inactiveBackground = %textBackgroundInactive TextArea.inactiveBackground = %textBackgroundInactive
TextArea.border = null
FormattedTextFieldUI = com.github.weisj.darklaf.ui.text.DarkFormattedTextFieldUI FormattedTextFieldUI = com.github.weisj.darklaf.ui.text.DarkFormattedTextFieldUI
FormattedTextField.border = com.github.weisj.darklaf.ui.text.DarkTextBorder FormattedTextField.border = com.github.weisj.darklaf.ui.text.DarkTextBorder

1
core/src/test/java/ui/tabbedPane/TabbedPaneDemo.java

@ -65,7 +65,6 @@ public class TabbedPaneDemo implements ComponentDemo {
addItem("SCROLL_TAB_LAYOUT"); addItem("SCROLL_TAB_LAYOUT");
addItem("WRAP_TAB_LAYOUT"); addItem("WRAP_TAB_LAYOUT");
setSelectedItem("SCROLL_TAB_LAYOUT"); setSelectedItem("SCROLL_TAB_LAYOUT");
//noinspection MagicConstant
addItemListener(e -> tabbedPane.setTabLayoutPolicy(mapping.get(e.getItem().toString()))); addItemListener(e -> tabbedPane.setTabLayoutPolicy(mapping.get(e.getItem().toString())));
}}, "sgx"); }}, "sgx");
controlPanel.add(new JLabel("TabPlacement:", JLabel.RIGHT)); controlPanel.add(new JLabel("TabPlacement:", JLabel.RIGHT));

2
windows/src/main/java/com/github/weisj/darklaf/platform/windows/ui/WindowsTitlePane.java

@ -144,6 +144,7 @@ public class WindowsTitlePane extends CustomTitlePane {
button.putClientProperty("JButton.shadow.click", button.putClientProperty("JButton.shadow.click",
UIManager.getColor("Windows.TitlePane.close.clickColor")); UIManager.getColor("Windows.TitlePane.close.clickColor"));
} }
button.putClientProperty("JButton.noShadowOverwrite", true);
button.setFocusable(false); button.setFocusable(false);
button.setOpaque(true); button.setOpaque(true);
button.setRolloverEnabled(true); button.setRolloverEnabled(true);
@ -312,6 +313,7 @@ public class WindowsTitlePane extends CustomTitlePane {
protected JButton createWindowIcon() { protected JButton createWindowIcon() {
windowIconButton = new JButton(); windowIconButton = new JButton();
windowIconButton.putClientProperty("JButton.noShadowOverwrite", true);
windowIconButton.setComponentPopupMenu(createMenu()); windowIconButton.setComponentPopupMenu(createMenu());
windowIconButton.putClientProperty("JButton.variant", "onlyLabel"); windowIconButton.putClientProperty("JButton.variant", "onlyLabel");
windowIconButton.addActionListener(e -> windowIconButton windowIconButton.addActionListener(e -> windowIconButton

Loading…
Cancel
Save